本博客 供个人学习使用 参考 博客
https://blog.csdn.net/jxq1994/article/details/52573506
https://blog.csdn.net/afei__/article/details/80950288
第一种方式 BottomNavigationView android自带的底部导航栏。
新建Activity时选择Bottom Navigation Activity就会自动使用BottomNavigationView并生成相应代码。
布局如下
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Style1Activity">
<TextView
android:id="@+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginTop="@dimen/activity_vertical_margin"
android:text="@string/title_home"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.design.widget.BottomNavigationView
android:id="@+id/navigation"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:background="?android:attr/windowBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="@menu/navigation" />
</android.support.constraint.ConstraintLayout>
一个android.support.design.widget.BottomNavigationView控件指明了app:menu="@menu/navigation就是 底部 布局文件
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/navigation_home"
android:icon="@drawable/ic_home_black_24dp"
android:title="@string/title_home" />
<item
android:id="@+id/navigation_dashboard"
android:icon="@drawable/ic_dashboard_black_24dp"
android:title="@string/title_dashboard" />
<item
android:id="@+id/navigation_notifications"
android:icon="@drawable/ic_notifications_black_24dp"
android:title="@string/title_notifications" />
</menu>
可以添加修改item达到自己预期效果
activity如下
public class Style1Activity extends AppCompatActivity {
private TextView mTextMessage;
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.navigation_home:
mTextMessage.setText(R.string.title_home);
return true;
case R.id.navigation_dashboard:
mTextMessage.setText(R.string.title_dashboard);
return true;
case R.id.navigation_notifications:
mTextMessage.setText(R.string.title_notifications);
return true;
}
return false;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_style1);
mTextMessage = (TextView) findViewById(R.id.message);
BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
}
}
修改 onNavigationItemSelected 事件应该能满足 大部分需求 比如 使用 Fragment 替换当前之类
private void replaceFragment(Fragment fragment){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.frame, fragment);
transaction.commit();
}
第二个方法 LinearLayout + TextView实现了底部导航栏的效果
首先 创建好资源
在drawable 目录下 新建 Drawable resource file 为四个底层导航栏图片文字设置选项
如table_menu_note.xml 设计记帐本 导航 选择与未选择的图片展示
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@mipmap/note_selected" android:state_selected="true" />
<item android:drawable="@mipmap/note_black" />
</selector>
table_menu_note_text.xml 设计记账本 选择与未选择的文字颜色展示 @color文件夹中可设置颜色
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/text_blue" android:state_selected="true"/>
<item android:color="@color/text_gray" />
</selector>
可 根据需要 将 底部导航栏 的 图片 文字 依次写出
创建背景资源table_menu_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true">
<shape>
<solid android:color="#FFC4C4C4"/>
</shape>
</item>
<item>
<shape>
<solid android:color="@color/colorPrimary" />
</shape>
</item>
</selector>
个人感觉 这里面最重要的就是 Drawable resource file文件的创建 是一个selector 包含属性 android:state_selected=“true”
当控件使用该资源时 可在活动中设置 控件的选中与否 使用 控件.setSelected(trye|false) 。然后控件 会根据设置的selector展现不同效果。
还需要创建 一个 自定义的 Fragment 该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:background="#dcdcdc">
<TextView
android:id="@+id/txt_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:text="呵呵"
android:textColor="@color/text_blue"
android:textSize="20sp"/>
</LinearLayout>
只有一个文本框用于展示 因为 重点 是 底部导航栏 fragment 只是用于展示接着创建一个继承Fragment的自定义类
该类可根据类方法getInstance获取 MyFragment实例。
public class MyFragment extends Fragment {
private TextView mTextView;
// 官方不建议 使用 带有参数的构造方法 如果强行使用 官方建议Fragment.setArguments(Bundle bundle)传递参数
// @SuppressLint("ValidFragment") 放在 类的开头
// public MyFragment(String content){
// this.content = content;
// }
// 获取MyFragment实例 并设置 参数
public static MyFragment getInstance(String content){
Bundle bundle = new Bundle();
bundle.putString("content", content);
MyFragment myFragment = new MyFragment();
myFragment.setArguments(bundle);
return myFragment;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment, container, false);
Bundle bundle = getArguments();
if(bundle != null){
String content = bundle.getString("content");
mTextView = view.findViewById(R.id.txt_content);
mTextView.setText(content);
}
return view;
}
}
将需要的资源 准备好 开始编写 布局文件
<?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=".Style2Activity">
<FrameLayout
android:id="@+id/fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/tab_menu"
android:layout_marginBottom="2dp" />
<LinearLayout
android:id="@+id/tab_menu"
android:layout_width="match_parent"
android:layout_height="56dp"
android:orientation="horizontal"
android:layout_alignParentBottom="true">
<TextView
android:id="@+id/txt_note"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/table_menu_bg"
android:drawableTop="@drawable/table_menu_note"
android:drawablePadding="3dp"
android:gravity="center"
android:text="记账"
android:textColor="@drawable/table_menu_note_text" />
<TextView
android:id="@+id/txt_table"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/table_menu_bg"
android:drawablePadding="3dp"
android:drawableTop="@drawable/table_menu_table"
android:gravity="center"
android:textColor="@drawable/table_menu_table_text"
android:text="图表"/>
<TextView
android:id="@+id/txt_find"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/table_menu_bg"
android:drawablePadding="3dp"
android:drawableTop="@drawable/table_menu_find"
android:gravity="center"
android:textColor="@drawable/table_menu_find_text"
android:text="发现"/>
<TextView
android:id="@+id/txt_mine"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/table_menu_bg"
android:drawablePadding="3dp"
android:drawableTop="@drawable/table_menu_mine"
android:gravity="center"
android:textColor="@drawable/table_menu_mine_text"
android:text="我的"/>
</LinearLayout>
</RelativeLayout>
每个TextView 的android:background android:drawableTop android:textColor 都使用的selector。可根据选中与否展示不同效果。 使用 FrameLayout 来展示 Fragment 实例
布局文件创建完成 开始Activity文件
package com.mingrisoft.bottomtabbar;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.TextView;
// TextView
public class Style2Activity extends AppCompatActivity implements View.OnClickListener {
private TextView tabNote;
private TextView tabTable;
private TextView tabFind;
private TextView tabMine;
// 四个碎片
private MyFragment myFragment1, myFragment2, myFragment3, myFragment4;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); //什么意思
setContentView(R.layout.activity_style2);
bindView();
tabNote.setSelected(true);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment, MyFragment.getInstance("添加账单"));
transaction.commit();
}
// UI 初始化 与 事件 绑定
private void bindView(){
tabNote = findViewById(R.id.txt_note);
tabTable = findViewById(R.id.txt_table);
tabFind = findViewById(R.id.txt_find);
tabMine = findViewById(R.id.txt_mine);
tabNote.setOnClickListener(this);
tabTable.setOnClickListener(this);
tabFind.setOnClickListener(this);
tabMine.setOnClickListener(this);
}
//重置所有文本的选中状态
public void selected(){
tabNote.setSelected(false);
tabTable.setSelected(false);
tabFind.setSelected(false);
tabMine.setSelected(false);
}
//隐藏所有Fragment
public void hideAllFragment(FragmentTransaction transaction){
if(myFragment1 != null){
transaction.hide(myFragment1);
}
if(myFragment2 != null){
transaction.hide(myFragment2);
}
if(myFragment3 != null){
transaction.hide(myFragment3);
}
if(myFragment4 != null){
transaction.hide(myFragment4);
}
}
@Override
public void onClick(View v) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
hideAllFragment(transaction);
selected();
switch (v.getId()){
case R.id.txt_note:
tabNote.setSelected(true); // 设置 为 选中状态
if(myFragment1 == null){ // 如果 myFragment1 不存在 就创建一个
myFragment1 = MyFragment.getInstance("添加账单");
transaction.add(R.id.fragment, myFragment1); // 将碎片添加进R.id.fragment的碎片管理器
} else { // 如果存在 就 显示出来 因为点击事件一旦触发 就会将 所有碎片隐藏
transaction.show(myFragment1);
}
break;
case R.id.txt_table:
tabTable.setSelected(true); // 设置 为 选中状态
if(myFragment2 == null){ // 如果 myFragment1 不存在 就创建一个
myFragment2 = MyFragment.getInstance("展示报表");
transaction.add(R.id.fragment, myFragment2); // 将碎片添加进R.id.fragment的碎片管理器
} else { // 如果存在 就 显示出来 因为点击事件一旦触发 就会将 所有碎片隐藏
transaction.show(myFragment2);
}
break;
case R.id.txt_find:
tabFind.setSelected(true); // 设置 为 选中状态
if(myFragment3 == null){
myFragment3 = MyFragment.getInstance("发现");
transaction.add(R.id.fragment, myFragment3);
} else {
transaction.show(myFragment3);
}
break;
case R.id.txt_mine:
tabMine.setSelected(true); // 设置 为 选中状态
if(myFragment4 == null){
myFragment4 = MyFragment.getInstance("我的");
transaction.add(R.id.fragment, myFragment4);
} else {
transaction.show(myFragment4);
}
break;
}
transaction.commit();
}
}
创建了 4 个 Fragment 实例 根据 TextView的点击事件 使用 FragmentTransaction 对四个碎片进行隐藏和展示。就能达到底部导航栏效果。
第三个方法 RadioGroup 代替 TextView
与 第二个方法 类似
首先 要将 几个资源文件修改一下 因为 RadioGroup 中 选中属性是 checked 不是 selected 如修改tab_menu_note.xml文件
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@mipmap/note_selected" android:state_selected="true" />
<item android:drawable="@mipmap/note_selected" android:state_checked="true"/>
<item android:drawable="@mipmap/note_black" />
</selector>
在原基础上加一句 即可其他的文字颜色 背景色 修改 同上。
准备工作完成 布局文件
<?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=".Style3Activity">
<FrameLayout
android:id="@+id/fragment_rg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/rb_group"
android:layout_marginBottom="2dp">
</FrameLayout>
<RadioGroup
android:id="@+id/rb_group"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_alignParentBottom="true"
android:background="@color/color_grey"
android:orientation="horizontal">
<RadioButton
android:id="@+id/rb_note"
style="@style/tab_menu_item"
android:drawableTop="@drawable/table_menu_note"
android:text="记账"/>
<RadioButton
android:id="@+id/rb_table"
style="@style/tab_menu_item"
android:drawableTop="@drawable/table_menu_table"
android:text="图表"/>
<RadioButton
android:id="@+id/rb_find"
style="@style/tab_menu_item"
android:drawableTop="@drawable/table_menu_find"
android:text="发现"/>
<RadioButton
android:id="@+id/rb_mine"
style="@style/tab_menu_item"
android:drawableTop="@drawable/table_menu_mine"
android:text="个人"/>
</RadioGroup>
</RelativeLayout>
其实与第二种方法 没什么 太大区别 只是使用RadioButton 代替了 TextView
Activity文件。。。
package com.mingrisoft.bottomtabbar;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.RadioButton;
import android.widget.RadioGroup;
public class Style3Activity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener {
private RadioGroup rbTab;
private MyFragment myFragment1,myFragment2, myFragment3, myFragment4;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_style3);
bindView();
}
// UI 初始化 与 事件 绑定
private void bindView(){
rbTab = findViewById(R.id.rb_group);
// 最为重要的一句 为 RadioGroup注册监听 判断哪个组件为选中状态 checked
rbTab.setOnCheckedChangeListener(this);
// 默认设置rbNote为选中状态
((RadioButton) findViewById(R.id.rb_note)).setChecked(true);
}
//隐藏所有Fragment
public void hideAllFragment(FragmentTransaction transaction){
if(myFragment1 != null){
transaction.hide(myFragment1);
}
if(myFragment2 != null){
transaction.hide(myFragment2);
}
if(myFragment3 != null){
transaction.hide(myFragment3);
}
if(myFragment4 != null){
transaction.hide(myFragment4);
}
}
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
hideAllFragment(transaction);
switch (checkedId){
case R.id.rb_note:
if(myFragment1 == null){
myFragment1 = MyFragment.getInstance("记账");
transaction.add(R.id.fragment_rg, myFragment1);
} else {
transaction.show(myFragment1);
}
break;
case R.id.rb_table:
if(myFragment2 == null){
myFragment2 = MyFragment.getInstance("图表");
transaction.add(R.id.fragment_rg, myFragment2);
} else {
transaction.show(myFragment2);
}
break;
case R.id.rb_find:
if(myFragment3 == null){
myFragment3 = MyFragment.getInstance("发现");
transaction.add(R.id.fragment_rg, myFragment3);
} else {
transaction.show(myFragment3);
}
break;
case R.id.rb_mine:
if(myFragment4 == null){
myFragment4 = MyFragment.getInstance("个人");
transaction.add(R.id.fragment_rg, myFragment4);
} else {
transaction.show(myFragment4);
}
break;
}
transaction.commit();
}
}
监听事件变成了RadioGroup 的 onCheckedChanged其他与第二种方式 一致。
第四个 方法 ViewPager + RadioGroup
使用ViewPager 代替 了 Framlayout 使页面 有 滑动效果
布局文件
<?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=".Style4Activity">
<android.support.v4.view.ViewPager
android:id="@+id/vp_fragments"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/rg_tabs">
</android.support.v4.view.ViewPager>
<RadioGroup
android:id="@+id/rg_tabs"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_alignParentBottom="true"
android:background="@color/color_grey"
android:orientation="horizontal">
<RadioButton
android:id="@+id/tab_note"
style="@style/tab_menu_item"
android:checked="true"
android:drawableTop="@drawable/table_menu_note"
android:text="@string/tab_note"/>
<RadioButton
android:id="@+id/tab_table"
style="@style/tab_menu_item"
android:drawableTop="@drawable/table_menu_table"
android:text="@string/tab_table"/>
<RadioButton
android:id="@+id/tab_find"
style="@style/tab_menu_item"
android:drawableTop="@drawable/table_menu_find"
android:text="@string/tab_find"/>
<RadioButton
android:id="@+id/tab_mine"
style="@style/tab_menu_item"
android:drawableTop="@drawable/table_menu_mine"
android:text="@string/tab_mine"/>
</RadioGroup>
</RelativeLayout>
Activity 文件
package com.mingrisoft.bottomtabbar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import java.util.ArrayList;
import java.util.List;
public class Style4Activity extends AppCompatActivity {
private ViewPager mViewPager;
private RadioGroup mRadioGroup;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_style4);
initView();
}
@Override
protected void onDestroy() {
super.onDestroy();
mViewPager.removeOnPageChangeListener(mPageChangeListener);
}
public void initView(){
mViewPager = findViewById(R.id.vp_fragments);
mRadioGroup = findViewById(R.id.rg_tabs);
// 碎片列表
// 初始化碎片 和 碎片列表
List<MyFragment> myFragments = new ArrayList<>(4);
myFragments.add(MyFragment.getInstance("记账"));
myFragments.add(MyFragment.getInstance("报表"));
myFragments.add(MyFragment.getInstance("发现"));
myFragments.add(MyFragment.getInstance("我的"));
// 管理碎片列表的Adapter
// 初始化FragmentPagerAdapter与ViewPager
FragmentPagerAdapter mAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager(), myFragments);
mViewPager.setAdapter(mAdapter);
// 分别设置 监听
mRadioGroup.setOnCheckedChangeListener(mCheckedChangeListener);
mViewPager.addOnPageChangeListener(mPageChangeListener);
}
// 页面改变事件监听 主要是与 RadioGroup 保持一致
private ViewPager.OnPageChangeListener mPageChangeListener = new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int i, float v, int i1) {
}
@Override
public void onPageSelected(int i) {
// 界面的 序号 对应 RadioGroup 中 RadioButton 的 顺序
RadioButton radioButton = (RadioButton) mRadioGroup.getChildAt(i);
radioButton.setChecked(true);
}
@Override
public void onPageScrollStateChanged(int i) {
}
};
// RadioGroup中RadioButton 选中按钮的 改变 保持 和 ViewPager 中 碎片对应一致
private RadioGroup.OnCheckedChangeListener mCheckedChangeListener = new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
// 找到CheckId 对应的 编号 也可以使用 switch
for(int i=0; i < group.getChildCount(); i++){
if(group.getChildAt(i).getId() == checkedId){
// 相等则 找到 选中RadioButton对应的 编号顺序 设置mViewPager
mViewPager.setCurrentItem(i);
break;
}
}
}
};
private class MyFragmentPagerAdapter extends FragmentPagerAdapter{
private List<MyFragment> mList;
MyFragmentPagerAdapter(FragmentManager fm, List<MyFragment> list){
super(fm);
this.mList = list;
}
@Override
public Fragment getItem(int i) {
// mList 为空 就 返回空 否则返回当前 项
return this.mList == null ? null : this.mList.get(i);
}
@Override
public int getCount() {
return this.mList == null ? 0 : this.mList.size();
}
}
}
主要设置 了 自定义的 FragmentPagerAdapter 来对 ViewPager 进行管理。 然后 对 RadioGroup 和 ViewPager 分别设置了监听事件。。。 使界面 的 切换 与 Button 的点击 保持一致 ViewPager 可以是 页面 左右滑动。
以上 效果图相差不大
**带页面跳转 功能的 底部导航 **
如下图
中间的图片 找不到 资源 就用了 系统 图表 只是表明 该按钮比较特别 。
<?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=".Style4Activity">
<android.support.v4.view.ViewPager
android:id="@+id/vp_fragments"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/rg_tabs">
</android.support.v4.view.ViewPager>
<RadioGroup
android:id="@+id/rg_tabs"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_alignParentBottom="true"
android:background="@color/color_grey"
android:orientation="horizontal">
<RadioButton
android:id="@+id/tab_note"
style="@style/tab_menu_item"
android:checked="true"
android:drawableTop="@drawable/table_menu_note"
android:text="@string/tab_note"/>
<RadioButton
android:id="@+id/tab_table"
style="@style/tab_menu_item"
android:drawableTop="@drawable/table_menu_table"
android:text="@string/tab_table"/>
<View
style="@style/tab_menu_item"/>
<RadioButton
android:id="@+id/tab_find"
style="@style/tab_menu_item"
android:drawableTop="@drawable/table_menu_find"
android:text="@string/tab_find"/>
<RadioButton
android:id="@+id/tab_mine"
style="@style/tab_menu_item"
android:drawableTop="@drawable/table_menu_mine"
android:text="@string/tab_mine"/>
</RadioGroup>
<ImageView
android:id="@+id/iv_sign"
android:layout_width="80dp"
android:layout_height="80dp"
android:contentDescription="@string/str_register"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="@android:color/transparent"
android:src="@mipmap/ic_launcher" />
</RelativeLayout>
RadioGroup 中 先填充 一个 View 然后 用一个 ImageView 覆盖 这样 不会遮挡住其他底部导航按钮。
即使 多了个 界面 跳转 按钮 原理 与 第四 个 其实 也一样 不过 需要注意
ViewPager 与 RadioGroup 的 事件监听
package com.mingrisoft.bottomtabbar;
import android.content.Intent;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import java.util.ArrayList;
import java.util.List;
public class Style5Activity extends AppCompatActivity {
private ImageView mImageView;
private RadioGroup mRadioGroup;
private ViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_style5);
initView();
}
@Override
protected void onDestroy() {
super.onDestroy();
mViewPager.removeOnPageChangeListener(pageChangeListener);
}
private void initView(){
mImageView = findViewById(R.id.iv_sign);
mRadioGroup = findViewById(R.id.rg_tabs);
mViewPager = findViewById(R.id.vp_fragments);
List<MyFragment> myFragments = new ArrayList<>(4);
myFragments.add(MyFragment.getInstance("记账"));
myFragments.add(MyFragment.getInstance("图表"));
myFragments.add(MyFragment.getInstance("发现"));
myFragments.add(MyFragment.getInstance("我的"));
FragmentPagerAdapter adapter = new MyFragmentPagerAdapter(getSupportFragmentManager(), myFragments);
mViewPager.setAdapter(adapter);
mImageView.setOnClickListener(clickListener);
mViewPager.addOnPageChangeListener(pageChangeListener);
mRadioGroup.setOnCheckedChangeListener(checkedChangeListener);
}
View.OnClickListener clickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.iv_sign:
Intent intent = new Intent(Style5Activity.this, Style1Activity.class);
startActivity(intent);
break;
}
}
};
RadioGroup.OnCheckedChangeListener checkedChangeListener = new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId){
case R.id.tab_note:
mViewPager.setCurrentItem(0);
break;
case R.id.tab_table:
mViewPager.setCurrentItem(1);
break;
case R.id.tab_find:
mViewPager.setCurrentItem(2);
break;
case R.id.tab_mine:
mViewPager.setCurrentItem(3);
break;
}
}
};
ViewPager.OnPageChangeListener pageChangeListener = new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int i, float v, int i1) {
}
@Override
public void onPageSelected(int i) {
if(i < 2){
RadioButton radioButton = (RadioButton) mRadioGroup.getChildAt(i);
radioButton.setChecked(true);
} else {
RadioButton radioButton = (RadioButton) mRadioGroup.getChildAt(i+1);
radioButton.setChecked(true);
}
}
@Override
public void onPageScrollStateChanged(int i) {
}
};
class MyFragmentPagerAdapter extends FragmentPagerAdapter{
private List<MyFragment> mList;
MyFragmentPagerAdapter(FragmentManager fm, List<MyFragment> list){
super(fm);
this.mList = list;
}
@Override
public Fragment getItem(int i) {
return this.mList == null ? null : this.mList.get(i);
}
@Override
public int getCount() {
return this.mList == null ? 0 : this.mList.size();
}
}
}
一定要注意这里的 RadioGroup 中间有一个占位的 View
对 RadioGroup.OnCheckedChangeListener的监听 使用的 switch 而不是 for循环 因为使用 for 循环 的话 因为 RadioGroup 的 子控件数量 与 碎片 数量不一致 会 越界
对 ViewPager.OnPageChangeListener 事件的监听 加上一个 判断 对 i 的判断
底部导航 差不多 应该就这么多 。 希望自己 能够 记住如何使用