如果要实现微信这样底部一个导航栏,实现中间的内容部分切换,大部分人想到的就是Activity+底部导航栏+Fragment或者Activity+底部导航栏+ViewPager+Fragment然而很多人不喜欢这样的结构,更喜欢把每个主体页面放在一个单独的Activity中这时候就产生了一种新的实现方式的思考
目标
- 点击底部导航栏的各个图标时视觉效果上看不出来是开启了新的Activity
- 避免无限循环,也就是Activity1->Activity2->Activity1,此时第二次打开的Activity1必须跟第一次打开的Activity1是同一个实例
- 在任意一级界面(即导航栏图标点击后的视觉一级界面),按返回键能直接关闭APP
实现
第一步:各个一级界面的XML布局文件中都放置导航栏
<com.wuadam.appbaselibrary.widget.NavigationView
android:id="@+id/navigation"
android:layout_width="match_parent"
android:layout_height="56dp"
app:layout_constraintBottom_toBottomOf="parent" />
第二步:各个一级界面的代码中得到导航栏对象后,手动点亮各自在导航栏中的图标
NavigationView.Item itemHome = new NavigationView.Item(R.drawable.ic_home_0, R.drawable.ic_home_1, R.string.navi_home_page);
NavigationView.Item itemBodyData = new NavigationView.Item(R.drawable.ic_body_data_0, R.drawable.ic_body_data_1, R.string.navi_body_data);
NavigationView.Item itemFood = new NavigationView.Item(R.drawable.ic_food_0, R.drawable.ic_food_1, R.string.navi_food);
NavigationView.Item itemProfile = new NavigationView.Item(R.drawable.ic_profile_0, R.drawable.ic_profile_1, R.string.navi_profile);
navigationView.addItem(itemHome);
navigationView.addItem(itemBodyData);
navigationView.addItem(itemFood);
navigationView.addItem(itemProfile);
navigationView.lockItem(2);
navigationView.setOnItemSelectListener(new NavigationView.OnItemSelectListener() {
@Override
public void onSelect(int position, NavigationView.Item item) {
if (item.equals(itemBodyData)) {
Intent intent = new Intent(FoodTypeActivity.this, BodyDataActivity.class);
startActivity(intent);
} else if (item.equals(itemHome)) {
Intent intent = new Intent(FoodTypeActivity.this, HomePageActivity.class);
startActivity(intent);
} else if (item.equals(itemProfile)) {
Intent intent = new Intent(FoodTypeActivity.this, MeActivity.class);
startActivity(intent);
}
}
});
第三步:关闭一级Activity进入和退出时的动画
在style中定义动画为null
<item name="android:windowAnimationStyle">@null</item>
至此已经实现了目标一,下面实现目标二
第四步:在所有一级Activity的Manifest声明中定义launchMode为singleTask
android:launchMode="singleTask"
至此实现了目标二,下面实现目标三
第五步:在各个Activity的父类也就是自定义的BaseActivity中添加如下方法
private static String action_finish = BaseActivity.class.getName() + "_action_finish";
public static void finishActivities(Context context) {
context.getApplicationContext().sendBroadcast(new Intent(action_finish));
}
private BroadcastReceiver finishReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent == null || intent.getAction() == null) {
return;
}
String action = intent.getAction();
if (action.equals(action_finish)) {
finish();
}
}
};
protected boolean shouldFinishOnReceiveBroadcast() {
return true;
}
这样任意一级界面在关闭时调用finishActivities(Context context)方法就能关闭所有界面,从而实现了目标三
而如果某个Activity不想这样被关闭,只需要Override shouldFinishOnReceiveBroadcast()方法并return false
缺点
- 通过点击导航栏图标进入新的界面时没有Fragment方案流畅
- Activity1->Activity2->Activity1->Activity2,第一次Activity2的状态得到保存,因为第二次的Activity2是一个新的实例