android Material Design 学习之十:底部Tab的两种实现

   上一篇:android Material Design 学习之九:TabLayout 基本使用 只是提到了TabLayout 作为顶部Tab 使用,其实TabLayout还可以作为底部的Tab。

TabLayout 实现底部Tab

布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
   >
   <include
       layout="@layout/tool_bar_layout"/>
    <com.dhl.mdstudy.NoAnimationViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        >
    </com.dhl.mdstudy.NoAnimationViewPager>
    <android.support.design.widget.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="@color/white"
        app:tabIndicatorHeight="0dp"
        >
    </android.support.design.widget.TabLayout>

</LinearLayout>


NoAnimationViewPager 是为了解决Tab切换动画闪动的问题,源码如下:

/**
 * 页面切换取消动画
 */

public class NoAnimationViewPager extends ViewPager {
    public NoAnimationViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public void setCurrentItem(int item) {
        super.setCurrentItem(item,false);
    }
}

自定义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:gravity="center"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/image_menu_item"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/selector_menu_home"/>

    <TextView
        android:id="@+id/tv_menu_item"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Item"
        android:textColor="@color/selector_blue"/>

</LinearLayout>

上面是一个ImageView,下面是TextView 

这里TextView 的selector :

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

    <item android:state_selected="true" android:color="@color/blue"></item>
    <item android:state_checked="true" android:color="@color/blue"></item>
    <item android:color="@color/gray"></item>

</selector>

代码部分:

初始化Indicators:

 private void initIndicators()
    {
        tabIndicators = new ArrayList<>();
        tabIndicators.add("Tab01");
        tabIndicators.add("Tab02");
        tabIndicators.add("Tab03");
    }

核心代码:

private void initTab()
    {
        fragments = new ArrayList<>();
        //tabIndicators = new ArrayList<>();
        fragments.add(TabFragment.newInstance("Fragment 1"));
        fragments.add(TabFragment.newInstance("Fragment 2"));
        fragments.add(TabFragment.newInstance("Fragment 3"));
        //底部固定
        mTab_layout.setTabMode(TabLayout.MODE_FIXED);
        TabPagerAdapter tabPagerAdapter = new TabPagerAdapter(getSupportFragmentManager());
        tabPagerAdapter.setTabFragments(fragments);
        mView_pager.setAdapter(tabPagerAdapter);
        mTab_layout.setupWithViewPager(mView_pager);
        //必须放在 mTab_layout.setupWithViewPager(mView_pager); 后面,要不然 itemTab == null
        for (int i = 0; i < tabIndicators.size(); i++) {
            TabLayout.Tab itemTab = mTab_layout.getTabAt(i);
            if (itemTab!=null){
                itemTab.setCustomView(R.layout.tab_layout_custom);
                TextView itemTv = itemTab.getCustomView().findViewById(R.id.tv_menu_item);
                ImageView imageView = itemTab.getCustomView().findViewById(R.id.image_menu_item);
                imageView.setImageResource(R.drawable.selector_menu_home);
                itemTv.setText(tabIndicators.get(i));
            }
        }
        mTab_layout.getTabAt(0).getCustomView().setSelected(true);
    }

对每个Tab 自定义CustomView ,然后设置适当的Seleector 。

如下图:


BottomNavigationView 实现底部Tab

布局:

<?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"
    tools:context="com.dhl.mdstudy.BottomNavActivity">

   <FrameLayout
       android:id="@+id/content_id"
       android:layout_width="match_parent"
       android:layout_height="match_parent"></FrameLayout>

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

    <View
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:layout_above="@id/bottom_nav_view"
        android:background="@color/gray"/>
</RelativeLayout>

Menu:

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

    <item
        android:id="@+id/action_home"
        android:title="首页"
        android:icon="@drawable/ic_action_home"/>

    <item
        android:id="@+id/action_explore"
        android:title="发现"
        android:icon="@drawable/ic_action_explore"/>

    <item
        android:id="@+id/action_me"
        android:title="我"
        android:icon="@drawable/ic_action_me"/>

</menu>

底部Tab 就能正确显示,添加Fragment ,支持正确切换:

public class BottomNavActivity extends AppCompatActivity {


    private BottomNavigationView bottomNavigationView ;
    private FragmentManager fragmentManager ;
    private FragmentTransaction transaction ;
    private TabFragment tabFragment01,tabFragment02,tabFragment03 ;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bottom_nav);
        fragmentManager = getSupportFragmentManager();
        transaction = fragmentManager.beginTransaction();
        bottomNavigationView = (BottomNavigationView)findViewById(R.id.bottom_nav_view);
        transaction = fragmentManager.beginTransaction();
        tabFragment01 = TabFragment.newInstance("tab01");
        transaction.add(R.id.content_id,tabFragment01);
        transaction.commit();
        bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                transaction = fragmentManager.beginTransaction();
                hideFragment();
                //bottomNavigationView.setSelectedItemId(item.getItemId());
                switch (item.getItemId())
                {
                    case R.id.action_home :

                        if(tabFragment01 == null)
                        {
                            tabFragment01 = TabFragment.newInstance("tab01");
                            transaction.add(R.id.content_id,tabFragment01);
                        }else
                        {
                            transaction.show(tabFragment01);
                        }
                        break;

                    case R.id.action_explore :
                       // bottomNavigationView.setSelectedItemId(item.getItemId());
                        if(tabFragment02 == null)
                        {
                            tabFragment02 = TabFragment.newInstance("tab02");
                            transaction.add(R.id.content_id,tabFragment02);
                        }else
                        {
                            transaction.show(tabFragment02);
                        }
                        break;

                    case R.id.action_me :
                       // bottomNavigationView.setSelectedItemId(item.getItemId());
                        if(tabFragment03 == null)
                        {
                            tabFragment03 = TabFragment.newInstance("tab03");
                            transaction.add(R.id.content_id,tabFragment03);
                        }else
                        {
                            transaction.show(tabFragment03);
                        }
                        break;


                }
                transaction.commit();
                updateNavigationBarState(item.getItemId());
                //必须return true
                return true;
            }
        });
    }

    /**
     * 隐藏Fragment
     */
    private void hideFragment()
    {
        if(tabFragment01 != null) {
            transaction.hide(tabFragment01);
        }
        if(tabFragment02 != null)
        {
            transaction.hide(tabFragment02);
        }
        if(tabFragment03 != null)
        {
            transaction.hide(tabFragment03);
        }

    }

    /**
     * 更新Tab 选中状态
     * @param actionId
     */
    private void updateNavigationBarState(int actionId){
        Menu menu = bottomNavigationView.getMenu();

        for (int i = 0, size = menu.size(); i < size; i++) {
            MenuItem item = menu.getItem(i);
            item.setChecked(item.getItemId() == actionId);
        }
    }
}

如下图:


这个感觉要比TabLayout 实现要好一点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值