http://www.cnblogs.com/lichenwei/p/3982302.html

什么是ViewPager?

  关于ViewPager的介绍和使用,在之前我写过一篇相关的文章《安卓开发复习笔记——ViewPager组件(仿微信引导界面)》,不清楚的朋友可以看看,这里就不再重复。

什么是Fragment?

Fragment是Android3.0后新增的概念,Fragment名为碎片,不过却和Activity十分相似,具有自己的生命周期,它是用来描述一些行为或一部分用户界面在一个Activity中,我们可以合并多个Fragment在一个单独的activity中建立多个UI面板,或者重用Fragment在多个activity中。

关于Fragment的生命周期,由于Fragment需要依赖Activity,也就是说当一个Activity的生命周期结束之后,那么Fragment的生命周期也自然结束。如果把一个Activiy比作一座大宅子的话,那么Fragment就可以比作大宅子里的房间,大宅子里的房间其中一间倒塌了,并不会引起整个大宅子的倒塌,但如果大宅子倒塌了,那么大宅里的房间也就都倒塌了。

下面来看下Fragment的生命周期:                    Activity和Fragment生命周期对比(相似):

            

为了更好的理解Fragment,我找了下面的一张图:

  看左边这张图,它是我们传统的手机界面,假设它现在呈现的是一个新闻列表页,那么当我们点击列表项中,我们将会跳转到新闻详细页中,上面是标题,下面是正文,这里是2个Activity。

  再看看右边的图,左边是新闻列表页,右边是新闻详细页,我们可以动态的点击左边的列表项,使得右边的新闻详细页动态变化,这里只有1个Activity里面嵌套了2个Fragment,左边一个,右边一个。

好了,做了简单的介绍后,先来看看今天我们要实现的效果图:(高仿微信主界面)

这里我画了张界面分析图,画图永远的痛,凑合着看哈

这里的XML布局文件,我把每一部分都分开写了:

top1.xml

 1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
2 xmlns:tools="http://schemas.android.com/tools"
3 android:layout_width="match_parent"
4 android:layout_height="50dp"
5 android:background="@drawable/bg"
6 android:paddingLeft="12dp"
7 android:paddingRight="12dp" >
8
9 <LinearLayout
10 android:layout_width="wrap_content"
11 android:layout_height="wrap_content"
12 android:layout_centerVertical="true"
13 android:gravity="center"
14 android:orientation="horizontal" >
15
16 <ImageView
17 android:layout_width="30dp"
18 android:layout_height="30dp"
19 android:src="@drawable/weixin" />
20
21 <TextView
22 android:layout_width="wrap_content"
23 android:layout_height="wrap_content"
24 android:layout_marginLeft="12dp"
25 android:text="微信"
26 android:textColor="@android:color/white"
27 android:textSize="18dp" />
28 </LinearLayout>
29
30 <LinearLayout
31 android:layout_width="wrap_content"
32 android:layout_height="wrap_content"
33 android:layout_alignParentRight="true"
34 android:layout_centerVertical="true"
35 android:gravity="center"
36 android:orientation="horizontal" >
37
38 <ImageView
39 android:layout_width="30dp"
40 android:layout_height="30dp"
41 android:src="@drawable/search" />
42
43 <ImageView
44 android:layout_width="30dp"
45 android:layout_height="30dp"
46 android:src="@drawable/add" />
47
48 <ImageView
49 android:layout_width="30dp"
50 android:layout_height="30dp"
51 android:src="@drawable/more" />
52 </LinearLayout>
53
54 </RelativeLayout>

