android 底部导航总结

1BottomNavigationView实现

实现方式:
1.1 BottomNavigationView是放置在design包中的,所以,使用前需要先引入com.android.support:design:25.1.0包

1.2 xml布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <include layout="@layout/include_toolbar" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tb_toolbar"
        android:orientation="vertical">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="22dp"
            tools:text="123524352" />

    </LinearLayout>

    <android.support.design.widget.BottomNavigationView
        android:id="@+id/bnv_menu"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        app:itemIconTint="@color/selector_blue"
        app:itemTextColor="@color/selector_blue"
        app:menu="@menu/menu_bottom_navigation" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_above="@id/bnv_menu"
        android:background="@color/gray" />

</RelativeLayout>

1.3 java代码

  • 基本实现
publicclassMainActivityextendsAppCompatActivityimplementsBottomNavigationView.OnNavigationItemSelectedListener{privateTextFragment fragment;@OverrideprotectedvoidonCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

FragmentManager fragmentManager = getSupportFragmentManager();

fragment =newTextFragment();

FragmentTransaction transaction = fragmentManager.beginTransaction();

transaction.replace(R.id.fragment_container, fragment);

transaction.commit();

BottomNavigationView bottomNavigationView = (BottomNavigationView) findViewById(R.id.navigation_view);

bottomNavigationView.setOnNavigationItemSelectedListener(this);

}@OverridepublicbooleanonNavigationItemSelected(@NonNull MenuItem item){@StringResinttext;switch(item.getItemId()) {caseR.id.recents:

text = R.string.recents;break;caseR.id.favourites:

text = R.string.favourites;break;caseR.id.nearby:

text = R.string.nearby;break;default:returnfalse;

}

switchFragmentText(text);returntrue;

}privatevoidswitchFragmentText(@StringResinttext){

fragment.setText(text);
}
}
}
  • 详细java代码
package com.song.wallpager;  

import android.support.v4.app.Fragment;  
import android.support.v4.app.FragmentActivity;  
import android.support.v4.app.FragmentTransaction;  
import android.os.Bundle;  
import android.support.annotation.NonNull;  
import android.support.design.widget.BottomNavigationView;  
import android.view.MenuItem;  
import android.widget.TextView;  

public class MainActivity extends FragmentActivity {  



    private Fragment1 fragment1;  
    private Fragment2 fragment2;  
    private Fragment3 fragment3;  
    private Fragment[] fragments;  
    private int lastShowFragment = 0;  

    private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener  
            = new BottomNavigationView.OnNavigationItemSelectedListener() {  

        @Override  
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {  
            switch (item.getItemId()) {  
                case R.id.navigation_home:  
                    if (lastShowFragment != 0) {  
                        switchFrament(lastShowFragment, 0);  
                        lastShowFragment = 0;  
                    }  
                    return true;  
                case R.id.navigation_dashboard:  
                    if (lastShowFragment != 1) {  
                        switchFrament(lastShowFragment, 1);  
                        lastShowFragment = 1;  
                    }  
                    return true;  
                case R.id.navigation_notifications:  
                    if (lastShowFragment != 2) {  
                        switchFrament(lastShowFragment, 2);  
                        lastShowFragment = 2;  
                    }  
                    return true;  
            }  
            return false;  
        }  

    };  

    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);  
        navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);  
        initFragments();  
    }  

    /**  
     * 切换Fragment  
     *  
     * @param lastIndex 上个显示Fragment的索引  
     * @param index     需要显示的Fragment的索引  
     */  
    public void switchFrament(int lastIndex, int index) {  
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();  
        transaction.hide(fragments[lastIndex]);  
        if (!fragments[index].isAdded()) {  
            transaction.add(R.id.fragment_container, fragments[index]);  
        }  
        transaction.show(fragments[index]).commitAllowingStateLoss();  
    }  

    private void initFragments() {  
        fragment1 = new Fragment1();  
        fragment2 = new Fragment2();  
        fragment3 = new Fragment3();  
        fragments = new Fragment[]{fragment1, fragment2, fragment3};  
        lastShowFragment = 0;  
        getSupportFragmentManager()  
                .beginTransaction()  
                .add(R.id.fragment_container, fragment1)  
                .show(fragment1)  
                .commit();  
    }  

}  

总结:

