原文出处
标题:Android (争取做到)最全的底部导航栏实现方法
作者:野狼谷
原文链接:https://www.cnblogs.com/yelanggu/p/9516429.html
前言
本文(争取做到)Android 最全的底部导航栏实现方法.
现在写了4个主要方法.
还有一些个人感觉不完全切题的方法也会简单介绍一下.
方法一. ViewPager + List + PagerAdapter
先看activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="45dp"
android:background="#0E6DB0"
android:gravity="center"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/app_name"
android:textColor="#ffffff"
android:textSize="20sp"
android:textStyle="bold" />
</LinearLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</android.support.v4.view.ViewPager>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="55dp"
android:background="#0E6DB0"
android:orientation="horizontal" >
<LinearLayout
android:id="@+id/llChat"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical" >
<ImageView
android:id="@+id/ivChat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
android:src="@drawable/tab_chat" />
<TextView
android:id="@+id/tvChat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="微信"
android:textColor="@drawable/tab_textview" />
</LinearLayout>
<LinearLayout
android:id="@+id/llFriends"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical" >
<ImageView
android:id="@+id/ivFriends"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
android:src="@drawable/tab_friends" />
<TextView
android:id="@+id/tvFriends"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="朋友"
android:textColor="@drawable/tab_textview" />
</LinearLayout>
<LinearLayout
android:id="@+id/llContacts"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical" >
<ImageView
android:id="@+id/ivContacts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
android:src="@drawable/tab_contacts" />
<TextView
android:id="@+id/tvContacts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="通讯录"
android:textColor="@drawable/tab_textview" />
</LinearLayout>
<LinearLayout
android:id="@+id/llSettings"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical" >
<ImageView
android:id="@+id/ivSettings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
android:src="@drawable/tab_setting" />
<TextView
android:id="@+id/tvSettings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="设置"
android:textColor="@drawable/tab_textview" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
说明一
还有另一种方式是用RadioGroup的方式,但是那种方式如果以后要包含小红点提醒或者右上角数字角标提醒,就不好灵活的修改了.所以本文忽略那种方法.
说明二
底部导航栏的4个ImageView使用的src, TextView使用的textColor都是seletor
然后看MainActivity.java
package com.yao.tab01;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MainActivity extends Activity implements OnClickListener {
private List<View> views = new ArrayList<View>();
private ViewPager viewPager;
private LinearLayout llChat, llFriends, llContacts, llSettings;
private ImageView ivChat, ivFriends, ivContacts, ivSettings, ivCurrent;
private TextView tvChat, tvFriends, tvContacts, tvSettings, tvCurrent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
initView();
initData();
}
private void initView() {
viewPager = (ViewPager) findViewById(R.id.viewPager);
llChat = (LinearLayout) findViewById(R.id.llChat);
llFriends = (LinearLayout) findViewById(R.id.llFriends);
llContacts = (LinearLayout) findViewById(R.id.llContacts);
llSettings = (LinearLayout) findViewById(R.id.llSettings);
llChat.setOnClickListener(this);
llFriends.setOnClickListener(this);
llContacts.setOnClickListener(this);
llSettings.setOnClickListener(this);
ivChat = (ImageView) findViewById(R.id.ivChat);
ivFriends = (ImageView) findViewById(R.id.ivFriends);
ivContacts = (ImageView) findViewById(R.id.ivContacts);
ivSettings = (ImageView) findViewById(R.id.ivSettings);
tvChat = (TextView) findViewById(R.id.tvChat);
tvFriends = (TextView) findViewById(R.id.tvFriends);
tvContacts = (TextView) findViewById(R.id.tvContacts);
tvSettings = (TextView) findViewById(R.id.tvSettings);
ivChat.setSelected(true);
tvChat.setSelected(true);
ivCurrent = ivChat;
tvCurrent = tvChat;
viewPager.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
changeTab(position);
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
private void initData() {
LayoutInflater mInflater = LayoutInflater.from(this);
View tab01 = mInflater.inflate(R.layout.tab01, null);
View tab02 = mInflater.inflate(R.layout.tab02, null);
View tab03 = mInflater.inflate(R.layout.tab03, null);
View tab04 = mInflater.inflate(R.layout.tab04, null);
views.add(tab01);
views.add(tab02);
views.add(tab03);
views.add(tab04);
MyPagerAdapter adapter = new MyPagerAdapter(views);
viewPager.setAdapter(adapter);
}
@Override
public void onClick(View v) {
changeTab(v.getId());
}
private void changeTab(int id) {
ivCurrent.setSelected(false);
tvCurrent.setSelected(false);
switch (id) {
case R.id.llChat:
viewPager.setCurrentItem(0);
case 0:
ivChat.setSelected(true);
ivCurrent = ivChat;
tvChat.setSelected(true);
tvCurrent = tvChat;
break;
case R.id.llFriends:
viewPager.setCurrentItem(1);
case 1:
ivFriends.setSelected(true);
ivCurrent = ivFriends;
tvFriends.setSelected(true);
tvCurrent = tvFriends;
break;
case R.id.llContacts:
viewPager.setCurrentItem(2);
case 2:
ivContacts.setSelected(true);
ivCurrent = ivContacts;
tvContacts.setSelected(true);
tvCurrent = tvContacts;
break;
case R.id.llSettings:
viewPager.setCurrentItem(3);
case 3:
ivSettings.setSelected(true);
ivCurrent = ivSettings;
tvSettings.setSelected(true);
tvCurrent = tvSettings;
break;
default:
break;
}
}
}
这种方法一的方式就是提前用mInflater.inflate4个View丢到PagerAdapter里面,再给ViewPager设置Adapter
然后把点击底部Tab的事件和滑动ViewPager的事件(主要包括图片和文字seletor切换)整合在一起.
方法二. ViewPager + List + FragmentPagerAdapter或FragmentStatePagerAdapter
activity_main.xml
MainActivity.java
package com.yao.tab02;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MainActivity extends Activity implements OnClickListener {
private List<Fragment> fragments = new ArrayList<Fragment>();
private ViewPager viewPager;
private LinearLayout llChat, llFriends, llContacts, llSettings;
private ImageView ivChat, ivFriends, ivContacts, ivSettings, ivCurrent;
private TextView tvChat, tvFriends, tvContacts, tvSettings, tvCurrent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
initView();
initData();
}
private void initView() {
viewPager = (ViewPager) findViewById(R.id.viewPager);
llChat = (LinearLayout) findViewById(R.id.llChat);
llFriends = (LinearLayout) findViewById(R.id.llFriends);
llContacts = (LinearLayout) findViewById(R.id.llContacts);
llSettings = (LinearLayout) findViewById(R.id.llSettings);
llChat.setOnClickListener(this);
llFriends.setOnClickListener(this);
llContacts.setOnClickListener(this);
llSettings.setOnClickListener(this);
ivChat = (ImageView) findViewById(R.id.ivChat);
ivFriends = (ImageView) findViewById(R.id.ivFriends);
ivContacts = (ImageView) findViewById(R.id.ivContacts);
ivSettings = (ImageView) findViewById(R.id.ivSettings);
tvChat = (TextView) findViewById(R.id.tvChat);
tvFriends = (TextView) findViewById(R.id.tvFriends);
tvContacts = (TextView) findViewById(R.id.tvContacts);
tvSettings = (TextView) findViewById(R.id.tvSettings);
ivChat.setSelected(true);
tvChat.setSelected(true);
ivCurrent = ivChat;
tvCurrent = tvChat;
viewPager.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
changeTab(position);
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
});
viewPager.setOffscreenPageLimit(2); //设置向左和向右都缓存limit个页面
}
private void initData() {
Fragment chatFragment = new ChatFragment();
Fragment friendsFragment = new FriendsFragment();
Fragment contactsFragment = new ContactsFragment();
Fragment settingsFragment = new SettingsFragment();
fragments.add(chatFragment);
fragments.add(friendsFragment);
fragments.add(contactsFragment);
fragments.add(settingsFragment);
MyFragmentPagerAdapter adapter = new MyFragmentPagerAdapter(getFragmentManager(), fragments);
// MyFragmentStatePagerAdapter adapter = new MyFragmentStatePagerAdapter(getFragmentManager(), fragments);
viewPager.setAdapter(adapter);
}
@Override
public void onClick(View v) {
changeTab(v.getId());
}
private void changeTab(int id) {
ivCurrent.setSelected(false);
tvCurrent.setSelected(false);
switch (id) {
case R.id.llChat:
viewPager.setCurrentItem(0);
case 0:
ivChat.setSelected(true);
ivCurrent = ivChat;
tvChat.setSelected(true);
tvCurrent = tvChat;
break;
case R.id.llFriends:
viewPager.setCurrentItem(1);
case 1:
ivFriends.setSelected(true);
ivCurrent = ivFriends;
tvFriends.setSelected(true);
tvCurrent = tvFriends;
break;
case R.id.llContacts:
viewPager.setCurrentItem(2);
case 2:
ivContacts.setSelected(true);
ivCurrent = ivContacts;
tvContacts.setSelected(true);
tvCurrent = tvContacts;
break;
case R.id.llSettings:
viewPager.setCurrentItem(3);
case 3:
ivSettings.setSelected(true);
ivCurrent = ivSettings;
tvSettings.setSelected(true);
tvCurrent = tvSettings;
break;
default:
break;
}
}
}
说明一
讲一下FragmentPagerAdapter 和 FragmentStatePagerAdapter 区别
1.FragmentStatePagerAdapter : 适合多个界面,类似于listView原理,离开视线就会被回收 会执行onDestroyView方法 onDestroy方法
2.FragmentPagerAdapter : 适合少量界面, 方便滑动 执行onDestroyView方法 不执行onDestroy方法
3.两者都会预先准备好并缓存上一个和下一个Fragment说明二:重要说明:有个神方法viewPager.setOffscreenPageLimit(2); //设置向左和向右都缓存limit个页面.
我也是很晚才发现有这个方法.下面4个Tab, 只要你设置这个值为3, 那4个Tab永远都会缓存着了.
变态说明
这里告诉大家一个小技巧.ViewPager是V4包里面的.用到的FragmentPagerAdapter和FragmentStatePagerAdapter也是V4包里面的.
如果我们不想用android.support.v4.app.Fragment, 那就可以自己复制出来一个FragmentPagerAdapter,然后把里面的Fragment改成android.app.Fragment.
连带FragmentManager和FragmentTransaction也要改成android.app包下的
暂时越过方法三的方法四. FragmentTabHost
跳过方法三,先讲方法四.方法四是代码量最少的方法.简单快捷轻便
item_tab.xml
这个是下面部分4个Tab中其中一个Tab的布局, 以此来FragmentTabHost会帮忙批量生产出4个Tab
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:padding="5dp" >
<ImageView
android:id="@+id/iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
android:src="@drawable/tab_setting" />
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@drawable/tab_textview" />
</LinearLayout>
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="45dp"
android:background="#0E6DB0"
android:gravity="center"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/app_name"
android:textColor="#ffffff"
android:textSize="20sp"
android:textStyle="bold" />
</LinearLayout>
<FrameLayout
android:id="@+id/flContainer"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</FrameLayout>
<com.yao.tab04.FragmentTabHost
android:id="@+id/tabhost"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#0E6DB0" >
</com.yao.tab04.FragmentTabHost>
</LinearLayout>
MainActivity.java
package com.yao.tab04;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.widget.ImageView;
import android.widget.TabHost.OnTabChangeListener;
import android.widget.TabHost.TabSpec;
import android.widget.TextView;
public class MainActivity extends Activity implements OnTabChangeListener {
private FragmentTabHost tabHost;
private String[] tabText = { "聊天", "朋友", "通讯录", "设置" };
private int[] imageRes = new int[] { R.drawable.tab_chat, R.drawable.tab_friends, R.drawable.tab_contacts, R.drawable.tab_setting };
private Class[] fragments = new Class[] { ChatFragment.class, FriendsFragment.class, ContactsFragment.class, SettingsFragment.class };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
tabHost = (FragmentTabHost) super.findViewById(R.id.tabhost);
tabHost.setup(this, super.getFragmentManager(), R.id.flContainer);
tabHost.getTabWidget().setDividerDrawable(null);
tabHost.setOnTabChangedListener(this);
initTab();
}
private void initTab() {
for (int i = 0; i < tabText.length; i++) {
View view = LayoutInflater.from(this).inflate(R.layout.item_tab, null);
((TextView) view.findViewById(R.id.tv)).setText(tabText[i]);
((ImageView) view.findViewById(R.id.iv)).setImageResource(imageRes[i]);
TabSpec tabSpec = tabHost.newTabSpec(tabText[i]).setIndicator(view);
tabHost.addTab(tabSpec, fragments[i], null);
tabHost.setTag(i);
}
}
//自动把getCurrentTabView下的所有子View的selected状态设为true. 牛逼!
@Override
public void onTabChanged(String tabId) {
//首次打开自动会调用一下 首次自动输出tabId : 聊天
Log.e("yao", "tabId : " + tabId);
// TabWidget tabWidget = tabHost.getTabWidget(); //获取整个底部Tab的布局, 可以通过tabWidget.getChildCount和tabWidget.getChildAt来获取某个子View
// int pos = tabHost.getCurrentTab(); //获取当前tab的位置
// View view = tabHost.getCurrentTabView(); //获取当前tab的view
}
}
说明一
重要说明:有些博主还需要写一个未选中的图片ResId数组和一个选中的图片ResId数组.然后根据点击自己在代码上写把图片切换成选中状态.Navie.
你只要传进去一组seletor图片,把文字颜色也设为seletor.FragmentTabHost叼的地方来了.它会自动把图片这个布局View下的所有子控件切换成selected状态.
说明二
业务逻辑写在onTabChanged. 一般用到的几个核心方法 已经写在上面了
说明三
TabHost好像不能设置导航栏在底部. 所以只能用FragmentTabHost.
说明四
切到别的页面,当前这个页面会执行到onDestroyView方法,不会执行onDestroy方法.
方法三. 用fragmentTransaction的show和hide方法隐藏和显示Fragment
网上这种代码已有,但是大多数写的很乱.
大致思路整理一下就是如下.
if (想要的fragment == null) {
if (当前显示的fragment != null) {
隐藏当前fragment
}
生产想要的fragment
} else if (想要的fragment == 当前显示的fragment) {
} else {
隐藏当前fragment
显示想要的fragment
}
然后在中间插入该变化的资源selector代码
下面看代码.
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="45dp"
android:background="#0E6DB0"
android:gravity="center"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/app_name"
android:textColor="#ffffff"
android:textSize="20sp"
android:textStyle="bold" />
</LinearLayout>
<FrameLayout
android:id="@+id/flContainer"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="55dp"
android:background="#0E6DB0"
android:orientation="horizontal" >
<LinearLayout
android:id="@+id/llChat"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical" >
<ImageView
android:id="@+id/ivChat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
android:src="@drawable/tab_chat" />
<TextView
android:id="@+id/tvChat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="微信"
android:textColor="@drawable/tab_textview" />
</LinearLayout>
<LinearLayout
android:id="@+id/llFriends"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical" >
<ImageView
android:id="@+id/ivFriends"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
android:src="@drawable/tab_friends" />
<TextView
android:id="@+id/tvFriends"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="朋友"
android:textColor="@drawable/tab_textview" />
</LinearLayout>
<LinearLayout
android:id="@+id/llContacts"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical" >
<ImageView
android:id="@+id/ivContacts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
android:src="@drawable/tab_contacts" />
<TextView
android:id="@+id/tvContacts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="通讯录"
android:textColor="@drawable/tab_textview" />
</LinearLayout>
<LinearLayout
android:id="@+id/llSettings"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical" >
<ImageView
android:id="@+id/ivSettings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
android:src="@drawable/tab_setting" />
<TextView
android:id="@+id/tvSettings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="设置"
android:textColor="@drawable/tab_textview" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
FragmentSwitchTool.java
/**
* FileName:FragmentSwitchTool.java
* Copyright YaoDiWei All Rights Reserved.
*/
package com.yao.tab03;
import java.util.ArrayList;
import java.util.List;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
/**
* @author YaoDiWei
* @version
*/
public class FragmentSwitchTool implements OnClickListener {
private FragmentManager fragmentManager;
private Fragment currentFragment;
// private View currentClickableView;
private View[] currentSelectedView;
private View[] clickableViews; //传入用于被点击的view,比如是一个LinearLayout
private List<View[]> selectedViews; //传入用于被更改资源selected状态的view[], 比如一组View[]{TextView, ImageView}
private Class<? extends Fragment>[] fragments;
private Bundle[] bundles;
private int containerId;
private boolean showAnimator;
public FragmentSwitchTool(FragmentManager fragmentManager, int containerId) {
super();
this.fragmentManager = fragmentManager;
this.containerId = containerId;
}
public void setClickableViews(View... clickableViews) {
this.clickableViews = clickableViews;
for (View view : clickableViews) {
view.setOnClickListener(this);
}
}
public void setSelectedViews(List<View[]> selectedViews) {
this.selectedViews = selectedViews;
}
public FragmentSwitchTool addSelectedViews(View... views){
if (selectedViews == null) {
selectedViews = new ArrayList<View[]>();
}
selectedViews.add(views);
return this;
}
public void setFragments(Class<? extends Fragment>... fragments) {
this.fragments = fragments;
}
public void setBundles(Bundle... bundles) {
this.bundles = bundles;
}
public void changeTag(View v) {
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Fragment fragment = fragmentManager.findFragmentByTag(String.valueOf(v.getId()));
for (int i = 0; i < clickableViews.length; i++) {
if (v.getId() == clickableViews[i].getId()) {
//过渡动画
if (showAnimator) {
int exitIndex = selectedViews.indexOf(currentSelectedView);
// Log.e("yao", "enter : " + i + " exit: " + exitIndex);
if (i > exitIndex){
fragmentTransaction.setCustomAnimations(R.anim.slide_right_in, R.anim.slide_left_out);
} else if (i < exitIndex) {
fragmentTransaction.setCustomAnimations(R.anim.slide_left_in, R.anim.slide_right_out);
}
}
//过渡动画
if (fragment == null) {
if (currentFragment != null) {
fragmentTransaction.hide(currentFragment);
for (View view : currentSelectedView) {
view.setSelected(false);
}
}
try {
fragment = fragments[i].newInstance();
if (bundles != null && bundles[i] != null) {
fragment.setArguments(bundles[i]);
}
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
fragmentTransaction.add(containerId, fragment, String.valueOf(clickableViews[i].getId()));
} else if (fragment == currentFragment) {
} else {
fragmentTransaction.hide(currentFragment);
for (View view : currentSelectedView) {
view.setSelected(false);
}
fragmentTransaction.show(fragment);
}
fragmentTransaction.commit();
currentFragment = fragment;
for (View view : selectedViews.get(i)) {
view.setSelected(true);
}
currentSelectedView = selectedViews.get(i);
break;
}
}
}
@Override
public void onClick(View v)
{
changeTag(v);
}
}
MainActivity.java
package com.yao.tab03;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MainActivity extends Activity{
private LinearLayout llChat, llFriends, llContacts, llSettings;
private ImageView ivChat, ivFriends, ivContacts, ivSettings;
private TextView tvChat, tvFriends, tvContacts, tvSettings;
private FragmentSwitchTool tool;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
initView();
tool = new FragmentSwitchTool(getFragmentManager(), R.id.flContainer);
tool.setClickableViews(llChat, llFriends, llContacts, llSettings);
tool.addSelectedViews(new View[]{ivChat, tvChat}).addSelectedViews(new View[]{ivFriends, tvFriends})
.addSelectedViews(new View[]{ivContacts, tvContacts}).addSelectedViews(new View[]{ivSettings, tvSettings});
tool.setFragments(ChatFragment.class, FriendsFragment.class, ContactsFragment.class, SettingsFragment.class);
tool.changeTag(llChat);
}
private void initView() {
llChat = (LinearLayout) findViewById(R.id.llChat);
llFriends = (LinearLayout) findViewById(R.id.llFriends);
llContacts = (LinearLayout) findViewById(R.id.llContacts);
llSettings = (LinearLayout) findViewById(R.id.llSettings);
ivChat = (ImageView) findViewById(R.id.ivChat);
ivFriends = (ImageView) findViewById(R.id.ivFriends);
ivContacts = (ImageView) findViewById(R.id.ivContacts);
ivSettings = (ImageView) findViewById(R.id.ivSettings);
tvChat = (TextView) findViewById(R.id.tvChat);
tvFriends = (TextView) findViewById(R.id.tvFriends);
tvContacts = (TextView) findViewById(R.id.tvContacts);
tvSettings = (TextView) findViewById(R.id.tvSettings);
}
}
说明一
重要说明:FragmentSwitchTool把所有的操作都封装好在里面了.所以以后只需要写一个布局文件(注意要写成seletor的形式).
在MainActivity中写几行给FragmentSwitchTool的传参就行.
说明二
方法五.Bottom Navigation
Bottom Navigation
Bottom Navigation是5.0(API level 21)新出的一种符合MD规范的导航栏规范。
注意这里说的是规范,所以当时并没有实现这个BottomNavigation这里有两篇文章可以看看。
原文: https://material.google.com/components/bottom-navigation.html
译文:https://modao.cc/posts/3068
但是谷歌并没有实现这个控件,所以目前民间有3个比较火的开源库,GitHub - aurelhubert/ahbottomnavigation,GitHub - roughike/BottomBar, Ashok-Varma/BottomNavigation。这3个库都很炫酷,动画很丰富。比如我有个小项目就用到了ahbottomnavigation。
BottomNavigationView
然后在Android Support Library 25 后,Android 终于自己增加了一个控件 android.support.design.widget.BottomNavigationView。用法很简单,你甚至不用去看文档。直接在Android studio 里新建一个 BottomNavigation 的模板 Activity 就行。
然而官方这个相比网上那三个开源库,动画就相对朴素了。
总结
方法一
创建就会一次性加载完四个页面.适合简单的页面,比如app一开始的导航页.
方法二
给力的方法.适合能左右滑动的页面.可以自己定制缓存策略.配合神方法,也能一开始就加载全部页面.
方法三
最大的好处是, 用的才加载. 一旦加载就不删除. 切换只用hide和show,速度飞快. 当然你也可以自己定制适合自己的缓存策略.
方法四
方法五
符合MD设计的,希望自己的APP炫酷一点的.毫无疑问都应该用BottomNavigation规范的控件。