Android 微信 底部tab 切换时是新的tabactivity切换界面 还是 fragment

首页-底部&顶部Tab导航(菜单栏)的实现:TabLayout+ViewPager+Fragment
Android开发中使用顶部 & 底部Tab导航栏的频次非常高,主要的实现手段有以下:
TabWidget 隐藏TabWidget,使用RadioGroup和RadioButton FragmentTabHost 5.0以后的TabLayout 最近推出的 Bottom navigation
在上一篇我介绍了如何使用(Fragment+FragmentTabHost++ViewPager)
今天我手把手教大家如何使用TabLayout+ViewPager+Fragment的组合来实现顶部和底部Tab导航栏,
1. 概念介绍
1.1 TabLayout
定义:实现Material Design效果的控件库(Android Design Support Library); 作用:用于实现点击选项进行切换选项卡的自定义效果(5.0可用)
1.2 ViewPager
定义:ViewPager是android扩展包v4包中的类 作用:左右切换当前的view,实现滑动切换的效果。
1.ViewPager类直接继承了ViewGroup类,和LinearLayout等布局一样,都是一个容器,需要在里面添加我们想要显示的内容。
2.ViewPager类需要PagerAdapter适配器类提供数据,与ListView类似 3.Google官方建议ViewPager配合Fragment使用
1.3 Fragment
定义:Fragment是activity的界面中的一部分或一种行为
1.把Fragment认为模块化的一段activity
2.它具有自己的生命周期,接收它自己的事件,并可以在activity运行时被添加或删除
3.Fragment不能独立存在,它必须嵌入到activity中,而且Fragment的生命周期直接受所在的activity的影响。例如:当activity暂停时,它拥有的所有的Fragment们都暂停了,当activity销毁时,它拥有的所有Fragment们都被销毁。
作用:支持更动态、更灵活的界面设计(从3.0开始引入)
2. 总体设计思路
TabLayout:点击切换选项卡 Fragment:存放不同选项的页面内容 ViewPager:实现页面的左右滑动效果
3. 实现步骤
利用(TabLayout+ViewPager+Fragment)实现顶部&底部Tab导航栏的步骤一共有6个:
步骤1:添加依赖 步骤2:创建需要的Fragment布局文件(需要多少个Tab选项,就建多少个Fragment) 步骤3:创建Fragment对应的Activity类 步骤4:定义适配器Adapter 步骤5:定义主布局activity_main.xml文件 步骤6:定义MainActivity类
4. Demo实战
4.1 效果图(丑是为了让大家更好地理解各个属性设置~~)
4.1 效果图(丑是为了让大家更好地理解各个属性设置~~)
4.3 工程目录
4.3 具体实现
接下来大家和我一步步去实现吧!!
强烈建议大家先去Carson_Ho的Github:去下载完整Demo,这样看效果会更好哦!
步骤1:在Gradle中添加依赖
//TabLayout
compile 'com.android.support:support-v4:23.4.0'
compile 'com.android.support:design:23.4.0'
//ViewPage
android.support.v4.view.ViewPager
步骤2:创建需要的Fragment布局文件(需要多少个Tab选项,就建多少个Fragment,这里以4个举例)
fragment1.xml(一共4个,这里只写出一个)
步骤3:创建Fragment对应的Activity类
Fragment1(一共4个,这里只写出一个)
package com.example.carson_ho.
import android.os.B
import android.support.annotation.N
import android.support.v4.app.F
import android.view.LayoutI
import android.view.V
import android.view.ViewG
* Created by Carson_Ho on 16/7/22.
public class Fragment1 extends Fragment {
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment1, container, false);
步骤4:定义适配器Adapter类
这里的适配的作用是将Fragment与ViewPager进行适配
MyFragmentPagerAdapter.java
package com.example.carson_ho.
import android.support.v4.app.F
import android.support.v4.app.FragmentM
import android.support.v4.app.FragmentPagerA
* Created by Carson_Ho on 16/7/22.
public class MyFragmentPagerAdapter extends FragmentPagerAdapter {
private String[] mTitles = new String[]{&首页&, &发现&, &进货单&,&我的&};
public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
public Fragment getItem(int position) {
if (position == 1) {
return new Fragment2();
} else if (position == 2) {
return new Fragment3();
}else if (position==3){
return new Fragment4();
return new Fragment1();
public int getCount() {
return mTitles.
//ViewPager与TabLayout绑定后,这里获取到PageTitle就是Tab的Text
public CharSequence getPageTitle(int position) {
return mTitles[position];
步骤5:定义主布局activity_main.xml
activity_main.xml
selected.xml
步骤6:定义MainActivity
MainActivity.Java
package com.example.carson_ho.
import android.os.B
import android.support.design.widget.TabL
import android.support.v4.view.ViewP
import android.support.v7.app.AppCompatA
public class MainActivity extends AppCompatActivity {
private TabLayout mTabL
private ViewPager mViewP
private MyFragmentPagerAdapter myFragmentPagerA
private TabLayout.T
private TabLayout.T
private TabLayout.T
private TabLayout.T
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().hide();//隐藏掉整个ActionBar
setContentView(R.layout.activity_main);
//初始化视图
initViews();
private void initViews() {
//使用适配器将ViewPager与Fragment绑定在一起
mViewPager= (ViewPager) findViewById(R.id.viewPager);
myFragmentPagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(myFragmentPagerAdapter);
//将TabLayout与ViewPager绑定在一起
mTabLayout = (TabLayout) findViewById(R.id.tabLayout);
mTabLayout.setupWithViewPager(mViewPager);
//指定Tab的位置
one = mTabLayout.getTabAt(0);
two = mTabLayout.getTabAt(1);
three = mTabLayout.getTabAt(2);
four = mTabLayout.getTabAt(3);
//设置Tab的图标,假如不需要则把下面的代码删去
one.setIcon(R.mipmap.ic_launcher);
two.setIcon(R.mipmap.ic_launcher);
three.setIcon(R.mipmap.ic_launcher);
four.setIcon(R.mipmap.ic_launcher);
4.4 效果图(丑是为了让大家更好地理解各个属性设置~~)4.5 底部Tab导航栏实现
实现了顶部Tab导航栏,该如何实现底部Tab导航栏实现呢?很简单!只需要在上面步骤5:定义主布局activity_main.xml中将TabLayout和ViewPager的位置交换就可以了!如下图:
步骤5:定义主布局activity_main.xml
activity_main.xml
5. 完整Demo下载地址
Carson_Ho的Github:
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'30323人阅读
android(31)
先看一下QQ、新浪微博、支付宝钱包这三个非常有名的应用,都有一个底部导航栏,我们一般称之‘选项卡’。google官方会叫他们为fixed
tab,不过国内好像很好这么叫的。其实,在anroid 4.x时代,google官方更希望应用的导航放在顶部,通过滑屏和点击标签来切换界面。但是随着ios的的跟风以及用户习惯的养成,这种设计风格的形成也就变成历史遗留问题。在这里我们不讨论哪一个风格好,哪一个风格不好。做为开发人员,我们可能更关注这种司空见惯的界面设计是怎么实现的呢?
在android 2.x时代,我们可能会地使用ActivityGroup来实现这种,但是随着jelly bean的市场份额超过50%,我们会发现有一种新的组建出现了,它叫Fragment()。而这种底部选项卡的风格界面的实现也由ActivityGroup转向了Fragment。先了,费话不多说了,下面我会一步一步教您怎么实现这个界面。在动手之前,我可能需要把我做好的样式图给你看一下,以遍让您有一个心里预期。
其实,我们这个界面的实现,基本没有什么java 代码。不信,你看下面就是主界面的代码:
public&class&MainActivity&extends&Activity&{&&&&&&private&FragmentManager&fragmentM&&&&&&private&RadioGroup&radioG&&&&&&&&@TargetApi(Build.VERSION_CODES.HONEYCOMB)&&&&&&@Override&&&&&&protected&void&onCreate(Bundle&savedInstanceState)&{&&&&&&&&&&super.onCreate(savedInstanceState);&&&&&&&&&&requestWindowFeature(Window.FEATURE_NO_TITLE);&&&&&&&&&&setContentView(R.layout.weibo_tab);&&&&&&&&&&&&fragmentManager&=&getFragmentManager();&&&&&&&&&&radioGroup&=&(RadioGroup)&findViewById(R.id.rg_tab);&&&&&&&&&&radioGroup.setOnCheckedChangeListener(new&RadioGroup.OnCheckedChangeListener()&{&&&&&&&&&&&&&&@Override&&&&&&&&&&&&&&public&void&onCheckedChanged(RadioGroup&group,&int&checkedId)&{&&&&&&&&&&&&&&&&&&FragmentTransaction&transaction&=&fragmentManager.beginTransaction();&&&&&&&&&&&&&&&&&&Fragment&fragment&=&FragmentFactory.getInstanceByIndex(checkedId);&&&&&&&&&&&&&&&&&&transaction.replace(R.id.content,&fragment);&&&&&&&&&&&&&&&&&&mit();&&&&&&&&&&&&&&}&&&&&&&&&&});&&&&&&}&&&&}&&
所以哦,亲们,我们把重点放在xml界面的编写上咯。
1.我们可能需要一背景图片像这样的:
2.我们要准备这五个选项卡图片。包括正常和被按下两种状态。所以共十张图片。
3.你要为这五个按钮分别编写selector,文件名为weibolist_attention_selector.xml
&version=&1.0&&encoding=&utf-8&&&&xmlns:android=&/apk/res/android&&&&&&&&android:drawable=&@drawable/weibo_listab_attention_on&&android:state_pressed=&true&&&&&&&&&android:drawable=&@drawable/weibo_listab_attention_on&&android:state_checked=&true&&&&&&&&&android:drawable=&@drawable/weibo_listab_attention_off&&&&&&
这个xml文件挺简单的啊,但是细心的同学可能会地现,你这里为什么要用android:state_checked的啊?为什么不是其他的,比如android:state_selected哦
我想说,其实我这个底部用的是RadioGroup,我怎么判断当前选中的是哪个呢,不选中的是哪个呢。这里最好的选择就是使用RadioGroup,它的最大好处就是彼此的RadioButton具有互斥性,这样就费掉用java代码判断和处理的麻烦了。
4.下面,就要考虑为整个界面布局了。文件名为activity.xml
&version=&1.0&&encoding=&utf-8&&&&&&&&&&&android:layout_width=&match_parent&&&&&&&android:layout_height=&match_parent&&&&&&&android:orientation=&vertical&&&&&&&xmlns:android=&/apk/res/android&&&&&&&&&&&&&&&&&&&&&android:id=&@+id/content&&&&&&&&&&&android:layout_width=&match_parent&&&&&&&&&&&android:layout_height=&match_parent&&&&&&&&&&&android:layout_weight=&1&&&&&&&&&&&&&&&&&&&&android:id=&@+id/rg_tab&&&&&&&&&&&android:orientation=&horizontal&&&&&&&&&&&android:layout_width=&match_parent&&&&&&&&&&&android:layout_height=&wrap_content&&&&&&&&&&&android:background=&@drawable/bg_weibo_listab&&&&&&&&&&&&&&&&&&&&&&&&&&&style=&@style/weibo_tab&&&&&&&&&&&&&&&android:drawableTop=&@drawable/weibolist_attention_selector&&&&&&&&&&&&&&&android:text=&微博&&&&&&&&&&&&&&&&&&&&&&&&&&&&style=&@style/weibo_tab&&&&&&&&&&&&&&&android:drawableTop=&@drawable/weibolist_atme_selector&&&&&&&&&&&&&&&android:text=&\@我&&&&&&&&&&&&&&&&&&&&&&&&&&&&style=&@style/weibo_tab&&&&&&&&&&&&&&&android:drawableTop=&@drawable/weibolist_comment_selector&&&&&&&&&&&&&&&android:text=&评论&&&&&&&&&&&&&&&&&&&&&&&&&&&&style=&@style/weibo_tab&&&&&&&&&&&&&&&android:drawableTop=&@drawable/weibolist_mylist_selector&&&&&&&&&&&&&&&android:text=&我的&&&&&&&&&&&&&&&&&&&&&&&&&&&&style=&@style/weibo_tab&&&&&&&&&&&&&&&android:drawableTop=&@drawable/weibolist_global_selector&&&&&&&&&&&&&&&android:text=&全站&&&&&&&&&&&&
这里可能就有几个问题啦
(1) FrameLayout是干什么的,可能用别的父控件吗?
& & &这个是一个预留的内容控件,以后会用它去呈现Fragment的内容。理论上是可以用别的父控件的,没试过。
(2)android:weight=1,怎么只有一个呢,这样做有对LinearLayout有意义吗?
& & &首先对FragLayout一定要写,不写就会变成这样。但是第二个RadioGroup的weight一定不要写,不然会很难调的。这个我猜测应该会有一个很好weight缺省值自适应的。
& & &我只是猜测啦,具体原因求解释。
(3)weibo_tab样式里面什么内容?
& & 什么内容,如下就可以啦:
&name=&weibo_tab&&&&&&&&name=&android:layout_height&wrap_content&&&&&&&name=&android:layout_width&match_parent&&&&&&&name=&android:layout_weight&1&&&&&&&name=&android:gravity&center&&&&&&&name=&android:textSize&14sp&&&&&&&name=&android:paddingTop&8dip&&&&&&&name=&android:paddingBottom&4dip&&&&&&&name=&android:background&@drawable/weibolist_bottombar_itembg_selector&&&&&&&name=&android:textColor&@color/weibolist_bottombar_textcolor_selector&&&&&&&name=&android:button&@null&&&&
& & 这个style的目地是为了把button相同的设置提取出来,进行很好地重构。
& & 这里可能要解释几个属性weight,其实RadioGroup是继承LinearLayout,设置weight的目的就是把这个底部视图五等分。
& & textColor,这是为是控制底部颜色变化的。button,这个一定要设置,否则就会这样
& &做到这里,我建议你就跑起来,试试效果。虽然没有用到Fragment,但是底部选项已经可以任意切换啦。
& &你是不是已经把它很好的搞定了呢,先恭喜你咯。
5.下一步我来内容填充的界面视图,文件名为fragment.xml
&version=&1.0&&encoding=&utf-8&&&&xmlns:android=&/apk/res/android&&&&&&&android:layout_width=&match_parent&&&&&&&android:layout_height=&match_parent&&&&&&&&&&&&&&&&&&&android:id=&@+id/txt_content&&&&&&&&&&&android:layout_width=&match_parent&&&&&&&&&&&android:layout_height=&match_parent&&&&&&&&&&&android:gravity=&center&&&&&&&&&&&android:padding=&10dp&&&&&&&&&&&android:text=&&&&&&&&&&&&android:textSize=&20sp&&&&&&
这个没有什么解释的,略过。
6.下面我们做五个Fragment内容的呈现,如下:
先有一个BaseFragment抽象类,以被具体的子类继承和实现。
public&abstract&class&BaseFragment&extends&Fragment&{&&&&&&@Override&&&&&&public&View&onCreateView(LayoutInflater&inflater,&ViewGroup&container,&Bundle&savedInstanceState)&{&&&&&&&&&&View&view&=&inflater.inflate(R.layout.fragment,&null);&&&&&&&&&&TextView&textView&=&(TextView)&view.findViewById(R.id.txt_content);&&&&&&&&&&textView.setText(initContent());&&&&&&&&&&return&&&&&&&}&&&&&&&&public&abstract&String&initContent();&&}&&
(1)关注界面
public&class&AttentionFragment&extends&BaseFragment&{&&&&&&@Override&&&&&&public&String&initContent()&{&&&&&&&&&&return&&这是关注我界面&;&&&&&&}&&}&&
public&class&AtmeFragment&extends&BaseFragment&{&&&&&&&&@Override&&&&&&public&String&initContent()&{&&&&&&&&&&return&&这是@我界面&;&&&&&&}&&}&&
(3)评论界面
public&class&CommentFragment&extends&BaseFragment&{&&&&&&@Override&&&&&&public&String&initContent()&{&&&&&&&&&&return&&这是评论我界面&;&&&&&&}&&}&&
(4)我的界面
public&class&MyListFragment&extends&BaseFragment&{&&&&&&@Override&&&&&&public&String&initContent()&{&&&&&&&&&&return&&这是我的列表界面&;&&&&&&}&&}&&
(5)全部界面
public&class&GlobalFragment&extends&BaseFragment&{&&&&&&@Override&&&&&&public&String&initContent()&{&&&&&&&&&&return&&这是全站界面&;&&&&&&}&&}&&
7.我们还需要一个工厂模式,来实现根据下标的位置返回相应的Fragment。像这样
public&class&FragmentFactory&{&&&&&&public&static&Fragment&getInstanceByIndex(int&index)&{&&&&&&&&&&Fragment&fragment&=&null;&&&&&&&&&&switch&(index)&{&&&&&&&&&&&&&&case&1:&&&&&&&&&&&&&&&&&&fragment&=&new&AttentionFragment();&&&&&&&&&&&&&&&&&&break;&&&&&&&&&&&&&&case&2:&&&&&&&&&&&&&&&&&&fragment&=&new&AtmeFragment();&&&&&&&&&&&&&&&&&&break;&&&&&&&&&&&&&&case&3:&&&&&&&&&&&&&&&&&&fragment&=&new&CommentFragment();&&&&&&&&&&&&&&&&&&break;&&&&&&&&&&&&&&case&4:&&&&&&&&&&&&&&&&&&fragment&=&new&MyListFragment();&&&&&&&&&&&&&&&&&&break;&&&&&&&&&&&&&&case&5:&&&&&&&&&&&&&&&&&&fragment&=&new&GlobalFragment();&&&&&&&&&&&&&&&&&&break;&&&&&&&&&&}&&&&&&&&&&return&&&&&&&}&&}&&
8.好了,万事具备只欠东风啦。请回到我们刚开始放出去那段代码,那你就已经完成它了。
9.哦,我们还是放上配置文件,贡大家参考。
&manifest&xmlns:android=&/apk/res/android&&&&&&&package=&com.mydream.fragment&&&&&&&android:versionCode=&1&&&&&&&android:versionName=&1.0&&&&&&&&&&&uses-sdk&&&&&&&&&&android:minSdkVersion=&14&&&&&&&&&&&android:targetSdkVersion=&19&&/&&&&&&&&&&application&&&&&&&&&&android:allowBackup=&true&&&&&&&&&&&android:label=&@string/app_name&&&&&&&&&&&android:icon=&@drawable/ic_launcher&&&&&&&&&&&&&activity&&&&&&&&&&&&&&android:name=&.MainActivity&&&&&&&&&&&&&&&android:label=&@string/app_name&&&&&&&&&&&&&&&&&intent-filter&&&&&&&&&&&&&&&&&&&&action&android:name=&android.intent.action.MAIN&&/&&&&&&&&&&&&&&&&&&&&&&category&android:name=&android.intent.category.LAUNCHER&&/&&&&&&&&&&&&&&&&/intent-filter&&&&&&&&&&&&/activity&&&&&&&&/application&&&&&&/manifest&&&
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:377036次
积分:4993
积分:4993
排名:第3794名
原创:152篇
转载:81篇
评论:85条
(1)(5)(1)(4)(3)(11)(6)(2)(1)(5)(3)(5)(6)(10)(12)(11)(5)(1)(13)(2)(8)(2)(1)(16)(13)(4)(2)(1)(11)(3)(3)(10)(5)(5)(1)(16)(13)(11)Android 微信 底部tab 切换时是新的activity 还是 fragment_百度知道
Android 微信 底部tab 切换时是新的activity 还是 fragment
提问者采纳
 言归正传,上边添加一个FrameLayout什么的,Android 版看起来应该是 fragment实现的,是Fragment,用FragmentTransation的add()或者Replace() 首页应该是 viewpager+fragment 的框架实现
来自团队:
其他类似问题
为您推荐:
其他1条回答
是Fragment,上边添加一个FrameLayout什么的,用FragmentTransation的add()或者Replace()
android的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁安卓开发复习笔记――Fragment+ViewPager组件(高仿微信界面)
么是ViewPager?
  关于ViewPager的介绍和使用,在之前我写过一篇相关的文章《安卓开发复习笔记&&ViewPager组件(仿微信引导界面)》,不清楚的朋友可以看看,这里就不再重复。
什么是Fragment?
& &Fragment是3.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布局文件,我把每一部分都分开写了:
&1 &RelativeLayout xmlns:android=&/apk/res/android&
&2 & & xmlns:tools=&/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& &
&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& &
16 & & & & &ImageView
17 & & & & & & android:layout_width=&30dp&
18 & & & & & & android:layout_height=&30dp&
19 & & & & & & android:src=&@drawable/weixin& /&
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&
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& &
38 & & & & &ImageView
39 & & & & & & android:layout_width=&30dp&
40 & & & & & & android:layout_height=&30dp&
41 & & & & & & android:src=&@drawable/search& /&
43 & & & & &ImageView
44 & & & & & & android:layout_width=&30dp&
45 & & & & & & android:layout_height=&30dp&
46 & & & & & & android:src=&@drawable/add& /&
48 & & & & &ImageView
49 & & & & & & android:layout_width=&30dp&
50 & & & & & & android:layout_height=&30dp&
51 & & & & & & android:src=&@drawable/more& /&
52 & & &/LinearLayout&
54 &/RelativeLayout&
&1 &LinearLayout xmlns:android=&/apk/res/android&
&2 & & android:layout_width=&match_parent&
&3 & & android:layout_height=&40dp&
&4 & & android:orientation=&vertical& &
&6 & & &LinearLayout
&7 & & & & android:layout_width=&match_parent&
&8 & & & & android:layout_height=&37dp&&
&9 & & & & android:gravity=&center_vertical&
10 & & & & android:background=&#cccccc&
11 & & & & &
13 & & & & &LinearLayout
14 & & & & & & android:layout_width=&wrap_content&
15 & & & & & & android:layout_height=&wrap_content&
16 & & & & & & android:layout_weight=&1&
17 & & & & & & android:gravity=&center& &
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&
27 & & & & &LinearLayout
28 & & & & & & android:layout_width=&wrap_content&
29 & & & & & & android:layout_height=&wrap_content&
30 & & & & & & android:layout_weight=&1&
31 & & & & & & android:gravity=&center& &
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&
41 & & & & &LinearLayout
42 & & & & & & android:layout_width=&wrap_content&
43 & & & & & & android:layout_height=&wrap_content&
44 & & & & & & android:layout_weight=&1&
45 & & & & & & android:gravity=&center& &
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&
56 & & &LinearLayout
57 & & & & android:layout_width=&match_parent&
58 & & & & android:layout_height=&3dp& &
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&
67 &/LinearLayout&
mywx.xml(用include包含前2个布局文件,并设置垂直排列)
&1 &LinearLayout xmlns:android=&/apk/res/android&
&2 & & xmlns:tools=&/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& &
&8 & & &include layout=&@layout/top1& /&
10 & & &include layout=&@layout/top2& /&
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&
21 &&/android.support.v4.view.ViewPager&
22 &/LinearLayout&
&Fragment1.xml(由于Flagment的布局文件只是简单采用字符标示,布局都一样,这里只给出第一个Fragment布局文件)
&1 &?xml version=&1.0& encoding=&utf-8&?&
&2 &RelativeLayout xmlns:android=&/apk/res/android&
&3 & & android:layout_width=&match_parent&
&4 & & android:layout_height=&match_parent&
&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 & & & & /&
17 &/RelativeLayout&
接下来是JAVA代码了,注释很全(其实用法还是之前的ViewPager,只不过之前的ViewPager的数据源里存放的是view对象,而这里是Fragment)
& 1 package com.example.weixin_
& 3 import java.util.ArrayL
& 4 import java.util.L
& 6 import android.graphics.C
& 7 import android.os.B
& 8 import android.support.v4.app.F
& 9 import android.support.v4.app.FragmentA
&10 import android.support.v4.app.FragmentPagerA
&11 import android.support.v4.view.ViewP
&12 import android.support.v4.view.ViewPager.OnPageChangeL
&13 import android.util.DisplayM
&14 import android.util.L
&15 import android.view.D
&16 import android.view.ViewGroup.LayoutP
&17 import android.view.W
&18 import android.widget.ImageV
&19 import android.widget.LinearL
&20 import android.widget.TextV
&22 public class MyWxTest extends FragmentActivity {
&24 & & private ViewPager viewP// 声明一个viewpager对象
&25 & & private TextView tv1;
&26 & & private TextView tv2;
&27 & & private TextView tv3;
&28 & & private ImageV
&29 & & private List&Fragment&// 声明一个list集合存放Fragment(数据源)
&31 & & private int tabLineL// 1/3屏幕宽
&32 & & private int currentPage = 0;// 初始化当前页为0(第一页)
&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();
&42 & & & & // 初始化界面
&43 & & & & initView();
&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 = tabLineL
&59 & & & & tabline.setLayoutParams(lp);
&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&();
&70 & & & & // 设置数据源
&71 & & & & Fragment1 fragment1 = new Fragment1();
&72 & & & & Fragment2 fragment2 = new Fragment2();
&73 & & & & Fragment3 fragment3 = new Fragment3();
&75 & & & & list.add(fragment1);
&76 & & & & list.add(fragment2);
&77 & & & & list.add(fragment3);
&79 & & & & // 设置适配器
&80 & & & & FragmentPagerAdapter adapter = new FragmentPagerAdapter(
&81 & & & & & & & & getSupportFragmentManager()) {
&83 & & & & & & @Override
&84 & & & & & & public int getCount() {
&85 & & & & & & & & return list.size();
&86 & & & & & & }
&88 & & & & & & @Override
&89 & & & & & & public Fragment getItem(int arg0) {
&90 & & & & & & & & return list.get(arg0);
&91 & & & & & & }
&92 & & & & };
&94 & & & & // 绑定适配器
&95 & & & & viewPager.setAdapter(adapter);
&97 & & & & // 设置滑动监听
&98 & & & & viewPager.setOnPageChangeListener(new OnPageChangeListener() {
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);
107 & & & & & & & & // 再改变当前选择页(position)对应的textview颜色
108 & & & & & & & & switch (position) {
109 & & & & & & & & case 0:
110 & & & & & & & & & & tv1.setTextColor(Color.rgb(51, 153, 0));
111 & & & & & & & & & &
112 & & & & & & & & case 1:
113 & & & & & & & & & & tv2.setTextColor(Color.rgb(51, 153, 0));
114 & & & & & & & & & &
115 & & & & & & & & case 2:
116 & & & & & & & & & & tv3.setTextColor(Color.rgb(51, 153, 0));
117 & & & & & & & & & &
118 & & & & & & & & }
120 & & & & & & & & currentPage =
122 & & & & & & }
124 & & & & & & @Override
125 & & & & & & public void onPageScrolled(int arg0, float arg1, int arg2) {
126 & & & & & & & & Log.i(&tuzi&, arg0 + &,& + arg1 + &,& + arg2);
128 & & & & & & & & // 取得该控件的实例
129 & & & & & & & & LinearLayout.LayoutParams ll = (android.widget.LinearLayout.LayoutParams) tabline
130 & & & & & & & & & & & & .getLayoutParams();
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 & & & & & & & & }
145 & & & & & & & & tabline.setLayoutParams(ll);
147 & & & & & & }
149 & & & & & & @Override
150 & & & & & & public void onPageScrollStateChanged(int arg0) {
151 & & & & & & & & // TODO Auto-generated method stub
153 & & & & & & }
154 & & & & });
对这个类做下说明:
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_
&3 import android.os.B
&4 import android.support.annotation.N
&5 import android.support.v4.app.F
&6 import android.view.LayoutI
&7 import android.view.V
&8 import android.view.ViewG
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);
&来讲一下关于这个类的说明:
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。
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'}

我要回帖

更多关于 activity切换fragment 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信