转载:Android (争取做到)最全的底部导航栏实现方法

原文出处

标题:Android (争取做到)最全的底部导航栏实现方法

作者:野狼谷

原文链接:Android (争取做到)最全的底部导航栏实现方法 - 野狼谷 - 博客园

前言

本文(争取做到)Android 最全的底部导航栏实现方法.

现在写了4个主要方法.

还有一些个人感觉不完全切题的方法也会简单介绍一下.

方法一. ViewPager + List<View> + 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<Fragment> + 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规范的控件。

下载地址:

http://download.csdn.net/detail/alcoholdi/9565976

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值