这种方式是google比较新的方式,实现的时候在MainActivity中使用frameLayout布局,标签tab是fragment,通过在activity中对fragment中add和hide实现或者replace(为了避免卡顿,add和hide整体上要好)。

2TabLayout+Viewpager+FragmentPagerAdapter实现

java代码

public class TabLayoutBottomActivity extends BaseActivity {

    private TabLayout mTabTl;
    private ViewPager mContentVp;

    private List<String> tabIndicators;
    private List<Fragment> tabFragments;
    private ContentPagerAdapter contentAdapter;


    public static void startActivity(Context context ){
        Intent intent = new Intent(context, TabLayoutBottomActivity.class);
        context.startActivity(intent);
    }


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tab_layout_bottom);

        mTabTl = (TabLayout) findViewById(R.id.tl_tab);
        mContentVp = (ViewPager) findViewById(R.id.vp_content);

        initContent();
        initTab();
    }

    private void initTab(){

        mTabTl.setTabMode(TabLayout.MODE_FIXED);
        mTabTl.setSelectedTabIndicatorHeight(0);
        ViewCompat.setElevation(mTabTl, 10);
        mTabTl.setupWithViewPager(mContentVp);

        for (int i = 0; i < tabIndicators.size(); i++) {
            TabLayout.Tab itemTab = mTabTl.getTabAt(i);
            if (itemTab!=null){
                itemTab.setCustomView(R.layout.item_tab_layout_custom);
                TextView itemTv = (TextView) itemTab.getCustomView().findViewById(R.id.tv_menu_item);
                itemTv.setText(tabIndicators.get(i));
            }
        }
        mTabTl.getTabAt(0).getCustomView().setSelected(true);
    }

    private void initContent(){
        tabIndicators = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            tabIndicators.add("Tab " + i);
        }
        tabFragments = new ArrayList<>();
        for (String s : tabIndicators) {
            tabFragments.add(TabContentFragment.newInstance(s));
        }
        contentAdapter = new ContentPagerAdapter(getSupportFragmentManager());
        mContentVp.setAdapter(contentAdapter);
    }


    class ContentPagerAdapter extends FragmentPagerAdapter {

        public ContentPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            return tabFragments.get(position);
        }

        @Override
        public int getCount() {
            return tabIndicators.size();
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return tabIndicators.get(position);
        }
    }

}

xml代码

<?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="match_parent"
    android:orientation="vertical">

    <include  layout="@layout/include_toolbar"/>

    <android.support.v4.view.ViewPager
        android:id="@+id/vp_content"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">
    </android.support.v4.view.ViewPager>

    <android.support.design.widget.TabLayout
        android:id="@+id/tl_tab"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dp_56"
        android:background="@color/white">

    </android.support.design.widget.TabLayout>

</LinearLayout>

总结

这种方式实现起来比较简单,而且可以左右滑动,注意这种方式注意viewpager会预加载fragment。

3 通过FragmentManager+Fragment实现显示隐藏实现

  • java代码
/** 
 * 项目的主Activity,所有的Fragment都嵌入在这里。 
 *  
 */  
public class MainActivity extends Activity implements OnClickListener {  

    /** 
     * 用于展示消息的Fragment 
     */  
    private MessageFragment messageFragment;  

    /** 
     * 用于展示联系人的Fragment 
     */  
    private ContactsFragment contactsFragment;  

    /** 
     * 用于展示动态的Fragment 
     */  
    private NewsFragment newsFragment;  

    /** 
     * 用于展示设置的Fragment 
     */  
    private SettingFragment settingFragment;  

    /** 
     * 消息界面布局 
     */  
    private View messageLayout;  

    /** 
     * 联系人界面布局 
     */  
    private View contactsLayout;  

    /** 
     * 动态界面布局 
     */  
    private View newsLayout;  

    /** 
     * 设置界面布局 
     */  
    private View settingLayout;  

    /** 
     * 在Tab布局上显示消息图标的控件 
     */  
    private ImageView messageImage;  

    /** 
     * 在Tab布局上显示联系人图标的控件 
     */  
    private ImageView contactsImage;  

    /** 
     * 在Tab布局上显示动态图标的控件 
     */  
    private ImageView newsImage;  

    /** 
     * 在Tab布局上显示设置图标的控件 
     */  
    private ImageView settingImage;  

    /** 
     * 在Tab布局上显示消息标题的控件 
     */  
    private TextView messageText;  

