详解Android中fragment和viewpager的那点事儿
在之前的博文《android 中使用 viewpager实现屏幕页面切换和页面轮播效果》和《详解android中fragment的两种创建方式》以及《android中fragment与activity之间的交互(两种实现方式)》中我们介绍了viewpager以及fragment各自的使用场景以及不同的实现方式。
那如果将他们两结合起来,会不会擦出点火花呢,答案是肯定的。之前在介绍viewpager时,我们实现了多个imageview的切换,并配合更新导航原点的状态。那我们现在就将之前的imageview替换为fragment,将导航原点替换为更加生动的布局,比如我们经常使用的微信(取消了actionbar):
(1)我们可以通过点击下面的导航按钮选择对应的显示界面(fragment),如下图:
(2)我们也可以通过滑动界面(fragment)来实现界面切换,同时下面的导航按钮状态也会发生变化,如下图:
那么重点来了,这样的效果要怎么实现呢,大至分为以下的步骤
(1)布局文件中直接部署viewpager以及下方的导航布局
(2)根据导航的个数来建立对应的fragment布局并建立配套的fragment类(为方便后期扩展,建议建立与导航个数相同的fragments)
(3)drable下使用selector实现导航组件的形态变化
(4)通过fragmentpageradapter(v4包下)实现viewpager与fragment的关联
(5)设置下方导航的点击事件以及viewpager的onpagechangelistener方法实现对应的状态改变
第一步:layout中的主布局文件activity_main.xml文件
取消了actionbar,采用linearlayout嵌套来实现主布局:
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.administrator.viewpagerfragment.mainactivity"> <linearlayout android:background="@color/colorblack" android:padding="10dp" android:layout_width="match_parent" android:layout_height="wrap_content"> <textview android:layout_width="0dp" android:layout_weight="1" android:gravity="center_vertical" android:layout_height="match_parent" android:layout_marginleft="5dp" android:text="潘侯爷微信" android:textsize="20sp" android:textcolor="@color/colorwhite"/> <imageview android:src="@mipmap/jy_drltsz_btn_addperson" android:adjustviewbounds="true" android:maxheight="23dp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </linearlayout> <android.support.v4.view.viewpager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/> <view android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/colornormal"/> <linearlayout android:orientation="horizontal" android:padding="5dp" android:layout_width="match_parent" android:layout_height="wrap_content"> <linearlayout android:id="@+id/weixin" android:clickable="true" android:orientation="vertical" android:layout_width="0dp" android:gravity="center" android:layout_weight="1" android:layout_height="wrap_content"> <imageview android:id="@+id/weixin_img" android:background="@drawable/weixin_picture_selector" android:layout_width="30dp" android:layout_height="25dp" /> <textview android:id="@+id/weixin_txt" android:layout_width="wrap_content" android:gravity="center" android:layout_height="wrap_content" android:text="微信" android:textsize="12sp" android:textcolor="@drawable/weixin_text_selector"/> </linearlayout> <linearlayout android:id="@+id/contact" android:clickable="true" android:orientation="vertical" android:layout_width="0dp" android:gravity="center" android:layout_weight="1" android:layout_height="wrap_content"> <imageview android:id="@+id/contact_img" android:background="@drawable/txl_picture_selector" android:layout_width="30dp" android:layout_height="25dp" /> <textview android:id="@+id/contact_txt" android:layout_width="wrap_content" android:gravity="center" android:layout_height="wrap_content" android:text="通讯录" android:textsize="12sp" android:textcolor="@drawable/weixin_text_selector"/> </linearlayout> <linearlayout android:id="@+id/find" android:clickable="true" android:orientation="vertical" android:layout_width="0dp" android:gravity="center" android:layout_weight="1" android:layout_height="wrap_content"> <imageview android:id="@+id/find_img" android:background="@drawable/find_picture_selector" android:layout_width="30dp" android:layout_height="25dp" /> <textview android:id="@+id/find_txt" android:layout_width="wrap_content" android:gravity="center" android:layout_height="wrap_content" android:text="发现" android:textsize="12sp" android:textcolor="@drawable/weixin_text_selector"/> </linearlayout> <linearlayout android:id="@+id/self" android:clickable="true" android:orientation="vertical" android:layout_width="0dp" android:gravity="center" android:layout_weight="1" android:layout_height="wrap_content"> <imageview android:id="@+id/self_img" android:background="@drawable/me_picture_selector" android:layout_width="30dp" android:layout_height="25dp" /> <textview android:id="@+id/self_txt" android:layout_width="wrap_content" android:gravity="center" android:layout_height="wrap_content" android:text="我" android:textsize="12sp" android:textcolor="@drawable/weixin_text_selector"/> </linearlayout> </linearlayout> </linearlayout>
第二步:layout中fragment的布局文件(可*扩展)
这里四个导航对应四个不同的fragment(实现上面的效果,也可以只建立一个fragment,但这样不利于后期扩展),这里我们只演示其中一个weixin_fragment.xml(其他三个为 contactlistfragment; findfragment;selffragment)
<?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" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <textview android:id="@+id/tv" android:layout_width="match_parent" android:layout_height="match_parent" android:text="没有微信消息" android:gravity="center" android:textsize="50sp"/> </linearlayout>
第三步:drable中设定下方导航组件不同的形态
导航组件中文字形态变化只是颜色不同,图片的话需要设置点击前后不同的图片(这里演示一种)
(1)文字的变化wenxin_text_selector.xml
这里使用selected而不用checked的原因:个人使用的导航布局为linerlayout,并且为linerlayout设置chiclable而不是其中的text/imageview,所以为了判断变化,这里使用了selected,方便代码中设置调用。
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="@color/colorpressed" android:state_selected="true"/> <item android:color="@color/colornormal" android:state_selected="false" /> </selector>
(2)图片的变化weixin_picture_selector.xml
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@mipmap/weixin_pressed" android:state_selected="true"/> <item android:drawable="@mipmap/weixin_normal" android:state_selected="false" /> </selector>
第四步:java中对应fragment布局的fragment继承类
这里建议继承android.support.v4.app.fragment包下的.fragment,因为后面要用的fragmentpageradapter属于v4包,应该统一。
4个fragment对应4个java类,这里演示一个,其他三个都一样。
import android.os.bundle; import android.support.annotation.nullable; import android.support.v4.app.fragment; import android.view.layoutinflater; import android.view.view; import android.view.viewgroup; import android.widget.textview; /** * created by panchengjia on 2016/12/24. */ public class weixinfragment extends fragment { @nullable @override public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) { view view = inflater.inflate(r.layout.weixin_fragment,container,false); return view; } }
第五步:java中功能实现mainactivity.java文件
代码中详细标注了各个实现步骤的注释,这里不再赘述(为了提高程序运行效率,很多重复方法未封装,代码看起来有点臃肿了)
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.linearlayout; import android.widget.textview; import java.util.arraylist; public class mainactivity extends appcompatactivity implements view.onclicklistener { //声明存储fragment的集合 private arraylist<fragment> fragments; //声明四个导航对应fragment weixinfragment weixinfragment; contactlistfragment contactlistfragment; findfragment findfragment; selffragment selffragment; //声明viewpager private viewpager viewpager; fragmentmanager fragmentmanager;//声明fragment管理 //声明导航栏中对应的布局 private linearlayout weixin, contact, find, self; //声明导航栏中包含的imageview和textview private imageview weixin_img, contact_img, find_img, self_img; private textview weixin_txt, contact_txt, find_txt, self_txt; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); //初始化加载首页布局 initview(); //调用自定义initlistener方法,为各个组件添加监听事件 initlistener(); //设置默认选择的pager和导航栏的状态 viewpager.setcurrentitem(0); weixin_img.setselected(true); weixin_txt.setselected(true); } private void initlistener() { //为四大导航组件添加监听 weixin.setonclicklistener(this); contact.setonclicklistener(this); find.setonclicklistener(this); self.setonclicklistener(this); //为viewpager添加页面变化的监听以及事件处理 viewpager.addonpagechangelistener(new viewpager.onpagechangelistener() { @override public void onpagescrolled(int position, float positionoffset, int positionoffsetpixels) { } @override public void onpageselected(int position) { //根据位置直接决定显示哪个fragment viewpager.setcurrentitem(position); switch (position) { case 0: weixin_img.setselected(true); weixin_txt.setselected(true); contact_img.setselected(false); contact_txt.setselected(false); find_img.setselected(false); find_txt.setselected(false); self_img.setselected(false); self_txt.setselected(false); break; case 1: weixin_img.setselected(false); weixin_txt.setselected(false); contact_img.setselected(true); contact_txt.setselected(true); find_img.setselected(false); find_txt.setselected(false); self_img.setselected(false); self_txt.setselected(false); break; case 2: weixin_img.setselected(false); weixin_txt.setselected(false); contact_img.setselected(false); contact_txt.setselected(false); find_img.setselected(true); find_txt.setselected(true); self_img.setselected(false); self_txt.setselected(false); break; case 3: weixin_img.setselected(false); weixin_txt.setselected(false); contact_img.setselected(false); contact_txt.setselected(false); find_img.setselected(false); find_txt.setselected(false); self_img.setselected(true); self_txt.setselected(true); break; } } @override public void onpagescrollstatechanged(int state) { } }); } private void initview() { //在主布局中根据id找到viewpager viewpager = (viewpager) findviewbyid(r.id.viewpager); //实例化所属四个fragment weixinfragment = new weixinfragment(); contactlistfragment = new contactlistfragment(); findfragment = new findfragment(); selffragment = new selffragment(); fragments = new arraylist<>(); //添加fragments到集合中 fragments.add(weixinfragment); fragments.add(contactlistfragment); fragments.add(findfragment); fragments.add(selffragment); fragmentmanager = getsupportfragmentmanager(); //为viewpager设置适配器用于部署fragments viewpager.setadapter(new myfragmentpageradapter(fragmentmanager)); weixin = (linearlayout) findviewbyid(r.id.weixin); contact = (linearlayout) findviewbyid(r.id.contact); find = (linearlayout) findviewbyid(r.id.find); self = (linearlayout) findviewbyid(r.id.self); weixin_img = (imageview) findviewbyid(r.id.weixin_img); contact_img = (imageview) findviewbyid(r.id.contact_img); find_img = (imageview) findviewbyid(r.id.find_img); self_img = (imageview) findviewbyid(r.id.self_img); weixin_txt = (textview) findviewbyid(r.id.weixin_txt); contact_txt = (textview) findviewbyid(r.id.contact_txt); find_txt = (textview) findviewbyid(r.id.find_txt); self_txt = (textview) findviewbyid(r.id.self_txt); } /** * 设置导航栏的点击事件并同步更新对应的viewpager * 点击事件其实就是更改导航布局中对应的text/imageview * 的选中状态,配合drable中的selector更改图片以及文字变化 * * @param v */ @override public void onclick(view v) { switch (v.getid()) { case r.id.weixin: viewpager.setcurrentitem(0); weixin_img.setselected(true); weixin_txt.setselected(true); contact_img.setselected(false); contact_txt.setselected(false); find_img.setselected(false); find_txt.setselected(false); self_img.setselected(false); self_txt.setselected(false); break; case r.id.contact: viewpager.setcurrentitem(1); weixin_img.setselected(false); weixin_txt.setselected(false); contact_img.setselected(true); contact_txt.setselected(true); find_img.setselected(false); find_txt.setselected(false); self_img.setselected(false); self_txt.setselected(false); break; case r.id.find: viewpager.setcurrentitem(2); weixin_img.setselected(false); weixin_txt.setselected(false); contact_img.setselected(false); contact_txt.setselected(false); find_img.setselected(true); find_txt.setselected(true); self_img.setselected(false); self_txt.setselected(false); break; case r.id.self: viewpager.setcurrentitem(3); weixin_img.setselected(false); weixin_txt.setselected(false); contact_img.setselected(false); contact_txt.setselected(false); find_img.setselected(false); find_txt.setselected(false); self_img.setselected(true); self_txt.setselected(true); break; } } //创建fragmentpageradapter class myfragmentpageradapter extends fragmentpageradapter { public myfragmentpageradapter(fragmentmanager fm) { super(fm); } @override public android.support.v4.app.fragment getitem(int position) { return fragments.get(position); } @override public int getcount() { return fragments.size(); } } }
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!
推荐阅读
-
详解Android中fragment和viewpager的那点事儿
-
Android中ViewPager获取当前显示的Fragment
-
Android 7.0中拍照和图片裁剪适配的问题详解
-
详解Android Libgdx中ScrollPane和Actor事件冲突问题的解决办法
-
Android学习笔记(Android Studio) 4-2-1~2 Fragment详解(一、二)(不可不会的Activity和Fragment)
-
详解Android中的MVP架构分解和实现
-
Android开发中libs和jinLibs文件夹的作用详解
-
详解Android中的MVP架构分解和实现
-
详解Android Libgdx中ScrollPane和Actor事件冲突问题的解决办法
-
Android 7.0中拍照和图片裁剪适配的问题详解