top2.xml

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
2 android:layout_width="match_parent"
3 android:layout_height="40dp"
4 android:orientation="vertical" >
5
6 <LinearLayout
7 android:layout_width="match_parent"
8 android:layout_height="37dp"
9 android:gravity="center_vertical"
10 android:background="#cccccc"
11 >
12
13 <LinearLayout
14 android:layout_width="wrap_content"
15 android:layout_height="wrap_content"
16 android:layout_weight="1"
17 android:gravity="center" >
18
19 <TextView
20 android:id="@+id/tv1"
21 android:layout_width="wrap_content"
22 android:layout_height="wrap_content"
23 android:text="聊天"
24 android:textColor="#339900"/>
25 </LinearLayout>
26
27 <LinearLayout
28 android:layout_width="wrap_content"
29 android:layout_height="wrap_content"
30 android:layout_weight="1"
31 android:gravity="center" >
32
33 <TextView
34 android:id="@+id/tv2"
35 android:layout_width="wrap_content"
36 android:layout_height="wrap_content"
37 android:text="发现"
38 android:textColor="@android:color/black"/>
39 </LinearLayout>
40
41 <LinearLayout
42 android:layout_width="wrap_content"
43 android:layout_height="wrap_content"
44 android:layout_weight="1"
45 android:gravity="center" >
46
47 <TextView
48 android:id="@+id/tv3"
49 android:layout_width="wrap_content"
50 android:layout_height="wrap_content"
51 android:text="通讯录"
52 android:textColor="@android:color/black"/>
53 </LinearLayout>
54 </LinearLayout>
55
56 <LinearLayout
57 android:layout_width="match_parent"
58 android:layout_height="3dp" >
59
60 <ImageView
61 android:id="@+id/tabline"
62 android:layout_width="100dp"
63 android:layout_height="match_parent"
64 android:background="@drawable/tabline" />
65 </LinearLayout>
66
67 </LinearLayout>

mywx.xml(用include包含前2个布局文件,并设置垂直排列)

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
2 xmlns:tools="http://schemas.android.com/tools"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent"
5 android:orientation="vertical"
6 tools:context="com.example.weixin_test.MyWxTest" >
7
8 <include layout="@layout/top1" />
9
10 <include layout="@layout/top2" />
11
12
13 <android.support.v4.view.ViewPager
14 android:id="@+id/viewpager"
15 android:layout_width="match_parent"
16 android:layout_height="wrap_content"
17 android:layout_weight="1"
18 >
19
20
21 </android.support.v4.view.ViewPager>
22 </LinearLayout>

 Fragment1.xml(由于Flagment的布局文件只是简单采用字符标示,布局都一样,这里只给出第一个Fragment布局文件)

 1 <?xml version="1.0" encoding="utf-8"?>
2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent"
5 >
6
7 <TextView
8 android:layout_width="wrap_content"
9 android:layout_height="wrap_content"
10 android:text="我是第一个界面"
11 android:textSize="30dp"
12 android:layout_centerInParent="true"
13
14 />
15
16
17 </RelativeLayout>

接下来是JAVA代码了,注释很全(其实用法还是之前的ViewPager,只不过之前的ViewPager的数据源里存放的是view对象,而这里是Fragment)

  1 package com.example.weixin_test;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import android.graphics.Color;