    /** 
     * 在Tab布局上显示联系人标题的控件 
     */  
    private TextView contactsText;  

    /** 
     * 在Tab布局上显示动态标题的控件 
     */  
    private TextView newsText;  

    /** 
     * 在Tab布局上显示设置标题的控件 
     */  
    private TextView settingText;  

    /** 
     * 用于对Fragment进行管理 
     */  
    private FragmentManager fragmentManager;  

    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        requestWindowFeature(Window.FEATURE_NO_TITLE);  
        setContentView(R.layout.activity_main);  
        // 初始化布局元素  
        initViews();  
        fragmentManager = getFragmentManager();  
        // 第一次启动时选中第0个tab  
        setTabSelection(0);  
    }  

    /** 
     * 在这里获取到每个需要用到的控件的实例,并给它们设置好必要的点击事件。 
     */  
    private void initViews() {  
        messageLayout = findViewById(R.id.message_layout);  
        contactsLayout = findViewById(R.id.contacts_layout);  
        newsLayout = findViewById(R.id.news_layout);  
        settingLayout = findViewById(R.id.setting_layout);  
        messageImage = (ImageView) findViewById(R.id.message_image);  
        contactsImage = (ImageView) findViewById(R.id.contacts_image);  
        newsImage = (ImageView) findViewById(R.id.news_image);  
        settingImage = (ImageView) findViewById(R.id.setting_image);  
        messageText = (TextView) findViewById(R.id.message_text);  
        contactsText = (TextView) findViewById(R.id.contacts_text);  
        newsText = (TextView) findViewById(R.id.news_text);  
        settingText = (TextView) findViewById(R.id.setting_text);  
        messageLayout.setOnClickListener(this);  
        contactsLayout.setOnClickListener(this);  
        newsLayout.setOnClickListener(this);  
        settingLayout.setOnClickListener(this);  
    }  

    @Override  
    public void onClick(View v) {  
        switch (v.getId()) {  
        case R.id.message_layout:  
            // 当点击了消息tab时,选中第1个tab  
            setTabSelection(0);  
            break;  
        case R.id.contacts_layout:  
            // 当点击了联系人tab时,选中第2个tab  
            setTabSelection(1);  
            break;  
        case R.id.news_layout:  
            // 当点击了动态tab时,选中第3个tab  
            setTabSelection(2);  
            break;  
        case R.id.setting_layout:  
            // 当点击了设置tab时,选中第4个tab  
            setTabSelection(3);  
            break;  
        default:  
            break;  
        }  
    }  

    /** 
     * 根据传入的index参数来设置选中的tab页。 
     *  
     * @param index 
     *            每个tab页对应的下标。0表示消息,1表示联系人,2表示动态,3表示设置。 
     */  
    private void setTabSelection(int index) {  
        // 每次选中之前先清楚掉上次的选中状态  
        clearSelection();  
        // 开启一个Fragment事务  
        FragmentTransaction transaction = fragmentManager.beginTransaction();  
        // 先隐藏掉所有的Fragment,以防止有多个Fragment显示在界面上的情况  
        hideFragments(transaction);  
        switch (index) {  
        case 0:  
            // 当点击了消息tab时,改变控件的图片和文字颜色  
            messageImage.setImageResource(R.drawable.message_selected);  
            messageText.setTextColor(Color.WHITE);  
            if (messageFragment == null) {  
                // 如果MessageFragment为空,则创建一个并添加到界面上  
                messageFragment = new MessageFragment();  
                transaction.add(R.id.content, messageFragment);  
            } else {  
                // 如果MessageFragment不为空,则直接将它显示出来  
                transaction.show(messageFragment);  
            }  
            break;  
        case 1:  
            // 当点击了联系人tab时,改变控件的图片和文字颜色  
            contactsImage.setImageResource(R.drawable.contacts_selected);  
            contactsText.setTextColor(Color.WHITE);  
            if (contactsFragment == null) {  
                // 如果ContactsFragment为空,则创建一个并添加到界面上  
                contactsFragment = new ContactsFragment();  
                transaction.add(R.id.content, contactsFragment);  
            } else {  
                // 如果ContactsFragment不为空,则直接将它显示出来  
                transaction.show(contactsFragment);  
            }  
            break;  
        case 2:  
            // 当点击了动态tab时,改变控件的图片和文字颜色  
            newsImage.setImageResource(R.drawable.news_selected);  
            newsText.setTextColor(Color.WHITE);  
            if (newsFragment == null) {  
                // 如果NewsFragment为空,则创建一个并添加到界面上  
                newsFragment = new NewsFragment();  
                transaction.add(R.id.content, newsFragment);  
            } else {  
                // 如果NewsFragment不为空,则直接将它显示出来  
                transaction.show(newsFragment);  
            }  
            break;  
        case 3:  
        default:  
            // 当点击了设置tab时,改变控件的图片和文字颜色  
            settingImage.setImageResource(R.drawable.setting_selected);  
            settingText.setTextColor(Color.WHITE);  
            if (settingFragment == null) {  
                // 如果SettingFragment为空,则创建一个并添加到界面上  
                settingFragment = new SettingFragment();  
                transaction.add(R.id.content, settingFragment);  
            } else {  
                // 如果SettingFragment不为空,则直接将它显示出来  
                transaction.show(settingFragment);  
            }  
            break;  
        }  
        transaction.commit();  
    }  

    /** 
     * 清除掉所有的选中状态。 
     */  
    private void clearSelection() {  
        messageImage.setImageResource(R.drawable.message_unselected);  
        messageText.setTextColor(Color.parseColor("#82858b"));  
        contactsImage.setImageResource(R.drawable.contacts_unselected);  
        contactsText.setTextColor(Color.parseColor("#82858b"));  
        newsImage.setImageResource(R.drawable.news_unselected);  
        newsText.setTextColor(Color.parseColor("#82858b"));  
        settingImage.setImageResource(R.drawable.setting_unselected);  
        settingText.setTextColor(Color.parseColor("#82858b"));  
    }  

    /** 
     * 将所有的Fragment都置为隐藏状态。 
     *  
     * @param transaction 
     *            用于对Fragment执行操作的事务 
     */  
    private void hideFragments(FragmentTransaction transaction) {  
        if (messageFragment != null) {  
            transaction.hide(messageFragment);  
        }  
        if (contactsFragment != null) {  
            transaction.hide(contactsFragment);  
        }  
        if (newsFragment != null) {  
            transaction.hide(newsFragment);  
        }  
        if (settingFragment != null) {  
            transaction.hide(settingFragment);  
        }  
    }  
}  
  • activity_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="match_parent"
    android:orientation="vertical">

    <include  layout="@layout/include_toolbar"/>

    <android.support.v4.view.ViewPager
        android:id="@+id/vp_content"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">
    </android.support.v4.view.ViewPager>

    <android.support.design.widget.TabLayout
        android:id="@+id/tl_tab"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dp_56"
        android:background="@color/white">

    </android.support.design.widget.TabLayout>

