Reputation: 14840
In my Android application I have two separate but related top-level screens / activities. I want to have two separate launcher icons for them, but allow the user to "swipe" between them, as with ViewPager.
The options I see are:
Implement two separate activities, and somehow allow swiping between them. The issues is that ViewPager can't be used with two separate activities.
Implement a single activity with two fragments, and use the ViewPager to switch between them. The swiping is simple, but is it possible to have two launchers that automatically switch to the correct fragment?
Is any of the above two options feasible, or is there something else I can try?
Upvotes: 6
Views: 13142
Reputation: 28179
I would go for solution 2, there's no need for dummy activities, it'll slow down the launch of your app, instead you can add activity-aliases in your Manifest, like this:
<activity-alias
android:name=".MySecondLauncher"
android:exported="true"
android:icon="@drawable/my_second_icon"
android:label="@string/my_second_launcher"
android:targetActivity=".MainScreen">
<meta-data
android:name="secondLauncher"
android:value="true" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity-alias>
Then, in the MainScreen activity, you can check which launcher you were called with, you can do that by looking for the launcher activity-alias name, or by checking the meta-data I added above:
ComponentName component = intent.getComponent();
String name = component.getShortClassName();
boolean secondLauncher = ".MySecondLauncher".equals(name);
or:
ActivityInfo info = getPackageManager().getActivityInfo(intent.getComponent(),PackageManager.GET_META_DATA);
boolean secondLauncher = info.metaData.getBoolean("secondLauncher", false);
Upvotes: 1
Reputation: 16397
I know this is old, but that's the first question I got to when I looked for the same problem.
You can find the solution there: ViewPager for multiple Activities, use Fragments... (it is also in the support library if you need to run on earlier versions of Android)
Upvotes: 0
Reputation: 14840
I tried solution two, but the issue is that a single activity cannot detect which launcher icon was used (please tell me if I'm wrong).
My solution was to add two "dummy" activities, which then launch the main activity which the correct "page" number. The difficulty with this approach is to handle the task stack properly. When the launcher is selected, the dummy activity must be launched, and it must send an intent to the main activity. Android tries really hard to prevent you from doing this, and just bring the last activity to the front again.
This is the best I could come up with:
The dummy activities (similar for LaunchActivity2):
public class LaunchActivity1 extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent newIntent = new Intent(this, MainActivity.class);
newIntent.putExtra(MainActivity.EXTRA_PAGE, 1);
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(newIntent);
finish();
}
}
In the main activity:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ViewPager viewPager = (ViewPager)findViewById(R.id.MainViewPager);
viewPager.setAdapter(new MyAdapter(getSupportFragmentManager()));
int page = getIntent().getIntExtra(EXTRA_PAGE, -1);
if(page >= 0 && page <= NUM_ITEMS)
viewPager.setCurrentItem(page);
}
public void onNewIntent(Intent intent) {
if(intent.hasExtra(EXTRA_PAGE)) {
int page = intent.getIntExtra(EXTRA_PAGE, -1);
ViewPager viewPager = (ViewPager)findViewById(R.id.MainViewPager);
if(page >= 0 && page <= NUM_ITEMS)
viewPager.setCurrentItem(page);
}
}
AndroidManifest.xml:
<!-- LaunchActivity2 is similar -->
<activity android:name=".LaunchActivity1" android:label="Launch 1"
android:clearTaskOnLaunch="true"
android:noHistory="true"
android:taskAffinity="Launch1"
android:theme="@android:style/Theme.Translucent.NoTitleBar">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".MainActivity"
android:label="My App"
android:clearTaskOnLaunch="true"
android:finishOnTaskLaunch="true"
android:launchMode="singleTask"
android:taskAffinity="MyApp">
</activity>
The issue with different task affinities is that both launchers, as well as the main task, appear in the "Recent Applications" list.
I would not recommend this approach to anyone else - rather just use a single launcher icon.
Upvotes: 3
Reputation: 5183
Solution 1: You can swipe in terms of starting the other Activity each time. In this case you should fix the transition animation for the two activities in order to have a "swiping" effect and set the two activities as SingleTask in order not to have multiple instances in your task (thus you should implement the onNewIntent() method).
Solution 2: Yeap this is possible. Based on the launcher icon, you should start and show the suitable fragment each time and then use swipe in order to change views.
Hope this helps!
Upvotes: 2