首页 > 代码库 > Android中Fragment和ViewPager那点事儿
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嵌套来实现主布局:
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 xmlns:tools="http://schemas.android.com/tools" 5 android:id="@+id/activity_main" 6 android:layout_width="match_parent" 7 android:layout_height="match_parent" 8 android:orientation="vertical" 9 tools:context="com.example.administrator.viewpagerfragment.MainActivity"> 10 11 <LinearLayout 12 android:background="@color/colorblack" 13 android:padding="10dp" 14 android:layout_width="match_parent" 15 android:layout_height="wrap_content"> 16 17 <TextView 18 android:layout_width="0dp" 19 android:layout_weight="1" 20 android:gravity="center_vertical" 21 android:layout_height="match_parent" 22 android:layout_marginLeft="5dp" 23 android:text="潘侯爷微信" 24 android:textSize="20sp" 25 android:textColor="@color/colorWhite"/> 26 27 <ImageView 28 android:src="http://www.mamicode.com/@mipmap/jy_drltsz_btn_addperson" 29 android:adjustViewBounds="true" 30 android:maxHeight="23dp" 31 android:layout_width="wrap_content" 32 android:layout_height="wrap_content" /> 33 </LinearLayout> 34 35 36 <android.support.v4.view.ViewPager 37 android:id="@+id/viewPager" 38 android:layout_width="match_parent" 39 android:layout_height="0dp" 40 android:layout_weight="1"/> 41 42 <View 43 android:layout_width="match_parent" 44 android:layout_height="1dp" 45 android:background="@color/colornormal"/> 46 47 <LinearLayout 48 android:orientation="horizontal" 49 android:padding="5dp" 50 android:layout_width="match_parent" 51 android:layout_height="wrap_content"> 52 53 <LinearLayout 54 android:id="@+id/weixin" 55 android:clickable="true" 56 android:orientation="vertical" 57 android:layout_width="0dp" 58 android:gravity="center" 59 android:layout_weight="1" 60 android:layout_height="wrap_content"> 61 62 <ImageView 63 android:id="@+id/weixin_img" 64 android:background="@drawable/weixin_picture_selector" 65 android:layout_width="30dp" 66 android:layout_height="25dp" /> 67 <TextView 68 android:id="@+id/weixin_txt" 69 android:layout_width="wrap_content" 70 android:gravity="center" 71 android:layout_height="wrap_content" 72 android:text="微信" 73 android:textSize="12sp" 74 android:textColor="@drawable/weixin_text_selector"/> 75 </LinearLayout> 76 77 <LinearLayout 78 android:id="@+id/contact" 79 android:clickable="true" 80 android:orientation="vertical" 81 android:layout_width="0dp" 82 android:gravity="center" 83 android:layout_weight="1" 84 android:layout_height="wrap_content"> 85 86 <ImageView 87 android:id="@+id/contact_img" 88 android:background="@drawable/txl_picture_selector" 89 android:layout_width="30dp" 90 android:layout_height="25dp" /> 91 92 <TextView 93 android:id="@+id/contact_txt" 94 android:layout_width="wrap_content" 95 android:gravity="center" 96 android:layout_height="wrap_content" 97 android:text="通讯录" 98 android:textSize="12sp" 99 android:textColor="@drawable/weixin_text_selector"/> 100 </LinearLayout> 101 102 <LinearLayout 103 android:id="@+id/find" 104 android:clickable="true" 105 android:orientation="vertical" 106 android:layout_width="0dp" 107 android:gravity="center" 108 android:layout_weight="1" 109 android:layout_height="wrap_content"> 110 111 <ImageView 112 android:id="@+id/find_img" 113 android:background="@drawable/find_picture_selector" 114 android:layout_width="30dp" 115 android:layout_height="25dp" /> 116 <TextView 117 android:id="@+id/find_txt" 118 android:layout_width="wrap_content" 119 android:gravity="center" 120 android:layout_height="wrap_content" 121 android:text="发现" 122 android:textSize="12sp" 123 android:textColor="@drawable/weixin_text_selector"/> 124 </LinearLayout> 125 126 <LinearLayout 127 android:id="@+id/self" 128 android:clickable="true" 129 android:orientation="vertical" 130 android:layout_width="0dp" 131 android:gravity="center" 132 android:layout_weight="1" 133 android:layout_height="wrap_content"> 134 135 <ImageView 136 android:id="@+id/self_img" 137 android:background="@drawable/me_picture_selector" 138 android:layout_width="30dp" 139 android:layout_height="25dp" /> 140 <TextView 141 android:id="@+id/self_txt" 142 android:layout_width="wrap_content" 143 android:gravity="center" 144 android:layout_height="wrap_content" 145 android:text="我" 146 android:textSize="12sp" 147 android:textColor="@drawable/weixin_text_selector"/> 148 </LinearLayout> 149 </LinearLayout> 150 </LinearLayout>
第二步:layout中fragment的布局文件(可自由扩展)
这里四个导航对应四个不同的fragment(实现上面的效果,也可以只建立一个fragment,但这样不利于后期扩展),这里我们只演示其中一个weixin_fragment.xml(其他三个为 contactListFragment; findFragment;selfFragment)
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 android:orientation="vertical" 5 android:layout_width="match_parent" 6 android:layout_height="match_parent"> 7 <TextView 8 android:id="@+id/tv" 9 android:layout_width="match_parent" 10 android:layout_height="match_parent" 11 android:text="没有微信消息" 12 android:gravity="center" 13 android:textSize="50sp"/> 14 </LinearLayout>
第三步:drable中设定下方导航组件不同的形态
导航组件中文字形态变化只是颜色不同,图片的话需要设置点击前后不同的图片(这里演示一种)
(1)文字的变化wenxin_text_selector.xml
这里使用selected而不用checked的原因:个人使用的导航布局为linerlayout,并且为linerlayout设置chiclable而不是其中的Text/imageView,所以为了判断变化,这里使用了selected,方便代码中设置调用。
1 <?xml version="1.0" encoding="utf-8"?> 2 <selector xmlns:android="http://schemas.android.com/apk/res/android"> 3 <item android:color="@color/colorpressed" android:state_selected="true"/> 4 <item android:color="@color/colornormal" android:state_selected="false" /> 5 </selector>
(2)图片的变化weixin_picture_selector.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <selector xmlns:android="http://schemas.android.com/apk/res/android"> 3 <item android:drawable="@mipmap/weixin_pressed" android:state_selected="true"/> 4 <item android:drawable="@mipmap/weixin_normal" android:state_selected="false" /> 5 </selector>
第四步:Java中对应fragment布局的Fragment继承类
这里建议继承android.support.v4.app.Fragment包下的.Fragment,因为后面要用的FragmentPagerAdapter属于V4包,应该统一。
4个fragment对应4个java类,这里演示一个,其他三个都一样。
1 import android.os.Bundle; 2 import android.support.annotation.Nullable; 3 import android.support.v4.app.Fragment; 4 import android.view.LayoutInflater; 5 import android.view.View; 6 import android.view.ViewGroup; 7 import android.widget.TextView; 8 /** 9 * Created by panchengjia on 2016/12/24. 10 */ 11 public class WeixinFragment extends Fragment { 12 @Nullable 13 @Override 14 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 15 View view = inflater.inflate(R.layout.weixin_fragment,container,false); 16 return view; 17 } 18 }
第五步:java中功能实现MainActivity.java文件
代码中详细标注了各个实现步骤的注释,这里不再赘述(为了提高程序运行效率,很多重复方法未封装,代码看起来有点臃肿了)
1 import android.support.v4.app.Fragment; 2 import android.support.v4.app.FragmentManager; 3 import android.support.v4.app.FragmentPagerAdapter; 4 import android.support.v4.view.ViewPager; 5 import android.support.v7.app.AppCompatActivity; 6 import android.os.Bundle; 7 import android.view.View; 8 import android.widget.ImageView; 9 import android.widget.LinearLayout; 10 import android.widget.TextView; 11 import java.util.ArrayList; 12 13 public class MainActivity extends AppCompatActivity implements View.OnClickListener { 14 //声明存储fragment的集合 15 private ArrayList<Fragment> fragments; 16 //声明四个导航对应fragment 17 WeixinFragment weixinFragment; 18 ContactListFragment contactListFragment; 19 FindFragment findFragment; 20 SelfFragment selfFragment; 21 //声明ViewPager 22 private ViewPager viewPager; 23 FragmentManager fragmentManager;//声明fragment管理 24 //声明导航栏中对应的布局 25 private LinearLayout weixin, contact, find, self; 26 //声明导航栏中包含的imageview和textview 27 private ImageView weixin_img, contact_img, find_img, self_img; 28 private TextView weixin_txt, contact_txt, find_txt, self_txt; 29 30 @Override 31 protected void onCreate(Bundle savedInstanceState) { 32 super.onCreate(savedInstanceState); 33 setContentView(R.layout.activity_main); 34 //初始化加载首页布局 35 initView(); 36 //调用自定义initListener方法,为各个组件添加监听事件 37 initListener(); 38 //设置默认选择的pager和导航栏的状态 39 viewPager.setCurrentItem(0); 40 weixin_img.setSelected(true); 41 weixin_txt.setSelected(true); 42 } 43 44 private void initListener() { 45 //为四大导航组件添加监听 46 weixin.setOnClickListener(this); 47 contact.setOnClickListener(this); 48 find.setOnClickListener(this); 49 self.setOnClickListener(this); 50 //为viewpager添加页面变化的监听以及事件处理 51 viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { 52 @Override 53 public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 54 55 } 56 57 @Override 58 public void onPageSelected(int position) { 59 //根据位置直接决定显示哪个fragment 60 viewPager.setCurrentItem(position); 61 switch (position) { 62 case 0: 63 weixin_img.setSelected(true); 64 weixin_txt.setSelected(true); 65 66 contact_img.setSelected(false); 67 contact_txt.setSelected(false); 68 find_img.setSelected(false); 69 find_txt.setSelected(false); 70 self_img.setSelected(false); 71 self_txt.setSelected(false); 72 73 break; 74 case 1: 75 weixin_img.setSelected(false); 76 weixin_txt.setSelected(false); 77 78 contact_img.setSelected(true); 79 contact_txt.setSelected(true); 80 find_img.setSelected(false); 81 find_txt.setSelected(false); 82 self_img.setSelected(false); 83 self_txt.setSelected(false); 84 85 break; 86 case 2: 87 weixin_img.setSelected(false); 88 weixin_txt.setSelected(false); 89 90 contact_img.setSelected(false); 91 contact_txt.setSelected(false); 92 find_img.setSelected(true); 93 find_txt.setSelected(true); 94 self_img.setSelected(false); 95 self_txt.setSelected(false); 96 97 break; 98 case 3: 99 weixin_img.setSelected(false); 100 weixin_txt.setSelected(false); 101 102 contact_img.setSelected(false); 103 contact_txt.setSelected(false); 104 find_img.setSelected(false); 105 find_txt.setSelected(false); 106 self_img.setSelected(true); 107 self_txt.setSelected(true); 108 break; 109 } 110 } 111 112 @Override 113 public void onPageScrollStateChanged(int state) { 114 115 } 116 }); 117 118 } 119 120 private void initView() { 121 //在主布局中根据id找到ViewPager 122 viewPager = (ViewPager) findViewById(R.id.viewPager); 123 //实例化所属四个fragment 124 weixinFragment = new WeixinFragment(); 125 contactListFragment = new ContactListFragment(); 126 findFragment = new FindFragment(); 127 selfFragment = new SelfFragment(); 128 fragments = new ArrayList<>(); 129 //添加fragments到集合中 130 fragments.add(weixinFragment); 131 fragments.add(contactListFragment); 132 fragments.add(findFragment); 133 fragments.add(selfFragment); 134 fragmentManager = getSupportFragmentManager(); 135 //为ViewPager设置适配器用于部署fragments 136 viewPager.setAdapter(new MyFragmentPagerAdapter(fragmentManager)); 137 138 139 weixin = (LinearLayout) findViewById(R.id.weixin); 140 contact = (LinearLayout) findViewById(R.id.contact); 141 find = (LinearLayout) findViewById(R.id.find); 142 self = (LinearLayout) findViewById(R.id.self); 143 144 145 weixin_img = (ImageView) findViewById(R.id.weixin_img); 146 contact_img = (ImageView) findViewById(R.id.contact_img); 147 find_img = (ImageView) findViewById(R.id.find_img); 148 self_img = (ImageView) findViewById(R.id.self_img); 149 150 weixin_txt = (TextView) findViewById(R.id.weixin_txt); 151 contact_txt = (TextView) findViewById(R.id.contact_txt); 152 find_txt = (TextView) findViewById(R.id.find_txt); 153 self_txt = (TextView) findViewById(R.id.self_txt); 154 } 155 156 /** 157 * 设置导航栏的点击事件并同步更新对应的ViewPager 158 * 点击事件其实就是更改导航布局中对应的Text/ImageView 159 * 的选中状态,配合drable中的selector更改图片以及文字变化 160 * 161 * @param v 162 */ 163 @Override 164 public void onClick(View v) { 165 switch (v.getId()) { 166 case R.id.weixin: 167 viewPager.setCurrentItem(0); 168 weixin_img.setSelected(true); 169 weixin_txt.setSelected(true); 170 171 contact_img.setSelected(false); 172 contact_txt.setSelected(false); 173 find_img.setSelected(false); 174 find_txt.setSelected(false); 175 self_img.setSelected(false); 176 self_txt.setSelected(false); 177 178 break; 179 case R.id.contact: 180 viewPager.setCurrentItem(1); 181 weixin_img.setSelected(false); 182 weixin_txt.setSelected(false); 183 184 contact_img.setSelected(true); 185 contact_txt.setSelected(true); 186 find_img.setSelected(false); 187 find_txt.setSelected(false); 188 self_img.setSelected(false); 189 self_txt.setSelected(false); 190 191 break; 192 case R.id.find: 193 viewPager.setCurrentItem(2); 194 weixin_img.setSelected(false); 195 weixin_txt.setSelected(false); 196 197 contact_img.setSelected(false); 198 contact_txt.setSelected(false); 199 find_img.setSelected(true); 200 find_txt.setSelected(true); 201 self_img.setSelected(false); 202 self_txt.setSelected(false); 203 204 break; 205 case R.id.self: 206 viewPager.setCurrentItem(3); 207 weixin_img.setSelected(false); 208 weixin_txt.setSelected(false); 209 210 contact_img.setSelected(false); 211 contact_txt.setSelected(false); 212 find_img.setSelected(false); 213 find_txt.setSelected(false); 214 self_img.setSelected(true); 215 self_txt.setSelected(true); 216 217 break; 218 } 219 } 220 221 //创建FragmentPagerAdapter 222 class MyFragmentPagerAdapter extends FragmentPagerAdapter { 223 224 public MyFragmentPagerAdapter(FragmentManager fm) { 225 super(fm); 226 } 227 228 @Override 229 public android.support.v4.app.Fragment getItem(int position) { 230 return fragments.get(position); 231 } 232 233 @Override 234 public int getCount() { 235 return fragments.size(); 236 } 237 } 238 }
后期就微信的其他功能的实现做简单介绍,不早了,休息
Android中Fragment和ViewPager那点事儿