</LinearLayout>
  • fragment中的布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:orientation="vertical" >

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:src="@drawable/contacts_selected" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:padding="10dp"
            android:text="这是联系人界面"
            android:textSize="20sp" />
    </LinearLayout>

</RelativeLayout>

总结
这种方式是非常清晰的方式,没有预加载,类似QQ 微信中的效果,美中不足的是所有fragment中的代码放在activity中,有点臃肿。

4 ViewPager+FragmentPagerAdapter

参考链接
https://www.kancloud.cn/digest/protectyoureyes/122210

  • java 代码
public class MainActivity extends FragmentActivity
        implements View.OnClickListener {

    private ViewPager viewPager;
    private Button one;
    private Button two;
    private Button three;
    private Button four;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //初始化ViewPager
        InitViewPager();
        //初始化布局
        InitView();

    }

    private void InitViewPager() {
        //获取ViewPager
        //创建一个FragmentPagerAdapter对象,该对象负责为ViewPager提供多个Fragment
        viewPager = (ViewPager) findViewById(R.id.pager);
        FragmentPagerAdapter pagerAdapter = new FragmentPagerAdapter(
                getSupportFragmentManager()) {

            //获取第position位置的Fragment
            @Override
            public Fragment getItem(int position) {
                Fragment fragment = null;
                switch (position) {
                    case 0:
                        fragment = new OneFragment();
                        break;
                    case 1:
                        fragment = new TwoFragment();
                        break;
                    case 2:
                        fragment = new ThreeFragment();
                        break;
                    case 3:
                        fragment = new FourFragment();
                        break;
                }

                return fragment;
            }

            //该方法的返回值i表明该Adapter总共包括多少个Fragment
            @Override
            public int getCount() {
                return 4;
            }

        };
        //为ViewPager组件设置FragmentPagerAdapter
        viewPager.setAdapter(pagerAdapter);

        //为viewpager组件绑定时间监听器
        viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            //当ViewPager显示的Fragment发生改变时激发该方法
            @Override
            public void onPageSelected(int position) {
                switch (position) {
                    //如果是点击的第一个button,那么就让第一个button的字体变为蓝色
                    //其他的button的字体的颜色变为黑色
                    case 0:
                        one.setTextColor(Color.BLUE);
                        two.setTextColor(Color.BLACK);
                        three.setTextColor(Color.BLACK);
                        four.setTextColor(Color.BLACK);
                        break;
                    case 1:
                        one.setTextColor(Color.BLACK);
                        two.setTextColor(Color.BLUE);
                        three.setTextColor(Color.BLACK);
                        four.setTextColor(Color.BLACK);
                        break;
                    case 2:
                        one.setTextColor(Color.BLACK);
                        two.setTextColor(Color.BLACK);
                        three.setTextColor(Color.BLUE);
                        four.setTextColor(Color.BLACK);
                        break;
                    case 3:
                        one.setTextColor(Color.BLACK);
                        two.setTextColor(Color.BLACK);
                        three.setTextColor(Color.BLACK);
                        four.setTextColor(Color.BLUE);
                        break;
                }
                super.onPageSelected(position);
            }
        });
    }

    private void InitView() {
        one = (Button) findViewById(R.id.bt_one);
        two = (Button) findViewById(R.id.bt_two);
        three = (Button) findViewById(R.id.bt_three);
        four = (Button) findViewById(R.id.bt_four);

        //设置点击监听
        one.setOnClickListener(this);
        two.setOnClickListener(this);
        three.setOnClickListener(this);
        four.setOnClickListener(this);

        //将button中字体的颜色先按照点击第一个button的效果初始化
        one.setTextColor(Color.BLUE);
        two.setTextColor(Color.BLACK);
        three.setTextColor(Color.BLACK);
        four.setTextColor(Color.BLACK);
    }

    //点击主界面上面的button后,将viewpager中的fragment跳转到对应的item
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.bt_one:
                viewPager.setCurrentItem(0);
                break;
            case R.id.bt_two:
                viewPager.setCurrentItem(1);
                break;
            case R.id.bt_three:
                viewPager.setCurrentItem(2);
                break;
            case R.id.bt_four:
                viewPager.setCurrentItem(3);
                break;
        }
    }

}

