版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/dhl_1986/article/details/80526396
上一篇: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 实现要好一点。