Android实现Tab布局的4种方式(Fragment+TabPageIndicator+ViewPager)
作者:鸿洋_ 发布时间:2023-02-26 10:45:41
Android现在实现Tab类型的界面方式越来越多,今天就把常见的实现方式给大家来个总结。目前写了:
1、传统的ViewPager实现
2、FragmentManager+Fragment实现
3、ViewPager+FragmentPagerAdapter实现
4、TabPageIndicator+ViewPager+FragmentPagerAdapter
1、传统的ViewPager实现
主要就是ViewPager+ViewAdapter这个还是比较常见的,就不多说了
效果图:
代码:
package com.example.mainframework02;
import javautilArrayList;
import javautilList;
import androidappActivity;
import androidosBundle;
import androidsupportvviewPagerAdapter;
import androidsupportvviewViewPager;
import androidsupportvviewViewPagerOnPageChangeListener;
import androidviewLayoutInflater;
import androidviewView;
import androidviewViewGroup;
import androidwidgetImageButton;
import androidwidgetImageView;
import androidwidgetLinearLayout;
public class TraditionalViewPagerAcvitity extends Activity
{
/**
* ViewPager
*/
private ViewPager mViewPager;
/**
* ViewPager的适配器
*/
private PagerAdapter mAdapter;
private List<View> mViews;
private LayoutInflater mInflater;
private int currentIndex;
/**
* 底部四个按钮
*/
private LinearLayout mTabBtnWeixin;
private LinearLayout mTabBtnFrd;
private LinearLayout mTabBtnAddress;
private LinearLayout mTabBtnSettings;
@Override
protected void onCreate(Bundle savedInstanceState)
{
superonCreate(savedInstanceState);
setContentView(Rlayoutactivity_main);
mInflater = LayoutInflaterfrom(this);
mViewPager = (ViewPager) findViewById(Ridid_viewpager);
/**
* 初始化View
*/
initView();
mViewPagersetAdapter(mAdapter);
mViewPagersetOnPageChangeListener(new OnPageChangeListener()
{
@Override
public void onPageSelected(int position)
{
resetTabBtn();
switch (position)
{
case 0:
((ImageButton) mTabBtnWeixinfindViewById(Ridbtn_tab_bottom_weixin))
setImageResource(Rdrawabletab_weixin_pressed);
break;
case 1:
((ImageButton) mTabBtnFrdfindViewById(Ridbtn_tab_bottom_friend))
setImageResource(Rdrawabletab_find_frd_pressed);
break;
case 2:
((ImageButton) mTabBtnAddressfindViewById(Ridbtn_tab_bottom_contact))
setImageResource(Rdrawabletab_address_pressed);
break;
case 3:
((ImageButton) mTabBtnSettingsfindViewById(Ridbtn_tab_bottom_setting))
setImageResource(Rdrawabletab_settings_pressed);
break;
}
currentIndex = position;
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2)
{
}
@Override
public void onPageScrollStateChanged(int arg0)
{
}
});
}
protected void resetTabBtn()
{
((ImageButton) mTabBtnWeixinfindViewById(Ridbtn_tab_bottom_weixin))
setImageResource(Rdrawabletab_weixin_normal);
((ImageButton) mTabBtnFrdfindViewById(Ridbtn_tab_bottom_friend))
setImageResource(Rdrawabletab_find_frd_normal);
((ImageButton) mTabBtnAddressfindViewById(Ridbtn_tab_bottom_contact))
setImageResource(Rdrawabletab_address_normal);
((ImageButton) mTabBtnSettingsfindViewById(Ridbtn_tab_bottom_setting))
setImageResource(Rdrawabletab_settings_normal);
}
private void initView()
{
mTabBtnWeixin = (LinearLayout) findViewById(Ridid_tab_bottom_weixin);
mTabBtnFrd = (LinearLayout) findViewById(Ridid_tab_bottom_friend);
mTabBtnAddress = (LinearLayout) findViewById(Ridid_tab_bottom_contact);
mTabBtnSettings = (LinearLayout) findViewById(Ridid_tab_bottom_setting);
mViews = new ArrayList<View>();
View first = mInflaterinflate(Rlayoutmain_tab_01, null);
View second = mInflaterinflate(Rlayoutmain_tab_02, null);
View third = mInflaterinflate(Rlayoutmain_tab_03, null);
View fourth = mInflaterinflate(Rlayoutmain_tab_04, null);
mViewsadd(first);
mViewsadd(second);
mViewsadd(third);
mViewsadd(fourth);
mAdapter = new PagerAdapter()
{
@Override
public void destroyItem(ViewGroup container, int position, Object object)
{
containerremoveView(mViewsget(position));
}
@Override
public Object instantiateItem(ViewGroup container, int position)
{
View view = mViewsget(position);
containeraddView(view);
return view;
}
@Override
public boolean isViewFromObject(View arg0, Object arg1)
{
return arg0 == arg1;
}
@Override
public int getCount()
{
return mViewssize();
}
};
}
}
评价:所有的代码都集中在一个Activity中,显得代码比较乱。
2、FragmentManager+Fragment实现
主要利用了Fragment在主内容界面对Fragment的add,hide等事务操作。
代码:
主Activity
package com.example.mainframework02.fragment;
import androidannotationSuppressLint;
import androidappActivity;
import androidappFragmentManager;
import androidappFragmentTransaction;
import androidosBundle;
import androidviewView;
import androidviewViewOnClickListener;
import androidwidgetImageButton;
import androidwidgetLinearLayout;
import comexamplemainframeworkR;
public class FragmentMainActivity extends Activity implements OnClickListener
{
private MainTab02 mTab02;
private MainTab01 mTab01;
private MainTab03 mTab03;
private MainTab04 mTab04;
/**
* 底部四个按钮
*/
private LinearLayout mTabBtnWeixin;
private LinearLayout mTabBtnFrd;
private LinearLayout mTabBtnAddress;
private LinearLayout mTabBtnSettings;
/**
* 用于对Fragment进行管理
*/
private FragmentManager fragmentManager;
@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState)
{
superonCreate(savedInstanceState);
setContentView(Rlayoutfragment_main);
initViews();
fragmentManager = getFragmentManager();
setTabSelection(0);
}
private void initViews()
{
mTabBtnWeixin = (LinearLayout) findViewById(Ridid_tab_bottom_weixin);
mTabBtnFrd = (LinearLayout) findViewById(Ridid_tab_bottom_friend);
mTabBtnAddress = (LinearLayout) findViewById(Ridid_tab_bottom_contact);
mTabBtnSettings = (LinearLayout) findViewById(Ridid_tab_bottom_setting);
mTabBtnWeixinsetOnClickListener(this);
mTabBtnFrdsetOnClickListener(this);
mTabBtnAddresssetOnClickListener(this);
mTabBtnSettingssetOnClickListener(this);
}
@Override
public void onClick(View v)
{
switch (vgetId())
{
case Ridid_tab_bottom_weixin:
setTabSelection(0);
break;
case Ridid_tab_bottom_friend:
setTabSelection(1);
break;
case Ridid_tab_bottom_contact:
setTabSelection(2);
break;
case Ridid_tab_bottom_setting:
setTabSelection(3);
break;
default:
break;
}
}
/**
* 根据传入的index参数来设置选中的tab页。
*
*/
@SuppressLint("NewApi")
private void setTabSelection(int index)
{
// 重置按钮
resetBtn();
// 开启一个Fragment事务
FragmentTransaction transaction = fragmentManagerbeginTransaction();
// 先隐藏掉所有的Fragment,以防止有多个Fragment显示在界面上的情况
hideFragments(transaction);
switch (index)
{
case 0:
// 当点击了消息tab时,改变控件的图片和文字颜色
((ImageButton) mTabBtnWeixinfindViewById(Ridbtn_tab_bottom_weixin))
setImageResource(Rdrawabletab_weixin_pressed);
if (mTab01 == null)
{
// 如果MessageFragment为空,则创建一个并添加到界面上
mTab01 = new MainTab01();
transactionadd(Ridid_content, mTab01);
} else
{
// 如果MessageFragment不为空,则直接将它显示出来
transactionshow(mTab01);
}
break;
case 1:
// 当点击了消息tab时,改变控件的图片和文字颜色
((ImageButton) mTabBtnFrdfindViewById(Ridbtn_tab_bottom_friend))
setImageResource(Rdrawabletab_find_frd_pressed);
if (mTab02 == null)
{
// 如果MessageFragment为空,则创建一个并添加到界面上
mTab02 = new MainTab02();
transactionadd(Ridid_content, mTab02);
} else
{
// 如果MessageFragment不为空,则直接将它显示出来
transactionshow(mTab02);
}
break;
case 2:
// 当点击了动态tab时,改变控件的图片和文字颜色
((ImageButton) mTabBtnAddressfindViewById(Ridbtn_tab_bottom_contact))
setImageResource(Rdrawabletab_address_pressed);
if (mTab03 == null)
{
// 如果NewsFragment为空,则创建一个并添加到界面上
mTab03 = new MainTab03();
transactionadd(Ridid_content, mTab03);
} else
{
// 如果NewsFragment不为空,则直接将它显示出来
transactionshow(mTab03);
}
break;
case 3:
// 当点击了设置tab时,改变控件的图片和文字颜色
((ImageButton) mTabBtnSettingsfindViewById(Ridbtn_tab_bottom_setting))
setImageResource(Rdrawabletab_settings_pressed);
if (mTab04 == null)
{
// 如果SettingFragment为空,则创建一个并添加到界面上
mTab04 = new MainTab04();
transactionadd(Ridid_content, mTab04);
} else
{
// 如果SettingFragment不为空,则直接将它显示出来
transactionshow(mTab04);
}
break;
}
transactioncommit();
}
/**
* 清除掉所有的选中状态。
*/
private void resetBtn()
{
((ImageButton) mTabBtnWeixinfindViewById(Ridbtn_tab_bottom_weixin))
setImageResource(Rdrawabletab_weixin_normal);
((ImageButton) mTabBtnFrdfindViewById(Ridbtn_tab_bottom_friend))
setImageResource(Rdrawabletab_find_frd_normal);
((ImageButton) mTabBtnAddressfindViewById(Ridbtn_tab_bottom_contact))
setImageResource(Rdrawabletab_address_normal);
((ImageButton) mTabBtnSettingsfindViewById(Ridbtn_tab_bottom_setting))
setImageResource(Rdrawabletab_settings_normal);
}
/**
* 将所有的Fragment都置为隐藏状态。
*
* @param transaction
* 用于对Fragment执行操作的事务
*/
@SuppressLint("NewApi")
private void hideFragments(FragmentTransaction transaction)
{
if (mTab01 != null)
{
transactionhide(mTab01);
}
if (mTab02 != null)
{
transactionhide(mTab02);
}
if (mTab03 != null)
{
transactionhide(mTab03);
}
if (mTab04 != null)
{
transactionhide(mTab04);
}
}
}
各个TabFragment,一共四个TabFragment,下面贴出两个,基本都一样。
package com.example.mainframework02.fragment;
import androidannotationSuppressLint;
import androidappFragment;
import androidosBundle;
import androidviewLayoutInflater;
import androidviewView;
import androidviewViewGroup;
@SuppressLint("NewApi")
public class MainTab01 extends Fragment
{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflaterinflate(comexamplemainframeworkRlayoutmain_tab_01, container, false);
}
}
package com.example.mainframework02.fragment;
import androidannotationSuppressLint;
import androidappFragment;
import androidosBundle;
import androidviewLayoutInflater;
import androidviewView;
import androidviewViewGroup;
import comexamplemainframeworkR;
@SuppressLint("NewApi")
public class MainTab02 extends Fragment
{
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflaterinflate(Rlayoutmain_tab_02, container, false);
}
}
评价:每个Fragment中的控件的处理,都是独立到各自的类中,相对来说主Activity简化了不少,可惜没有左右滑动的效果了。
3、ViewPager+Fragment实现
主要通过ViewPager和FragmentPagerAdapter一起来实现。
效果图:
代码:
主Activity
package com.example.mainframework03;
import javautilArrayList;
import javautilList;
import androidosBundle;
import androidsupportvappFragment;
import androidsupportvappFragmentActivity;
import androidsupportvappFragmentPagerAdapter;
import androidsupportvviewViewPager;
import androidsupportvviewViewPagerOnPageChangeListener;
import androidwidgetImageButton;
import androidwidgetLinearLayout;
public class MainActivity extends FragmentActivity
{
private ViewPager mViewPager;
private FragmentPagerAdapter mAdapter;
private List<Fragment> mFragments = new ArrayList<Fragment>();
/**
* 底部四个按钮
*/
private LinearLayout mTabBtnWeixin;
private LinearLayout mTabBtnFrd;
private LinearLayout mTabBtnAddress;
private LinearLayout mTabBtnSettings;
@Override
protected void onCreate(Bundle savedInstanceState)
{
superonCreate(savedInstanceState);
setContentView(Rlayoutactivity_main);
mViewPager = (ViewPager) findViewById(Ridid_viewpager);
initView();
mAdapter = new FragmentPagerAdapter(getSupportFragmentManager())
{
@Override
public int getCount()
{
return mFragmentssize();
}
@Override
public Fragment getItem(int arg0)
{
return mFragmentsget(arg0);
}
};
mViewPagersetAdapter(mAdapter);
mViewPagersetOnPageChangeListener(new OnPageChangeListener()
{
private int currentIndex;
@Override
public void onPageSelected(int position)
{
resetTabBtn();
switch (position)
{
case 0:
((ImageButton) mTabBtnWeixinfindViewById(Ridbtn_tab_bottom_weixin))
setImageResource(Rdrawabletab_weixin_pressed);
break;
case 1:
((ImageButton) mTabBtnFrdfindViewById(Ridbtn_tab_bottom_friend))
setImageResource(Rdrawabletab_find_frd_pressed);
break;
case 2:
((ImageButton) mTabBtnAddressfindViewById(Ridbtn_tab_bottom_contact))
setImageResource(Rdrawabletab_address_pressed);
break;
case 3:
((ImageButton) mTabBtnSettingsfindViewById(Ridbtn_tab_bottom_setting))
setImageResource(Rdrawabletab_settings_pressed);
break;
}
currentIndex = position;
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2)
{
}
@Override
public void onPageScrollStateChanged(int arg0)
{
}
});
}
protected void resetTabBtn()
{
((ImageButton) mTabBtnWeixinfindViewById(Ridbtn_tab_bottom_weixin))
setImageResource(Rdrawabletab_weixin_normal);
((ImageButton) mTabBtnFrdfindViewById(Ridbtn_tab_bottom_friend))
setImageResource(Rdrawabletab_find_frd_normal);
((ImageButton) mTabBtnAddressfindViewById(Ridbtn_tab_bottom_contact))
setImageResource(Rdrawabletab_address_normal);
((ImageButton) mTabBtnSettingsfindViewById(Ridbtn_tab_bottom_setting))
setImageResource(Rdrawabletab_settings_normal);
}
private void initView()
{
mTabBtnWeixin = (LinearLayout) findViewById(Ridid_tab_bottom_weixin);
mTabBtnFrd = (LinearLayout) findViewById(Ridid_tab_bottom_friend);
mTabBtnAddress = (LinearLayout) findViewById(Ridid_tab_bottom_contact);
mTabBtnSettings = (LinearLayout) findViewById(Ridid_tab_bottom_setting);
MainTab01 tab01 = new MainTab01();
MainTab02 tab02 = new MainTab02();
MainTab03 tab03 = new MainTab03();
MainTab04 tab04 = new MainTab04();
mFragmentsadd(tab01);
mFragmentsadd(tab02);
mFragmentsadd(tab03);
mFragmentsadd(tab04);
}
}
还有4个TabFragment,下面贴一个,四个基本一样
package com.example.mainframework03;
import androidosBundle;
import androidsupportvappFragment;
import androidviewLayoutInflater;
import androidviewView;
import androidviewViewGroup;
public class MainTab01 extends Fragment
{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflaterinflate(Rlayoutmain_tab_01, container, false);
}
}
评价:实现效果和第一种效果一模一样,每个Fragment独自处理自己内部的逻辑,代码整洁很多,并且支持左右滑动。感觉是第一种和第二种的结合版本。
4、TabPageIndicator+ViewPager+FragmentPagerAdapter
实现方式和3是一致的,但是使用了TabPageIndicator作为tab的指示器,效果还是不错的,这个之前写过,就不再贴代码了。
效果图:
好了,就总结了这么多,肯定还有很多别的实现方式,大家可以留言,有时间会继续完善这篇总结的。
第一种和第二种的源码:demo下载
第三种方式的源码:demo下载
来源:http://blog.csdn.net/lmj623565791/article/details/24740977