OneFragment:(由于4个fragment的布局都一样,在此就只放上第一个了)

public class OneFragment extends Fragment {

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }

    @Override
    @Nullable
    public View onCreateView(LayoutInflater inflater,
                             @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.one, container, false);//关联布局文件

        //设置在OneFragment中的点击效果
        Button bt_frg_one = (Button) rootView.findViewById(R.id.bt_frg_one);
        bt_frg_one.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getActivity().getApplicationContext(), "这是第一页按钮的点击效果", Toast.LENGTH_SHORT).show();
            }
        });
        return rootView;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }
}
  • xml 布局代码

activity_main

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></android.support.v4.view.ViewPager>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true">

        <Button
            android:id="@+id/bt_one"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="one"
            android:textSize="20sp" />

        <Button
            android:id="@+id/bt_two"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="two"
            android:textSize="20sp" />

        <Button
            android:id="@+id/bt_three"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="three"
            android:textSize="20sp" />

        <Button
            android:id="@+id/bt_four"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="four"
            android:textSize="20sp" />

    </LinearLayout>
</RelativeLayout>

one

<?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="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/bt_frg_one"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="one"
        android:textSize="30dp" />
</LinearLayout>

总结
这种方式跟2的方式唯一不同的是第二个用到tabLayout这种方式用的是LinerLayout布局,其他的是一样的。

5 TabPageIndicator+ViewPager+ FragmentPagerAdapter实现

总结这种方式跟2和4类似

6 FragmentTabHost+Fragment实现

  • java 代码
public class MainActivity extends FragmentActivity {    

      private FragmentTabHost mTabHost;    
      private LayoutInflater mInflater;    
      private ArrayList<Tab> mTabs= new ArrayList<Tab>(5);   