7 import android.os.Bundle;
8 import android.support.v4.app.Fragment;
9 import android.support.v4.app.FragmentActivity;
10 import android.support.v4.app.FragmentPagerAdapter;
11 import android.support.v4.view.ViewPager;
12 import android.support.v4.view.ViewPager.OnPageChangeListener;
13 import android.util.DisplayMetrics;
14 import android.util.Log;
15 import android.view.Display;
16 import android.view.ViewGroup.LayoutParams;
17 import android.view.Window;
18 import android.widget.ImageView;
19 import android.widget.LinearLayout;
20 import android.widget.TextView;
21
22 public class MyWxTest extends FragmentActivity {
23
24 private ViewPager viewPager;// 声明一个viewpager对象
25 private TextView tv1;
26 private TextView tv2;
27 private TextView tv3;
28 private ImageView tabline;
29 private List<Fragment> list;// 声明一个list集合存放Fragment(数据源)
30
31 private int tabLineLength;// 1/3屏幕宽
32 private int currentPage = 0;// 初始化当前页为0(第一页)
33
34 @Override
35 protected void onCreate(Bundle savedInstanceState) {
36 super.onCreate(savedInstanceState);
37 requestWindowFeature(Window.FEATURE_NO_TITLE);
38 setContentView(R.layout.mywx);
39 // 初始化滑动条1/3
40 initTabLine();
41
42 // 初始化界面
43 initView();
44 }
45
46 private void initTabLine() {
47 // 获取显示屏信息
48 Display display = getWindow().getWindowManager().getDefaultDisplay();
49 // 得到显示屏宽度
50 DisplayMetrics metrics = new DisplayMetrics();
51 display.getMetrics(metrics);
52 // 1/3屏幕宽度
53 tabLineLength = metrics.widthPixels / 3;
54 // 获取控件实例
55 tabline = (ImageView) findViewById(R.id.tabline);
56 // 控件参数
57 LayoutParams lp = tabline.getLayoutParams();
58 lp.width = tabLineLength;
59 tabline.setLayoutParams(lp);
60 }
61
62 private void initView() {
63 // 实例化对象
64 viewPager = (ViewPager) findViewById(R.id.viewpager);
65 tv1 = (TextView) findViewById(R.id.tv1);
66 tv2 = (TextView) findViewById(R.id.tv2);
67 tv3 = (TextView) findViewById(R.id.tv3);
68 list = new ArrayList<Fragment>();
69
70 // 设置数据源
71 Fragment1 fragment1 = new Fragment1();
72 Fragment2 fragment2 = new Fragment2();
73 Fragment3 fragment3 = new Fragment3();
74
75 list.add(fragment1);
76 list.add(fragment2);
77 list.add(fragment3);
78
79 // 设置适配器
80 FragmentPagerAdapter adapter = new FragmentPagerAdapter(
81 getSupportFragmentManager()) {
82
83 @Override
84 public int getCount() {
85 return list.size();
86 }
87
88 @Override
89 public Fragment getItem(int arg0) {
90 return list.get(arg0);
91 }
92 };
93
94 // 绑定适配器
95 viewPager.setAdapter(adapter);
96
97 // 设置滑动监听
98 viewPager.setOnPageChangeListener(new OnPageChangeListener() {
99
100 @Override
101 public void onPageSelected(int position) {
102 // 当页面被选择时,先讲3个textview的字体颜色初始化成黑
103 tv1.setTextColor(Color.BLACK);
104 tv2.setTextColor(Color.BLACK);
105 tv3.setTextColor(Color.BLACK);
106
107 // 再改变当前选择页(position)对应的textview颜色
108 switch (position) {
109 case 0:
110 tv1.setTextColor(Color.rgb(51, 153, 0));
111 break;
112 case 1:
113 tv2.setTextColor(Color.rgb(51, 153, 0));
114 break;
115 case 2:
116 tv3.setTextColor(Color.rgb(51, 153, 0));
117 break;
118 }
119
120 currentPage = position;
121
122 }
123
124 @Override
125 public void onPageScrolled(int arg0, float arg1, int arg2) {
126 Log.i("tuzi", arg0 + "," + arg1 + "," + arg2);
127
128 // 取得该控件的实例
129 LinearLayout.LayoutParams ll = (android.widget.LinearLayout.LayoutParams) tabline
130 .getLayoutParams();
131
132 if (currentPage == 0 && arg0 == 0) { // 0->1移动(第一页到第二页)
133 ll.leftMargin = (int) (currentPage * tabLineLength + arg1
134 * tabLineLength);
135 } else if (currentPage == 1 && arg0 == 1) { // 1->2移动(第二页到第三页)
136 ll.leftMargin = (int) (currentPage * tabLineLength + arg1
137 * tabLineLength);
138 } else if (currentPage == 1 && arg0 == 0) { // 1->0移动(第二页到第一页)
139 ll.leftMargin = (int) (currentPage * tabLineLength - ((1 - arg1) * tabLineLength));
140 } else if (currentPage == 2 && arg0 == 1) { // 2->1移动(第三页到第二页)
141 ll.leftMargin = (int) (currentPage * tabLineLength - (1 - arg1)
142 * tabLineLength);
143 }
144
145 tabline.setLayoutParams(ll);
146
147 }
148
149 @Override
150 public void onPageScrollStateChanged(int arg0) {
151 // TODO Auto-generated method stub
152
153 }
154 });
155
156 }
157
158 }

对这个类做下说明:

1、这里的滑动屏幕下划线动态跟随的效果,其实实现方法有2种,原理是一样的

(1)可以使用ViewPager的两个子类ViewFlipper和ViewSwitche,这种方法比较简单,直接用就行。

(2)用原生代码实现,也就是动态的去控制下划线的左外边距。

