首页 > 代码库 > 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)通过FragmentPagerAdapterV4包下)实现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那点事儿