 @Override   
      protected void onCreate(Bundle savedInstanceState) {              
          super.onCreate(savedInstanceState);        
          setContentView(R.layout.activity_main);       
          initTab();   
 }    

      private void initTab() {        
          //实例化5个Tab类的对象        
          Tab Tab_home = new Tab(R.drawable.selector_home,R.string.home,HomeFragment.class);        
          Tab Tab_hot = new Tab(R.drawable.selector_hot,R.string.hot, HotFragment.class);        
          Tab Tab_discover = new Tab(R.drawable.selector_discover,R.string.discover, DiscoverFragment.class);        
          Tab Tab_cart = new Tab(R.drawable.selector_cart,R.string.cart, CartFragment.class);          
          Tab Tab_user = new Tab(R.drawable.selector_user,R.string.user, UserFragment.class);      

           //将这5个对象加到一个List中        
          mTabs.add(Tab_home);        
          mTabs.add(Tab_hot);        
          mTabs.add(Tab_discover);        
          mTabs.add(Tab_cart);        
          mTabs.add(Tab_user);        

          mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);        
          mTabHost.setup(this, getSupportFragmentManager(), R.id.realcontent);        
          mInflater = LayoutInflater.from(this);        

          //通过循环实例化一个个TabSpec        
          //并调用其中setIndicator方法        
          //然后将TabSpec加到TabHost中        
          for (Tab tab  :mTabs) {            
              TabHost.TabSpec tabSpec = mTabHost.newTabSpec(String.valueOf(tab.getText()));                  
              tabSpec.setIndicator(buildView(tab));            
              mTabHost.addTab(tabSpec,tab.getFragment(), null);        
            }        

           //通过这行代码可以去除掉底部菜单5个图表之间的分割线
           mTabHost.getTabWidget().setShowDividers(LinearLayout.SHOW_DIVIDER_NONE);    }    

          //设置Indicator中的View    
          private View buildView(Tab tab) {        
          View view = mInflater.inflate(R.layout.tab_indicator,null);        
          ImageView Tab_img = (ImageView) view.findViewById(R.id.tab_img);        
          TextView Tab_txt = (TextView) view.findViewById(R.id.tab_txt);        

          Tab_img.setBackgroundResource(tab.getImage());        
          Tab_txt.setText(tab.getText());        
          return view;    
        }
      }

public class Tab {   
      private int Image;    
      private int Text;    
      private Class Fragment;    

      public Tab(int image, int text, Class fragment) {        
              Image = image;       
              Text = text;       
              Fragment = fragment;    }    

      public int getImage() {        return Image;    }    
      public void setImage(int image) {        Image = image;    }          
      public int getText() {        return Text;    }    
      public void setText(int text) {        Text = text;    }    
      public Class getFragment() {        return Fragment;    }    
      public void setFragment(Class fragment) {        Fragment = fragment;    }
}

  • 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"              
              tools:context=".MainActivity">    

   <FrameLayout        
              android:id="@+id/realcontent"        
              android:layout_width="match_parent"        
              android:layout_height="0dp"        
              android:layout_weight="1">    
    </FrameLayout>    

    <android.support.v4.app.FragmentTabHost        
              android:id="@android:id/tabhost"          
              android:layout_width="match_parent"        
              android:layout_height="wrap_content"        
              android:background="#ffffff" >      

         <FrameLayout         
               android:id="@android:id/tabcontent"            
               android:layout_width="0dp"            
               android:layout_height="0dp"            
               android:layout_weight="0" >
         </FrameLayout>    
     </android.support.v4.app.FragmentTabHost></LinearLayout>

7 ViewPager+Fragment+FragmentTabHost实现底部菜单

具体实现:

  • 每个fragment布局
<?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="match_parent"
    android:orientation="vertical" 
    android:gravity="center">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="fragment1" 
        android:textSize="20dp"/>

</LinearLayout>
  • Activity布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

     <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <android.support.v4.app.FragmentTabHost
        android:id="@android:id/tabhost"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/black" >
    </android.support.v4.app.FragmentTabHost>

</LinearLayout>
  • 底部菜单布局
<?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="match_parent"
    android:gravity="center"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/tab_imageview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/tab_textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@android:color/white" />

</LinearLayout>

activity_main 中的java代码

//注意是继承 FragmentActivity
public class MainActivity extends FragmentActivity
{

