废话前言
刚工作的时候就事采用这种方式实现的底部导航,方便快捷,重要的是好理解。
我将采用我觉得最清晰的思路实现这种方式
一、创建主页面
为了便于查看,我只写了两个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:orientation="vertical">
<!--用来显示切换的Fragment-->
<FrameLayout
android:id="@+id/fl_content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</FrameLayout>
<!-- 分割线 -->
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/colorPrimary" />
<!-- 导航按钮 -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="56dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<!-- 选项卡一 -->
<LinearLayout
android:id="@+id/tab_home"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/iv_home"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/tab_home_iv" />
<TextView
android:id="@+id/text_home"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:gravity="center"
android:lineSpacingMultiplier="0"
android:textColor="@drawable/tab_home_text"
android:text="首页" />
</LinearLayout>
<!--选项卡二-->
<LinearLayout
android:id="@+id/tab_my"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/iv_my"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/tab_my_iv" />
<TextView
android:id="@+id/text_my"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:gravity="center"
android:textColor="@drawable/tab_my_text"
android:text="我的" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
可直接复制使用。没什么难度
二、为tab中的图片文字创建不同状态的文件
1.首先是图片的,不同状态的两个图片
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@mipmap/home_yes" android:state_selected="true"/>
<item android:drawable="@mipmap/home_no"/>
</selector>
2.文字的,不同状态的颜色
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/selected" android:state_selected="true"/>
<item android:color="@color/unselect" />
</selector>
文字颜色只有一个文件即可,图片的分别对应。
三、准备Fragment文件
1.FragmentHome
public class FragmentHome extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.layout_fragment_home, container, false);
return view;
}
}
2.对应xml
<?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">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="首页" />
</LinearLayout>
其他页面仿照即可。很简单的
四、主Activity
前面都是准备工作。接下来才是重头戏,不过也很简单啦。
思路真的很清晰
列提纲:
- 获取主页面xml的控件
- 点击事件触发
- 先把所有tab变成不被选中,然后把点击的变为选中效果
- 初始化APP默认点击第一个tab。
提纲在这,直接上代码了,简单直接,咱们代码中说话
public class BottomCard extends Activity implements View.OnClickListener {
private TextView tab_home_text;
private TextView tab_my_text;
private ImageView tab_home_iv;
private ImageView tab_my_iv;
private FrameLayout fl_content;
private LinearLayout tab_home;
private LinearLayout tab_my;
private FragmentHome fragmentHome;
private FragmentMy fragmentMy;
private Fragment fragment_now = null;//用于保存正在显示的页面,隐藏这个
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_bottomcard);
bindView();
}
private void bindView() {
tab_home_iv = this.findViewById(R.id.iv_home);
tab_home_text = this.findViewById(R.id.text_home);
tab_my_iv = this.findViewById(R.id.iv_my);
tab_my_text = this.findViewById(R.id.text_my);
fl_content = this.findViewById(R.id.fl_content);
tab_home = this.findViewById(R.id.tab_home);
tab_my = this.findViewById(R.id.tab_my);
tab_my.setOnClickListener(this);
tab_home.setOnClickListener(this);
onClick(tab_home);//初始化的时候默认点击第一个tab
}
@Override
public void onClick(View view) {
FragmentTransaction transaction = getFragmentManager().beginTransaction();
switch (view.getId()) {
case R.id.tab_home:
TabAllUnSelect();
TabSelect(tab_home_iv,tab_home_text);
if (fragmentHome == null) {
//如果为空,则new对象,添加到transaction,并展示出来
fragmentHome = new FragmentHome();
if(fragment_now != null){
// 如果当前正在显示Fragment,则隐藏掉
transaction.hide(fragment_now);
}
transaction.add(R.id.fl_content, fragmentHome).show(fragmentHome).commit();
} else {
//不为空,则不添加直接展示当前
if(fragment_now != null){
transaction.hide(fragment_now);
}
// 隐藏当前的fragment,add下一个fragment到Activity中并显示
transaction.show(fragmentHome).commitAllowingStateLoss();
}
fragment_now = fragmentHome;
break;
case R.id.tab_my:
TabAllUnSelect();
TabSelect(tab_my_iv,tab_my_text);
if (fragmentMy == null) {
fragmentMy = new FragmentMy();
if(fragment_now != null){
transaction.hide(fragment_now);
}
transaction.add(R.id.fl_content, fragmentMy).show(fragmentMy).commit();
} else {
if(fragment_now != null){
transaction.hide(fragment_now);
}
transaction.show(fragmentMy).commitAllowingStateLoss();
}
fragment_now = fragmentMy;
break;
}
}
/**
* 选中的tab 的图标和字体颜色
*/
public void TabSelect(View iv, View text) {
iv.setSelected(true);
text.setSelected(true);
}
/**
* 所有的tab 的图标和字体颜色
*/
public void TabAllUnSelect() {
tab_home_iv.setSelected(false);
tab_home_text.setSelected(false);
tab_my_iv.setSelected(false);
tab_my_text.setSelected(false);
}
}
到这里就完成了。思路清晰,看似慌中带急,实则稳中带皮。我去研究RadioButton方式了
补充 常用方式比较
1.在我学习RadioButton方式后,发现与单独TextView一样,都是使用drawableTop这个属性,但是这种属性不易控制导航内部的文字与图片的间距。所以我觉得ImageView+TextView的方式灵活性最高。而且思路也挺清晰的
2.还有google提供的bottomnevagition方式,封装的挺好的,但是我使用又换掉了,好像是因为没有办法控制导航和正文的分割线,具体忘了,所有也就放弃了这种。