这里我采用的是第2种方法,我觉得授人予鱼还不如授人予渔,其实也并不复杂,细节去理下细节就懂了。

这里需要注意一个地方,我们在给ViewPager设置监听器时,这边会复写一个onPageScrolled方法,里面有3个参数,我用Log打印出它们在页面滑动时的数据变化

这是页面一向页面二滑动时候的数据记录:

我们可以发现第一个参数值直接从0->1,第二个参数值从0.0依次增加到0.9xx无限靠近1,然后页面到达第二页它又恢复成了0,第三个参数从1开始累积到300+(这个我们不去关注)

这是页面二向页面三滑动时候的数据记录:

我们可以发现第一个参数值直接从1->2,第二个参数值从0.0依次增加到0.9xx无限靠近1,然后页面到达第二页它又恢复成了0,第三个参数从1开始累积到300+(这个我们不去关注)

因此我们可以发现一个规律:

当ViewPager页面值为0(第一页)且当参数一为0时,页面的状态时从  第一页到第二页

当ViewPager页面值为1(第二页)且当参数一为1时,页面的状态时从  第一页到第二页

以此类推,大家可以自己打印出来看看,对这些数据比较有感觉,由于文章篇幅问题,这里就不再贴图了。

我们可以利用第二个参数从0.0推荐递增到1,这个数据来控制左外边距(在第一页时左外边距为0,第二页时左外边距为1/3屏幕宽,第三页时左外边距为2/3屏幕宽)

由此推导出的公式为:

向左滑时:当前页数*屏幕1/3宽+onPageScrolled方法第二个参数*屏幕1/3宽

向右滑时:当前页数*屏幕1/3宽-(1-onPageScrolled方法第二个参数)*屏幕1/3宽

2、由于这里使用到了Fragment,这里就不再和以往一样继承Activity,这里需要继承Activity的子类FragmentActivity。

由于3个Fragment的代码几乎一致,所以这里只给出Fragment1.java

 1 package com.example.weixin_test;
2
3 import android.os.Bundle;
4 import android.support.annotation.Nullable;
5 import android.support.v4.app.Fragment;
6 import android.view.LayoutInflater;
7 import android.view.View;
8 import android.view.ViewGroup;
9
10 public class Fragment1 extends Fragment {
11 @Override
12 public View onCreateView(LayoutInflater inflater,
13 @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
14 return inflater.inflate(R.layout.fragment1, container, false);
15 }
16
17 }

来讲一下关于这个类的说明:

1、Fragment一般是作为Activity界面的一部分,它把Layout对象嵌入到了Activity之中,若要对一个Fragment提供Layout对象必须去调用一个onCreateView()方法,它的返回值是一个View对象,这个方法为我们提供了一个LayoutInflater便于我们把XML布局文件转换成View对象。

2、onCreateView()方法中:

container参数是用来存放Fragment的layout。

saveInstanceState参数是一个Bundle,跟Activity的onCreate()中Bundle差不多,用于状态恢复。

3、inflate()方法中有三个参数:

1:layout的资源id。

2:存放fragment的layout的ViewGroup。

3:这个布尔值是代表是否在创建Fragment的layout期间,把layout附加到container上,由于系统已经把layout对象存放在了ViewGroup中,所以这里为false。

作者:Balla_兔子
出处:http://www.cnblogs.com/lichenwei/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
正在看本人博客的这位童鞋,我看你气度不凡,谈吐间隐隐有王者之气,日后必有一番作为!旁边有“推荐”二字,你就顺手把它点了吧,相得准,我分文不收;相不准,你也好回来找我!