猜你喜欢
- 主窗体Form1关键代码: 将子窗体最为对话框模式弹出,当窗体关闭或取消时更新主窗体 private void simpleButton1_
- 引言前文中了解到AQS借助LockSupport.park和LockSupport.unpark完成线程的阻塞和唤醒,那么LockSuppo
- 先看实例 代码如下 classip { privatestaticlongiptolong(stringstrip) //将127.0.0.
- using System;using System.Collections.Generic;using System.Net;using S
- 使用例子如下,用JAVA 运行Sort1, 输入你要排序的文件路径 , 如 例子是对H:\下的文件和它所有子文件夹下的文件进行排序2, 输入
- 本文实例讲述了WinForm实现状态栏跑马灯效果的方法。分享给大家供大家参考,具体如下:using System;using System.
- 1、引言在SpringMVC的使用中,后端与前端的交互一般是使用Json格式进行数据传输,SpringMVC的@Response
- 在C#中常用到的运算符有条件运算符,is运算符,as运算符,typeof 运算符等等,接下来在文章中将为大家具体介绍各个运算符的使用方法条件
- 本文实例讲述了C#使用Dispose模式实现手动对资源的释放。分享给大家供大家参考。具体实现方法如下://单一类的实现class MyCla
- 在笔试编程过程中,关于数据的读取如果迷迷糊糊,那后来的编程即使想法很对,实现很好,也是徒劳,于是在这里认真总结了Java Scanner 类
- 一、介绍Mesh类:通过脚本创建或是获取网格的类,网格包含多个顶点和三角形数组。顶点信息包含坐标和所在面的法线。unity中3D的世界的所有
- Android前段和后端接口进行交互时,经常会遇到特殊字符,比如表情、特殊标点等,这样在Url中是无法识别的,需要进行转码,后端进行解码交互
- 本文实例为大家分享了android实现录屏功能的具体代码,供大家参考,具体内容如下1、mian.activitypackage com.fp
- 1:新建一个项目运行起来,可以看到顶部一直有个标题栏看着不是很美观2:有两种方法可以去除顶部标题栏(1)将代码中AndroidManifes
- 上篇文章我们讲解了使用Hibernate Validation来校验数据,当校验完数据后,如果发生错误我们需要给客户返回一个错误信息,因此这
- Spring如何使用 * 缓存解决循环依赖在没开始文章之前首先来了解一下什么是循环依赖@Componentpublic class A {@A
- SpringBoot集成Redis 1.添加redis依赖<dependency> <groupId
- 本文实例为大家分享了android studio实现简单计算器的具体代码,供大家参考,具体内容如下布局:<?xml version=&
- 一、算法描述波雷费密码是一种对称式密码,是首种双字母取代的加密法。下面描述算法步骤:1、从1号二维码M05,提取明文信息和密文,M05格式:
- 目录前言解决方案前言我们在开发Spring应用时可能会不小心注入两个相同类型的Bean,比如实现了两个相同Service接口的类,示例伪代码