Android 最常用底部导航栏的几种实现 https://juejin.cn/post/7013524259821584414
RadioGroup + ViewPager 实现 https://juejin.cn/post/7013524259821584414
Fragment RadioButton 实现底部导航栏 https://www.twle.cn/l/yufei/android/android-basic-fragment-radiobutton.html
公共:
图片资源:
tab_menu_home.xml
1 2 3 4 5 |
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/tab_home_pressed" android:state_checked="true" /> <item android:drawable="@drawable/tab_home" /> </selector> |
tab_menu_category.xml
1 2 3 4 5 |
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/tab_category_pressed" android:state_checked="true" /> <item android:drawable="@drawable/tab_category" /> </selector> |
tab_menu_cart.xml
1 2 3 4 5 |
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/tab_cart_pressed" android:state_checked="true" /> <item android:drawable="@drawable/tab_cart" /> </selector> |
tab_menu_discover.xml
1 2 3 4 5 |
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/tab_discover_pressed" android:state_checked="true" /> <item android:drawable="@drawable/tab_discover" /> </selector> |
文字资源:tab_menu_text.xml
1 2 3 4 5 |
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="#1296db" android:state_checked="true" /> <item android:color="#515151" /> </selector> |
背景资源:tab_menu_bg.xml,选中的 tab 背景会有点灰色
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_checked="true"> <shape> <solid android:color="#ffdddddd" /> </shape> </item> <item> <shape> <solid android:color="#00FFFFFF" /> </shape> </item> </selector> |
RadioButton样式: themes.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<resources xmlns:tools="http://schemas.android.com/tools"> ...... <style name="tab_menu_item"> <item name="android:layout_width">0dp</item> <item name="android:layout_weight">1</item> <item name="android:layout_height">match_parent</item> <item name="android:background">@drawable/tab_menu_bg</item> <item name="android:button">@null</item> <item name="android:gravity">center</item> <item name="android:paddingTop">3dp</item> <item name="android:textColor">@drawable/tab_menu_text</item> <item name="android:textSize">18sp</item> </style> </resources> |
ViewPage方式:
四个布局文件,类似,只给第一个 vpb_content1.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff"> <TextView android:id="@+id/ms_txt_content" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="简单教程,简单编程111" android:textColor="#333333" android:textSize="20sp"/> </LinearLayout> |
Activity布局 viewpage_main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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" tools:context="com.example.test.myapplication.act.ViewPageNavActivity"> <androidx.viewpager.widget.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@+id/radioGroupBar"/> <RadioGroup android:id="@+id/radioGroupBar" android:layout_width="match_parent" android:layout_height="56dp" android:layout_alignParentBottom="true" android:background="#ffffff" android:orientation="horizontal"> <RadioButton android:id="@+id/bottom_tab1" style="@style/tab_menu_item" android:drawableTop="@drawable/tab_menu_home" android:text="首页" /> <RadioButton android:id="@+id/bottom_tab2" style="@style/tab_menu_item" android:drawableTop="@drawable/tab_menu_category" android:text="分类" /> <RadioButton android:id="@+id/bottom_tab3" style="@style/tab_menu_item" android:drawableTop="@drawable/tab_menu_discover" android:text="发现" /> <RadioButton android:id="@+id/bottom_tab4" style="@style/tab_menu_item" android:drawableTop="@drawable/tab_menu_cart" android:text="购物车" /> </RadioGroup> <View android:id="@+id/div_tab_bar" android:layout_width="match_parent" android:layout_height="2px" android:background="#E5E5E5" android:layout_above="@id/radioGroupBar"/> </RelativeLayout> |
ViewPageNavActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
package com.example.test.myapplication.act; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.RadioButton; import android.widget.RadioGroup; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.viewpager.widget.PagerAdapter; import androidx.viewpager.widget.ViewPager; import com.example.test.myapplication.R; import java.util.ArrayList; import java.util.List; import butterknife.BindView; import butterknife.ButterKnife; public class ViewPageNavActivity extends AppCompatActivity { @BindView(R.id.viewpager) ViewPager mViewPager; @BindView(R.id.radioGroupBar) RadioGroup radioGroupBar; @BindView(R.id.bottom_tab1) RadioButton tab1; @BindView(R.id.bottom_tab2) RadioButton tab2; @BindView(R.id.bottom_tab3) RadioButton tab3; @BindView(R.id.bottom_tab4) RadioButton tab4; //四个单选按钮 private List<View> mViews; //存放视图 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.viewpage_main); ButterKnife.bind(this); initView();//初始化数据 //对单选按钮进行监听,选中、未选中 radioGroupBar.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup radioGroup, int i) { switch (i) { case R.id.bottom_tab1: mViewPager.setCurrentItem(0); break; case R.id.bottom_tab2: mViewPager.setCurrentItem(1); break; case R.id.bottom_tab3: mViewPager.setCurrentItem(2); break; case R.id.bottom_tab4: mViewPager.setCurrentItem(3); break; } } }); tab1.setChecked(true); } private void initView() { mViews=new ArrayList<View>();//加载,添加视图 mViews.add(LayoutInflater.from(this).inflate(R.layout.vpb_content1,null)); mViews.add(LayoutInflater.from(this).inflate(R.layout.vpb_content2,null)); mViews.add(LayoutInflater.from(this).inflate(R.layout.vpb_content3,null)); mViews.add(LayoutInflater.from(this).inflate(R.layout.vpb_content4,null)); mViewPager.setAdapter(new MyViewPagerAdapter());//设置一个适配器 //对viewpager监听,让分页和底部图标保持一起滑动 mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override //让viewpager滑动的时候,下面的图标跟着变动 public void onPageSelected(int position) { switch (position) { case 0: setChecked(tab1); break; case 1: setChecked(tab2); break; case 2: setChecked(tab3); break; case 3: setChecked(tab4); break; } } @Override public void onPageScrollStateChanged(int state) { } }); } private void setChecked(RadioButton chkBtn){ tab1.setChecked(false); tab2.setChecked(false); tab3.setChecked(false); tab4.setChecked(false); chkBtn.setChecked(true); } //ViewPager适配器 private class MyViewPagerAdapter extends PagerAdapter { @Override public int getCount() { return mViews.size(); } @Override public boolean isViewFromObject(@NonNull View view, @NonNull Object object) { return view==object; } @Override public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) { container.removeView(mViews.get(position)); } @NonNull @Override public Object instantiateItem(@NonNull ViewGroup container, int position) { container.addView(mViews.get(position)); return mViews.get(position); } } } |
Fragment方式:
Fragment布局:fg_content.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff"> <TextView android:id="@+id/ms_txt_content" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="简单教程,简单编程" android:textColor="#333333" android:textSize="20sp"/> </LinearLayout> |
Activity布局:fragment_main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
<?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"> <RelativeLayout android:id="@+id/ms_topbar" android:layout_width="match_parent" android:layout_height="48dp" android:background="#FCFCFC"> <TextView android:id="@+id/ms_topbar_title" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerInParent="true" android:gravity="center" android:textSize="18sp" android:textColor="#694E42" android:text="信息"/> <View android:layout_width="match_parent" android:layout_height="2px" android:background="#E5E5E5" android:layout_alignParentBottom="true"/> </RelativeLayout> <RadioGroup android:id="@+id/radioGroupBar" android:layout_width="match_parent" android:layout_height="56dp" android:layout_alignParentBottom="true" android:background="#ffffff" android:orientation="horizontal"> <RadioButton android:id="@+id/bottom_tab1" style="@style/tab_menu_item" android:drawableTop="@drawable/tab_menu_home" android:text="首页" /> <RadioButton android:id="@+id/bottom_tab2" style="@style/tab_menu_item" android:drawableTop="@drawable/tab_menu_category" android:text="分类" /> <RadioButton android:id="@+id/bottom_tab3" style="@style/tab_menu_item" android:drawableTop="@drawable/tab_menu_discover" android:text="发现" /> <RadioButton android:id="@+id/bottom_tab4" style="@style/tab_menu_item" android:drawableTop="@drawable/tab_menu_cart" android:text="购物车" /> </RadioGroup> <View android:id="@+id/div_tab_bar" android:layout_width="match_parent" android:layout_height="2px" android:background="#E5E5E5" android:layout_above="@id/radioGroupBar"/> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@id/ms_topbar" android:layout_above="@id/div_tab_bar" android:id="@+id/ms_content"> </FrameLayout> </RelativeLayout> |
MsFragment.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
package com.example.test.myapplication.act; import android.annotation.SuppressLint; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; @SuppressLint("ValidFragment") public class MsFragment extends Fragment { private String content; public MsFragment(String content) { this.content = content; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fg_content,container,false); TextView txt_content = (TextView) view.findViewById(R.id.ms_txt_content); txt_content.setText(content); return view; } } |
FragmentActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
package com.example.test.myapplication.act; import android.app.Activity; import android.app.FragmentManager; import android.app.FragmentTransaction; import android.os.Bundle; import android.view.Window; import android.widget.RadioButton; import android.widget.RadioGroup; import com.example.test.myapplication.MsFragment; import com.example.test.myapplication.R; import butterknife.BindView; import butterknife.ButterKnife; /** * 继承自 Activity 而非 AppCompatActivity */ public class FragmentActivity extends Activity implements RadioGroup.OnCheckedChangeListener { @BindView(R.id.ms_tab_bar) RadioGroup ms_tab_bar; @BindView(R.id.bottom_tab1) RadioButton bottom_tab1; //底部十个Fragment private MsFragment fg1, fg2, fg3, fg4; //Fragment管理对象 private FragmentManager fManager; @Override protected void onCreate(Bundle savedInstanceState) { //把 requestWindowFeature(Window.FEATURE_NO_TITLE); //放在 super.onCreate(savedInstanceState); 前面就可以隐藏 ActionBar 而不报错 requestWindowFeature(Window.FEATURE_NO_TITLE); super.onCreate(savedInstanceState); setContentView(R.layout.fragment_main); ButterKnife.bind(FragmentActivity.this); init(); } protected void init() { fManager = super.getFragmentManager(); ms_tab_bar.setOnCheckedChangeListener(this); //获取第一个单选按钮,并设置其为选中状态 bottom_tab1.setChecked(true); } @Override public void onCheckedChanged(RadioGroup group, int checkedId) { FragmentTransaction fTransaction = fManager.beginTransaction(); Bundle bundle = new Bundle(); hideAllFragment(fTransaction); switch (checkedId) { case R.id.bottom_tab1: if (fg1 == null) { fg1 = new MsFragment("第一个 Fragment"); fTransaction.add(R.id.ms_content, fg1); } else { fTransaction.show(fg1); } bundle.putString("key",fg1.getContent()); fg1.setArguments(bundle); break; case R.id.bottom_tab2: if (fg2 == null) { fg2 = new MsFragment("第二个 Fragment"); fTransaction.add(R.id.ms_content, fg2); } else { fTransaction.show(fg2); } bundle.putString("key",fg2.getContent()); fg2.setArguments(bundle); break; case R.id.bottom_tab3: if (fg3 == null) { fg3 = new MsFragment("第三个 Fragment"); fTransaction.add(R.id.ms_content, fg3); } else { fTransaction.show(fg3); } bundle.putString("key",fg3.getContent()); fg3.setArguments(bundle); break; case R.id.bottom_tab4: if (fg4 == null) { fg4 = new MsFragment("第四个 Fragment"); fTransaction.add(R.id.ms_content, fg4); } else { fTransaction.show(fg4); } bundle.putString("key",fg4.getContent()); fg4.setArguments(bundle); break; } fTransaction.commit(); } //隐藏所有Fragment private void hideAllFragment(FragmentTransaction fragmentTransaction) { if (fg1 != null) fragmentTransaction.hide(fg1); if (fg2 != null) fragmentTransaction.hide(fg2); if (fg3 != null) fragmentTransaction.hide(fg3); if (fg4 != null) fragmentTransaction.hide(fg4); } } |