转-Fragment+ViewPager组件(高仿微信界面)的更多相关文章

  1. 安卓开发笔记——Fragment+ViewPager组件(高仿微信界面)

    什么是ViewPager? 关于ViewPager的介绍和使用,在之前我写过一篇相关的文章<安卓开发复习笔记——ViewPager组件(仿微信引导界面)>,不清楚的朋友可以看看,这里就不再 ...

  2. Android控件-Fragment+ViewPager(高仿微信界面)

    什么是Fragment? Fragment是Android3.0后新增的概念,Fragment名为碎片,不过却和Activity十分相似,具有自己的生命周期,它是用来描述一些行为或一部分用户界面在一个 ...

  3. 转-ViewPager组件(仿微信引导界面)

    http://www.cnblogs.com/lichenwei/p/3970053.html 这2天事情比较多,都没时间更新博客,趁周末,继续继续~ 今天来讲个比较新潮的组件——ViewPager ...

  4. 安卓开发笔记——ViewPager组件(仿微信引导界面)

    这2天事情比较多,都没时间更新博客,趁周末,继续继续~ 今天来讲个比较新潮的组件——ViewPager 什么是ViewPager? ViewPager是安卓3.0之后提供的新特性,继承自ViewGro ...

  5. Android ActionBar应用实战,高仿微信主界面的设计

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/26365683 经过前面两篇文章的学习,我想大家对ActionBar都已经有一个相对 ...

  6. Android 高仿微信6.0主界面 带你玩转切换图标变色

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/41087219,本文出自:[张鸿洋的博客] 1.概述 学习Android少不了模仿 ...

  7. Android仿微信界面

    效果图 原理介绍 1.先绘制一个颜色(例如:粉红) 2.设置Mode=DST_IN 3.绘制我们这个可爱的小机器人 回答我,显示什么,是不是显示交集,交集是什么?交集是我们的小机器人的非透明区域,也就 ...

  8. Android ActionBar仿微信界面

    ActionBar仿微信界面 1.学习了别人的两篇关于ActionBar博客,在结合别人的文章来仿造一下微信的界面: 思路如下:1).利用ActionBar生成界面的头部,在用ActionBar的Ac ...

  9. GSD_WeiXin(高仿微信)应用源码

    高仿微信计划:已经实现功能 1.微信首页(cell侧滑编辑.下拉眼睛动画.下拉拍短视频.点击进入聊天详情界面) 2.通讯录(联系人字母排序.搜索界面) 3.发现(朋友圈) 4.我(界面) 待实现功能( ...

随机推荐

  1. java的nio之:java的nio系列教程之FileChannel

    一:Java NIO的FileChannel===>Java NIO中的FileChannel是一个连接到文件的通道.可以通过文件通道读写文件. ===>FileChannel无法设置为非 ...

  2. Introduction to Monte Carlo Tree Search (蒙特卡罗搜索树简介)

    Introduction to Monte Carlo Tree Search (蒙特卡罗搜索树简介)  部分翻译自“Monte Carlo Tree Search and Its Applicati ...

  3. java .net compartion

    1, http://www-01.ibm.com/software/smb/na/J2EE_vs_NET_History_and_Comparison.pdf http://stackoverflow ...

  4. JSBinding + SharpKit / 实战:转换 2DPlatformer

    最后修改:2015年07月29日 2016年2月25日 2DPlatformer 是 Unity3D 的一个官方 Demo.本文将介绍使用 JSBinging + SharpKit 转换 2DPlat ...

  5. AWR分析。(shared_pool,sga_size大小设置)

    Execute to Parse 指标反映了执行解析比 其公式为 1-(parse/execute) , 目标为100% 及接近于只 执行而不解析 在oracle中解析往往是执行的先提工作,但是通过游 ...

  6. rac 11g_第二个节点重启后无法启动实例:磁盘组dismount问题

    原创作品,出自 "深蓝的blog" 博客,欢迎转载,转载时请务必注明以下出处,否则追究版权法律责任. 深蓝的blog:http://blog.csdn.net/huangyanlo ...

  7. C# waitformultipleobjects()

    class WatchThread { [DllImport("kernel32.dll")] private static extern int CreateEvent(IntP ...

  8. Git服务器搭建及SSH无密码登录设置

    在Git服务器中建立一个git帐号,用于多人使用. adduser git输入此命令后,会在/home/下建立一个git文件 /home/git 下建立.ssh目录(注意,是.ssh..有个点!) c ...

  9. Oracle监听启动失败问题

    1. C:\Users\10188535.ZTE>lsnrctl start LISTENER LSNRCTL for 32-bit Windows: Version 11.2.0.1.0 - ...

  10. Oracle序列使用:建立、删除

    转自:http://www.cnblogs.com/WangPB/archive/2010/07/13/1776766.html 在开始讲解Oracle序列使用方法之前,先加一点关于Oracle cl ...