Android利用碎片fragment实现底部标题栏(Github模板开源)
在安卓开发当中,一个十分重要的布局则是底部标题栏了,拥有了底部标题栏,我们就拥有了整个软件ui开发的框架,一般而言,整个软件的布局首先就是从底部标题栏开始构建,然后再开始其他模块的编写,组成一个完善的软件,那么如何才能够编写一个底部标题栏呢,我这里使用了碎片来实现,当然是碎片的动态加载的方式,静态加载的话则不可以达到点击按钮切换碎片的功能。
首先先上效果图:
github项目地址:https://github.com/geeksongs/buttontitile
在每一个底部标题栏上一共有四个分类吗,分别是主页,地点,聊天和设置。每一个分类都对应着上方的一个fragment,因此我们需要创建四个fragment来对应下面的每一个分类,下面的底部导航栏不是由fragment来实现的,而是直接在主布局activity_main.xml当中使用imageview和textview组合而成。在activity_main.xml的上方是fragment,因此使用帧布局framelayout,下面是activity_main.xml的布局代码:
一.activity_main.xml
<?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=".mainactivity"> <linearlayout android:id="@+id/tab_linear" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignparentbottom="true" android:orientation="horizontal" android:background="@color/colorprimary"> <linearlayout android:id="@+id/home" android:orientation="vertical" android:layout_weight="1" android:layout_width="0dp" android:layout_height="60dp"> <imageview android:layout_gravity="center" android:layout_width="40dp" android:layout_height="40dp" android:src="@drawable/home"/> <textview android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="主页" android:textcolor="@drawable/text_color_back" /> </linearlayout> <linearlayout android:id="@+id/location" android:orientation="vertical" android:layout_weight="1" android:layout_width="0dp" android:layout_height="60dp"> <imageview android:layout_gravity="center" android:layout_width="40dp" android:layout_height="40dp" android:src="@drawable/location_view"/> <textview android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="地点" android:textcolor="@drawable/text_color_back" /> </linearlayout> <linearlayout android:id="@+id/linear_polymer" android:orientation="vertical" android:layout_weight="1" android:layout_width="0dp" android:layout_height="60dp"> <imageview android:layout_gravity="center" android:layout_width="40dp" android:layout_height="40dp" android:src="@drawable/comment"/> <textview android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="聊天" android:textcolor="@drawable/text_color_back" /> </linearlayout> <linearlayout android:orientation="vertical" android:id="@+id/linear_user" android:layout_weight="1" android:layout_width="0dp" android:layout_height="60dp"> <imageview android:layout_gravity="center" android:layout_width="40dp" android:layout_height="40dp" android:src="@drawable/contrast_view" /> <textview android:layout_gravity="center" android:text="设置" android:textcolor="@drawable/text_color_back" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </linearlayout> </linearlayout> <framelayout android:id="@+id/fragment_frame" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@+id/tab_linear"> </framelayout> </relativelayout>
编写好的界面如下:
然后在我们最开始的演示视频当中大家也看到了我们每点击一次按钮,按钮的颜色就会发生变化,因此我们需要为每一个按钮编写选择器selector,这里就只展示第一个选择器"主页"的selector吧,还有三个按钮,咱们可以利用同样的方式建立selector,如果想要了解其他按钮的selector编写的话,请前往github:https://github.com/geeksongs/buttontitile
二.home.xml
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_selected="true" android:drawable="@drawable/home3"/> <item android:drawable="@drawable/home31"/> </selector>
其中上面的图片我均放置在了drawble文件夹当中,这里强烈推荐阿里云矢量图标库,在这里可以找到你想要图标,网址如下:。然后找到你所需要的图标之后就可以进行下载啦!
三.fragment1.java
接下来是对碎片fragment1.java代码的编写,在这段代码的编写当中所需要注意的是我们将会返回整个fragment.xml的view布局,而不是直接返回一个textview或者imageview之类的控件,这样会让初学者感到十分困惑,为什么不返回整个fragment所对应的xml界面,代码如下:
import android.os.bundle; import androidx.annotation.nullable; import androidx.fragment.app.fragment; import android.view.layoutinflater; import android.view.view; import android.view.viewgroup; import android.widget.textview; /** * a simple {@link fragment} subclass. */ public class fragment1 extends fragment { private string fragmenttext; private textview fragmenttextview; @nullable @override public view oncreateview(layoutinflater inflater, @nullable viewgroup container, @nullable bundle savedinstancestate) { view view=inflater.inflate(r.layout.fragment_fragment1,container,false); return view;//返回view布局 } public fragment1(string fragmenttext) { this.fragmenttext=fragmenttext; } }
其余几个fragment的代码也差不多,只是其构造方法的名称略有不同,所使用了fragment1(2/3/4),毕竟它们的类名不同嘛。编写了fragment的java代码,是时候编写fragment的xml代码了,因为这样才可以将编写好的界面传递到主界面:activity_main.xml当中,代码如下:
四.fragment1.xml
<?xml version="1.0" encoding="utf-8"?> <framelayout 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=".fragment1"> <!-- todo: update blank fragment layout --> <textview android:id="@+id/fragment1" android:layout_width="match_parent" android:layout_height="match_parent" android:textsize="30dp" android:text="这是第一个碎片" /> </framelayout>
由于安卓默认的字体比较小,我就略微修改了一下将字体的大小修改为了30dp,当然你也可以根据自己的需要进行改动,这个fragment文件我们一共需要建立4份,毕竟有四个底部标题栏的按钮。
五.mainactivity.java
下面是主活动的java代码:
public class mainactivity extends appcompatactivity implements view.onclicklistener{ linearlayout homelinear; linearlayout listlinear; linearlayout polylinear; linearlayout userlinear; fragment1 fragmenthome; fragment2 fragmentlist; fragment3 fragmentpoly; fragment4 fragmentuser; private fragmentmanager mfragmentmanger; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); homelinear= (linearlayout) findviewbyid(r.id.home); listlinear= (linearlayout) findviewbyid(r.id.location); polylinear= (linearlayout) findviewbyid(r.id.linear_polymer); userlinear= (linearlayout) findviewbyid(r.id.linear_user); homelinear.setonclicklistener(this); listlinear.setonclicklistener(this); polylinear.setonclicklistener(this); userlinear.setonclicklistener(this); mfragmentmanger = getsupportfragmentmanager(); homelinear.performclick(); } @override public void onclick(view view) { fragmenttransaction fragmenttransaction = mfragmentmanger.begintransaction();//只能是局部变量,不能为全局变量,否则不能重复commit //fragmenttransaction只能使用一次 hideallfragment(fragmenttransaction); switch (view.getid()){ case r.id.home: setallfalse(); homelinear.setselected(true); if (fragmenthome==null){ fragmenthome=new fragment1("home"); fragmenttransaction.add(r.id.fragment_frame,fragmenthome); }else{ fragmenttransaction.show(fragmenthome); } break; case r.id.location: setallfalse(); listlinear.setselected(true); if(fragmentlist==null){ fragmentlist=new fragment2("list"); fragmenttransaction.add(r.id.fragment_frame,fragmentlist); }else { fragmenttransaction.show(fragmentlist); } break; case r.id.linear_polymer: setallfalse(); polylinear.setselected(true); if(fragmentpoly==null){ fragmentpoly=new fragment3("polymer"); fragmenttransaction.add(r.id.fragment_frame,fragmentpoly); }else { fragmenttransaction.show(fragmentpoly); } break; case r.id.linear_user: setallfalse(); userlinear.setselected(true); if(fragmentuser==null){ fragmentuser=new fragment4("user"); fragmenttransaction.add(r.id.fragment_frame,fragmentuser); }else { fragmenttransaction.show(fragmentuser); } break; } fragmenttransaction.commit();//记得必须要commit,否则没有效果 } private void hideallfragment(fragmenttransaction fragmenttransaction) { if(fragmenthome!=null){ fragmenttransaction.hide(fragmenthome); } if(fragmentlist!=null){ fragmenttransaction.hide(fragmentlist); } if(fragmentpoly!=null){ fragmenttransaction.hide(fragmentpoly); } if(fragmentuser!=null){ fragmenttransaction.hide(fragmentuser); } } private void setallfalse() { homelinear.setselected(false); listlinear.setselected(false); polylinear.setselected(false); userlinear.setselected(false); } }
咱们的底部标题栏就这样完美地实现啦,对于代码和整个工程布局还不太明白的地方可以参见github源码:https://github.com/geeksongs/buttontitile,欢迎star呀!