    // FragmentTabHost
    private FragmentTabHost mTabHost;
    // layoutInflater
    private LayoutInflater layoutInflater;
    // imageViewArray数组,用于显示底部菜单
    private int imageViewArray[] = { R.drawable.mywork, R.drawable.mypatient,
            R.drawable.infusion, R.drawable.personal };
    // textViewArray数组
    private String textViewArray[] = { "工作", "回家", "互动", "我的" };
    // Fragment数组
    private List<Fragment> list = new ArrayList<Fragment>();
    // ViewPager
    private ViewPager vp;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_tab_layout);

        initView();
    }

    /**
     * 控件初始化
     */
    private void initView()
    {
        vp = (ViewPager) findViewById(R.id.pager);

        layoutInflater = LayoutInflater.from(this);
        mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
        mTabHost.setup(this, getSupportFragmentManager(), R.id.pager);

        Fragment1 fragment1 = new Fragment1();
        Fragment2 fragment2 = new Fragment2();
        Fragment3 fragment3 = new Fragment3();
        Fragment4 fragment4 = new Fragment4();
        list.add(fragment1);
        list.add(fragment2);
        list.add(fragment3);
        list.add(fragment4);

        int count = textViewArray.length;

        // 添加菜单内容
        for (int i = 0; i < count; i++)
        {
            // 一个菜单就是一个TabSpec,然后添加到FragmentTabHost中
            TabSpec tabSpec = mTabHost.newTabSpec(textViewArray[i])
                    .setIndicator(getTabItemView(i));
            mTabHost.addTab(tabSpec, list.get(i).getClass(), null);
            // 默认让第一个选中
            mTabHost.getTabWidget().getChildAt(0)
                    .setBackgroundResource(R.drawable.selector_tab_background);
        }

        // ViewPager添加Adapter,这里用FragmentPagerAdapter
        vp.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager())
        {

            @Override
            public int getCount()
            {

                return list.size();
            }

            @Override
            public android.support.v4.app.Fragment getItem(int arg0)
            {
                return list.get(arg0);
            }
        });

    }

    private View getTabItemView(int i)
    {
        View view = layoutInflater.inflate(R.layout.tab_content, null);
        ImageView mImageView = (ImageView) view
                .findViewById(R.id.tab_imageview);
        TextView mTextView = (TextView) view.findViewById(R.id.tab_textview);
        mImageView.setBackgroundResource(imageViewArray[i]);
        mTextView.setText(textViewArray[i]);
        return view;
    }

}
  • 当viewpager滑动的时候关联viewpager与底部菜单
vp.setOnPageChangeListener(new OnPageChangeListener()
        {

            @Override
            public void onPageScrollStateChanged(int arg0)
            {

            }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2)
            {

            }

            @Override
            public void onPageSelected(int arg0)
            {
                // 选中菜单
                mTabHost.setCurrentTab(arg0);
                // 设置对应菜单高亮
                mTabHost.getTabWidget()
                        .getChildAt(arg0)
                        .setBackgroundResource(
                                R.drawable.selector_tab_background);
            }
        });
  • FragmentTabHost实现setOnTabChangedListener,目的是当点击了下面的菜单时,上面的ViewPager应该滑动到对应的Fragment
mTabHost.setOnTabChangedListener(new OnTabChangeListener()
        {

            @Override
            public void onTabChanged(String tabId)
            {
                // 获取点击的菜单的位置
                int position = mTabHost.getCurrentTab();
                // ViewPager滑动到对应的位置
                vp.setCurrentItem(position);
            }
        });

总结
基本原理都是viewPager+FragmentPagerAdapter.如果要求内容不需要滑动,如微信、支付宝那种,只有底部点击切换Fragment的功能,那么只需要将Activity布局中的ViewPager换成一个FrameLayout占位,然后在程序替换Fragment即可~~

对以上几种实现方式的建议:
在项目中用的话
简便实用性: 3和6
如果需要左右滑动则 2 4 5
第一个是比较新的特性 我自己用的少,根据个人情况来选择。

参考链接
https://juejin.im/entry/583414ce61ff4b006b8cf338 (第一条)
http://blog.csdn.net/qq_35366908/article/details/72457909(第一条)
http://www.jianshu.com/p/f7351d4ee903 (第五条)
http://www.jianshu.com/p/491386d6435c (FragmentTabHost)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值