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 實現要好一點。
相關文章
- Android之Material DesignAndroidMaterial Design
- Android Material Design 陰影實現AndroidMaterial Design
- Android技術分享|【自定義View】實現Material Design的Loading效果AndroidViewMaterial Design
- Material Design之RecyclerView基本講解與瀑布流的實現Material DesignView
- Material Design元件之AppBarLayoutMaterial Design元件APP
- Material Design 元件之FloatingActionButtonMaterial Design元件
- Material Design 元件之FloatingActionBuMaterial Design元件
- html兩種方法來實現tab切換效果HTML
- Material Design Lite元件之徽章Material Design元件
- Material Design Lite元件之按鈕Material Design元件
- UI介面微信底部(ViewPager實現Tab,左右滑動+底部點選)UIViewpager
- Material Design之-互動效果炸裂的 FloatingActionMenuMaterial Design
- Material Design 實戰 之第一彈——Toolbar詳解Material Design
- 使用純 CSS 實現仿 Material Design 的 input 過渡效果CSSMaterial Design
- Material Design 系列之 CardView、FAB 和 SnackbarMaterial DesignView
- 『Material Design入門學習筆記』TabLayout與NestedScrollView(附demo)Material Design筆記TabLayoutView
- javascript實現tab切換的四種方法JavaScript
- Android 使用BottomNavigationView實現底部導航欄AndroidNavigationView
- flutter的進階之路之Material Design與IOS風格元件FlutterMaterial DesigniOS元件
- Android Material Design控制元件使用(一)——ConstraintLayout 約束佈局AndroidMaterial Design控制元件AI
- Android Material Design控制元件使用(二)——FloatButton TextInputEditText TextInputLayout 按鈕AndroidMaterial Design控制元件
- 微信小程式之animation底部彈窗動畫(兩種方法)微信小程式動畫
- Redis學習 RDB和AOF兩種持久化介紹以及實現Redis持久化
- Android學習之活動的最佳實踐Android
- HTML+CSS底部footer兩種固定方式HTMLCSS
- 【Android】 banner+tab吸頂+viewpager切換+重新整理載入之實現AndroidViewpager
- 值得一看!2018年最優秀的9個Android Material Design Apps!AndroidMaterial DesignAPP
- 強大的CSS:placeholder-shown偽類實現Material Design佔位符互動效果CSSMaterial Design
- Spring實現IOC容器的兩種實現方式Spring
- 雜湊表的兩種實現
- 實現微前端的十種方式 【第一種】前端
- 實現微前端的十種方式 【第二種】前端
- HarmonyOS NEXT應用開發之Tab元件實現增刪Tab標籤元件
- 純CSS Material Design風格按鈕CSSMaterial Design
- 單利模式的兩種最佳實現模式
- python 程式池的兩種不同實現Python
- WPF Material Design中資源的查詢和使用Material Design
- 實現高可用的兩種方案與實戰