转载于:https://www.cnblogs.com/caobotao/p/5103673.html
在平时的Android开发中,我们经常会使用Tab来进行主界面的布局。由于手机屏幕尺寸的限制,合理使用Tab可以极大的利用屏幕资源,给用户带来良好的体验。学会Tab的使用方法已经成为学习Android开发必不可少的技能了。我们经常使用的微信、QQ就是使用Tab的方式进行主界面的布局的。
下面我们通过三种方式实现旧版的微信主界面以演示Tab的使用方式。
最终效果:
第一种:单纯使用ViewPager
MainActivity.java
public class MainActivity extends Activity implements OnClickListener {
//声明ViewPager
private ViewPager mViewpager;
//声明四个Tab
private LinearLayout mTabWeixin;
private LinearLayout mTabFrd;
private LinearLayout mTabAddress;
private LinearLayout mTabSetting;
//声明四个ImageButton
private ImageButton mWeixinImg;
private ImageButton mFrdImg;
private ImageButton mAddressImg;
private ImageButton mSettingImg;
//声明ViewPager的适配器
private PagerAdapter mAdpater;
//用于装载四个Tab的List
private List mTabs = new ArrayList();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//去掉TitleBar
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
initViews();//初始化控件
initDatas();//初始化数据
initEvents();//初始化事件
}
private void initEvents() {
//设置四个Tab的点击事件
mTabWeixin.setOnClickListener(this);
mTabFrd.setOnClickListener(this);
mTabAddress.setOnClickListener(this);
mTabSetting.setOnClickListener(this);
//添加ViewPager的切换Tab的监听事件
mViewpager.addOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
//获取ViewPager的当前Tab
int currentItem = mViewpager.getCurrentItem();
//将所以的ImageButton设置成灰色
resetImgs();
//将当前Tab对应的ImageButton设置成绿色
switch (currentItem) {
case 0:
mWeixinImg.setImageResource(R.mipmap.tab_weixin_pressed);
break;
case 1:
mFrdImg.setImageResource(R.mipmap.tab_find_frd_pressed);
break;
case 2:
mAddressImg.setImageResource(R.mipmap.tab_address_pressed);
break;
case 3:
mSettingImg.setImageResource(R.mipmap.tab_settings_pressed);
break;
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
private void initDatas() {
//初始化ViewPager的适配器
mAdpater = new PagerAdapter() {
@Override
public int getCount() {
return mTabs.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
View view = mTabs.get(position);
container.addView(view);
return view;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(mTabs.get(position));
}
};
//设置ViewPager的适配器
mViewpager.setAdapter(mAdpater);
}
//初始化控件
private void initViews() {
mViewpager = (ViewPager) findViewById(R.id.id_viewpager);
mTabWeixin = (LinearLayout) findViewById(R.id.id_tab_weixin);
mTabFrd = (LinearLayout) findViewById(R.id.id_tab_frd);
mTabAddress = (LinearLayout) findViewById(R.id.id_tab_address);
mTabSetting = (LinearLayout) findViewById(R.id.id_tab_setting);
mWeixinImg = (ImageButton) findViewById(R.id.id_tab_weixin_img);
mFrdImg = (ImageButton) findViewById(R.id.id_tab_frd_img);
mAddressImg = (ImageButton) findViewById(R.id.id_tab_address_img);
mSettingImg = (ImageButton) findViewById(R.id.id_tab_setting_img);
//获取到四个Tab
LayoutInflater inflater = LayoutInflater.from(this);
View tab1 = inflater.inflate(R.layout.tab1, null);
View tab2 = inflater.inflate(R.layout.tab2, null);
View tab3 = inflater.inflate(R.layout.tab3, null);
View tab4 = inflater.inflate(R.layout.tab4, null);
//将四个Tab添加到集合中
mTabs.add(tab1);
mTabs.add(tab2);
mTabs.add(tab3);
mTabs.add(tab4);
}
@Override
public void onClick(View v) {
//先将四个ImageButton都设置成灰色
resetImgs();
switch (v.getId()) {
case R.id.id_tab_weixin:
//设置viewPager的当前Tab
mViewpager.setCurrentItem(0);
//将当前Tab对应的ImageButton设置成绿色
mWeixinImg.setImageResource(R.mipmap.tab_weixin_pressed);
break;
case R.id.id_tab_frd:
mViewpager.setCurrentItem(1);
mFrdImg.setImageResource(R.mipmap.tab_find_frd_pressed);
break;
case R.id.id_tab_address:
mViewpager.setCurrentItem(2);
mAddressImg.setImageResource(R.mipmap.tab_address_pressed);
break;
case R.id.id_tab_setting:
mViewpager.setCurrentItem(3);
mSettingImg.setImageResource(R.mipmap.tab_settings_pressed);
break;
}
}
//将四个ImageButton设置成灰色
private void resetImgs () {
mWeixinImg.setImageResource(R.mipmap.tab_weixin_normal);
mFrdImg.setImageResource(R.mipmap.tab_find_frd_normal);
mAddressImg.setImageResource(R.mipmap.tab_address_normal);
mSettingImg.setImageResource(R.mipmap.tab_settings_normal);
}
}
顶部布局文件
top.xm
四个Tab对应页面的布局文件
tabl1.xml
tab2.xml
tab3.xm
tab4.xml
底部布局文件
bottom.xml
主布局文件
完整源码 : 点击下载
单纯使用ViewPager的方式可以实现左右滑动切换页面和点击Tab切换页面的效果。但是大家发现,这种方式需要在Activity完成所有的代码实现,包括初始化Tab及其对应页面的初始化控件、数据、事件及业务逻辑的处理。这样会使得Activity看起来非常臃肿,进而造成代码的可读性和可维护性变得极差。
谷歌在Android 3.0时推出了Fragment。可以分别使用Fragment来管理每个Tab对应的页面的布局及功能的实现。然后将Fragment与Android关联,这样Android只需要管理Fragment就行了,起到了调度器的作用,不再关心每个Fragment里的内容及功能实现是什么。这样就极大的解放了Activity,使代码变得简单、易读。
下面我们通过使用Fragment的方式来实现Tab。
第二种:单纯使用Fragment
MainActivity.java
public class MainActivity extends FragmentActivity implements OnClickListener {
//声明四个Tab的布局文件
private LinearLayout mTabWeixin;
private LinearLayout mTabFrd;
private LinearLayout mTabAddress;
private LinearLayout mTabSetting;
//声明四个Tab的ImageButton
private ImageButton mWeixinImg;
private ImageButton mFrdImg;
private ImageButton mAddressImg;
private ImageButton mSettingImg;
//声明四个Tab分别对应的Fragment
private Fragment mFragWeinxin;
private Fragment mFragFrd;
private Fragment mFragAddress;
private Fragment mFragSetting;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
initViews();//初始化控件
initEvents();//初始化事件
selectTab(0);//默认选中第一个Tab
}
private void initEvents() {
//初始化四个Tab的点击事件
mTabWeixin.setOnClickListener(this);
mTabFrd.setOnClickListener(this);
mTabAddress.setOnClickListener(this);
mTabSetting.setOnClickListener(this);
}
private void initViews() {
//初始化四个Tab的布局文件
mTabWeixin = (LinearLayout) findViewById(R.id.id_tab_weixin);
mTabFrd = (LinearLayout) findViewById(R.id.id_tab_frd);
mTabAddress = (LinearLayout) findViewById(R.id.id_tab_address);
mTabSetting = (LinearLayout) findViewById(R.id.id_tab_setting);
//初始化四个ImageButton
mWeixinImg = (ImageButton) findViewById(R.id.id_tab_weixin_img);
mFrdImg = (ImageButton) findViewById(R.id.id_tab_frd_img);
mAddressImg = (ImageButton) findViewById(R.id.id_tab_address_img);
mSettingImg = (ImageButton) findViewById(R.id.id_tab_setting_img);
}
//处理Tab的点击事件
@Override
public void onClick(View v) {
//先将四个ImageButton置为灰色
resetImgs();
switch (v.getId()) {
case R.id.id_tab_weixin:
selectTab(0);//当点击的是微信的Tab就选中微信的Tab
break;
case R.id.id_tab_frd:
selectTab(1);
break;
case R.id.id_tab_address:
selectTab(2);
break;
case R.id.id_tab_setting:
selectTab(3);
break;
}
}
//进行选中Tab的处理
private void selectTab(int i) {
//获取FragmentManager对象
FragmentManager manager = getSupportFragmentManager();
//获取FragmentTransaction对象
FragmentTransaction transaction = manager.beginTransaction();
//先隐藏所有的Fragment
hideFragments(transaction);
switch (i) {
//当选中点击的是微信的Tab时
case 0:
//设置微信的ImageButton为绿色
mWeixinImg.setImageResource(R.mipmap.tab_weixin_pressed);
//如果微信对应的Fragment没有实例化,则进行实例化,并显示出来
if (mFragWeinxin == null) {
mFragWeinxin = new WeixinFragment();
transaction.add(R.id.id_content, mFragWeinxin);
} else {
//如果微信对应的Fragment已经实例化,则直接显示出来
transaction.show(mFragWeinxin);
}
break;
case 1:
mFrdImg.setImageResource(R.mipmap.tab_find_frd_pressed);
if (mFragFrd == null) {
mFragFrd = new FrdFragment();
transaction.add(R.id.id_content, mFragFrd);
} else {
transaction.show(mFragFrd);
}
break;
case 2:
mAddressImg.setImageResource(R.mipmap.tab_address_pressed);
if (mFragAddress == null) {
mFragAddress = new AddressFragment();
transaction.add(R.id.id_content, mFragAddress);
} else {
transaction.show(mFragAddress);
}
break;
case 3:
mSettingImg.setImageResource(R.mipmap.tab_settings_pressed);
if (mFragSetting == null) {
mFragSetting = new SettingFragment();
transaction.add(R.id.id_content, mFragSetting);
} else {
transaction.show(mFragSetting);
}
break;
}
//不要忘记提交事务
transaction.commit();
}
//将四个的Fragment隐藏
private void hideFragments(FragmentTransaction transaction) {
if (mFragWeinxin != null) {
transaction.hide(mFragWeinxin);
}
if (mFragFrd != null) {
transaction.hide(mFragFrd);
}
if (mFragAddress != null) {
transaction.hide(mFragAddress);
}
if (mFragSetting != null) {
transaction.hide(mFragSetting);
}
}
//将四个ImageButton置为灰色
private void resetImgs() {
mWeixinImg.setImageResource(R.mipmap.tab_weixin_normal);
mFrdImg.setImageResource(R.mipmap.tab_find_frd_normal);
mAddressImg.setImageResource(R.mipmap.tab_address_normal);
mSettingImg.setImageResource(R.mipmap.tab_settings_normal);
}
}
“微信”、“朋友”、“通讯录”、“设置”所对应的Fragment
WeixinFragment.java
public class WeixinFragment extends Fragment{
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.tab1, container, false);
return view;
}
}
FrdFragmen.java
public class FrdFragment extends Fragment{
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.tab2, container, false);
return view;
}
}
AddressFragmen.java
public class AddressFragment extends Fragment{
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.tab3, container, false);
return view;
}
}
SettingFragment.java
public class SettingFragment extends Fragment{
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.tab4, container, false);
return view;
}
}
顶部布局文件
top.xml
四个Tab对应页面的布局文件
tab1.xml
tab2.xml
tab3.xml
tab4.xml
底部布局文件
bottom.xml
主布局文件
完整源码 : 点击下载
可以看出,使用Fragment实现了Activity与Tab对应的页面分离,特别是当Tab对应的页面的布局和逻辑比较复杂时更能体会到使用Fragment的好处。但是单纯使用Fragment只能通过点击Tab来切换页面,并不能实现左右滑动进行切换。
下面我们通过使用 ViewPager + Fragment 的方式实现Tab,这也是开发中使用比较广泛的一种方式。
第三种:使用 ViewPager + Fragment
MainActivity.java
public class MainActivity extends FragmentActivity implements OnClickListener {
//声明ViewPager
private ViewPager mViewPager;
//适配器
private FragmentPagerAdapter mAdapter;
//装载Fragment的集合
private List mFragments;
//四个Tab对应的布局
private LinearLayout mTabWeixin;
private LinearLayout mTabFrd;
private LinearLayout mTabAddress;
private LinearLayout mTabSetting;
//四个Tab对应的ImageButton
private ImageButton mImgWeixin;
private ImageButton mImgFrd;
private ImageButton mImgAddress;
private ImageButton mImgSetting;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
initViews();//初始化控件
initEvents();//初始化事件
initDatas();//初始化数据
}
private void initDatas() {
mFragments = new ArrayList<>();
//将四个Fragment加入集合中
mFragments.add(new WeixinFragment());
mFragments.add(new FrdFragment());
mFragments.add(new AddressFragment());
mFragments.add(new SettingFragment());
//初始化适配器
mAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) {
@Override
public Fragment getItem(int position) {//从集合中获取对应位置的Fragment
return mFragments.get(position);
}
@Override
public int getCount() {//获取集合中Fragment的总数
return mFragments.size();
}
};
//不要忘记设置ViewPager的适配器
mViewPager.setAdapter(mAdapter);
//设置ViewPager的切换监听
mViewPager.addOnPageChangeListener(new OnPageChangeListener() {
@Override
//页面滚动事件
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
//页面选中事件
@Override
public void onPageSelected(int position) {
//设置position对应的集合中的Fragment
mViewPager.setCurrentItem(position);
resetImgs();
selectTab(position);
}
@Override
//页面滚动状态改变事件
public void onPageScrollStateChanged(int state) {
}
});
}
private void initEvents() {
//设置四个Tab的点击事件
mTabWeixin.setOnClickListener(this);
mTabFrd.setOnClickListener(this);
mTabAddress.setOnClickListener(this);
mTabSetting.setOnClickListener(this);
}
//初始化控件
private void initViews() {
mViewPager = (ViewPager) findViewById(R.id.id_viewpager);
mTabWeixin = (LinearLayout) findViewById(R.id.id_tab_weixin);
mTabFrd = (LinearLayout) findViewById(R.id.id_tab_frd);
mTabAddress = (LinearLayout) findViewById(R.id.id_tab_address);
mTabSetting = (LinearLayout) findViewById(R.id.id_tab_setting);
mImgWeixin = (ImageButton) findViewById(R.id.id_tab_weixin_img);
mImgFrd = (ImageButton) findViewById(R.id.id_tab_frd_img);
mImgAddress = (ImageButton) findViewById(R.id.id_tab_address_img);
mImgSetting = (ImageButton) findViewById(R.id.id_tab_setting_img);
}
@Override
public void onClick(View v) {
//先将四个ImageButton置为灰色
resetImgs();
//根据点击的Tab切换不同的页面及设置对应的ImageButton为绿色
switch (v.getId()) {
case R.id.id_tab_weixin:
selectTab(0);
break;
case R.id.id_tab_frd:
selectTab(1);
break;
case R.id.id_tab_address:
selectTab(2);
break;
case R.id.id_tab_setting:
selectTab(3);
break;
}
}
private void selectTab(int i) {
//根据点击的Tab设置对应的ImageButton为绿色
switch (i) {
case 0:
mImgWeixin.setImageResource(R.mipmap.tab_weixin_pressed);
break;
case 1:
mImgFrd.setImageResource(R.mipmap.tab_find_frd_pressed);
break;
case 2:
mImgAddress.setImageResource(R.mipmap.tab_address_pressed);
break;
case 3:
mImgSetting.setImageResource(R.mipmap.tab_settings_pressed);
break;
}
//设置当前点击的Tab所对应的页面
mViewPager.setCurrentItem(i);
}
//将四个ImageButton设置为灰色
private void resetImgs() {
mImgWeixin.setImageResource(R.mipmap.tab_weixin_normal);
mImgFrd.setImageResource(R.mipmap.tab_find_frd_normal);
mImgAddress.setImageResource(R.mipmap.tab_address_normal);
mImgSetting.setImageResource(R.mipmap.tab_settings_normal);
}
}
“微信”、“朋友”、“通讯录”、“设置”所对应的Fragment
WeixinFragment.java
public class WeixinFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.tab1, container, false);
return view;
}
}
FrdFragment.java
public class FrdFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.tab2, container, false);
return view;
}
}
AddressFragment.java
public class AddressFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.tab3, container, false);
return view;
}
}
SettingFragment.java
public class SettingFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.tab4, container, false);
return view;
}
}
顶部布局文件
top.xml
四个Tab对应页面的布局文件
tab1.xml
tab2.xml
tab3.xml
tab4.xml
底部布局文件
bottom.xml
主布局文件
完整源码 :点击下载
使用 ViewPager + Fragment 的方式综合了使用ViewPager和使用Fragment的优势,即:既能使用Fragment管理Tab对应页面的布局及业务逻辑的实现,使得Activity与Tab对应的页面分离,又能使用ViewPager实现左右滑动切换页面的效果。这种方式需要为ViewPager设置FragmentPagerAdapter适配器,关于适配器的知识可参考我之前写的一篇文章:Android必学之数据适配器BaseAdapter
作者:caobotao
出处: http://www.cnblogs.com/caobotao/p/5103673.html
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。