在平时的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<View> mTabs = new ArrayList<View>(); @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);
}
}

顶部布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:background="@android:drawable/title_bar"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="45dp"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="微信"
android:textColor="#ffffff"
android:textSize="20sp"
android:textStyle="bold"/> </LinearLayout>

top.xml

四个Tab对应页面的布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="30sp"
android:text="The Weixin Tab!"/>
</LinearLayout>

tab1.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="30sp"
android:text="The Friend Tab!"/>
</LinearLayout>

tab2.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="30sp"
android:text="The Address Tab!"/>
</LinearLayout>

tab3.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="30sp"
android:text="The Setting Tab!"/>
</LinearLayout>

tab4.xml

底部布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="55dp"
android:gravity="center"
android:background="@color/material_blue_grey_800"
android:orientation="horizontal"> <LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/id_tab_weixin"
android:gravity="center"
android:orientation="vertical"> <ImageButton
android:id="@+id/id_tab_weixin_img"
android:clickable="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/tab_weixin_pressed"
android:background="#00000000"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ffffff"
android:text="微信"/>
</LinearLayout>
<LinearLayout
android:id="@+id/id_tab_frd"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"> <ImageButton
android:id="@+id/id_tab_frd_img"
android:clickable="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/tab_find_frd_normal"
android:background="#00000000"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ffffff"
android:text="朋友"/>
</LinearLayout>
<LinearLayout
android:id="@+id/id_tab_address"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"> <ImageButton
android:id="@+id/id_tab_address_img"
android:clickable="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/tab_address_normal"
android:background="#00000000"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ffffff"
android:text="通讯录"/>
</LinearLayout>
<LinearLayout
android:id="@+id/id_tab_setting"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"> <ImageButton
android:id="@+id/id_tab_setting_img"
android:clickable="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/tab_settings_normal"
android:background="#00000000"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ffffff"
android:text="设置"/>
</LinearLayout> </LinearLayout>

bottom.xml

主布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/top"/> <android.support.v4.view.ViewPager
android:id="@+id/id_viewpager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"> </android.support.v4.view.ViewPager> <include layout="@layout/bottom"/>
</LinearLayout>

activity_main.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

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;
}
}

WeixinFragment.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;
}
}

FrdFragment.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;
}
}

AddressFragment.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;
}
}

SettingFragment.java

顶部布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:background="@android:drawable/title_bar"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="45dp"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="微信"
android:textColor="#ffffff"
android:textSize="20sp"
android:textStyle="bold"/> </LinearLayout>

top.xml

四个Tab对应页面的布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="30sp"
android:text="The Weixin Tab!"/>
</LinearLayout>

tab1.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="30sp"
android:text="The Friend Tab!"/>
</LinearLayout>

tab2.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="30sp"
android:text="The Address Tab!"/>
</LinearLayout>

tab3.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="30sp"
android:text="The Setting Tab!"/>
</LinearLayout>

tab4.xml

底部布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="55dp"
android:gravity="center"
android:background="@color/material_blue_grey_800"
android:orientation="horizontal"> <LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/id_tab_weixin"
android:gravity="center"
android:orientation="vertical"> <ImageButton
android:id="@+id/id_tab_weixin_img"
android:clickable="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/tab_weixin_pressed"
android:background="#00000000"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ffffff"
android:text="微信"/>
</LinearLayout>
<LinearLayout
android:id="@+id/id_tab_frd"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"> <ImageButton
android:id="@+id/id_tab_frd_img"
android:clickable="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/tab_find_frd_normal"
android:background="#00000000"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ffffff"
android:text="朋友"/>
</LinearLayout>
<LinearLayout
android:id="@+id/id_tab_address"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"> <ImageButton
android:id="@+id/id_tab_address_img"
android:clickable="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/tab_address_normal"
android:background="#00000000"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ffffff"
android:text="通讯录"/>
</LinearLayout>
<LinearLayout
android:id="@+id/id_tab_setting"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"> <ImageButton
android:id="@+id/id_tab_setting_img"
android:clickable="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/tab_settings_normal"
android:background="#00000000"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ffffff"
android:text="设置"/>
</LinearLayout> </LinearLayout>

bottom.xml

主布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/top"/> <FrameLayout
android:id="@+id/id_content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"> </FrameLayout> <include layout="@layout/bottom"/>
</LinearLayout>

activity_main.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<Fragment> 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

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;
}
}

WeixinFragment.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;
}
}

FrdFragment.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;
}
}

AddressFragment.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;
}
}

SettingFragment.java

顶部布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:background="@android:drawable/title_bar"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="45dp"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="微信"
android:textColor="#ffffff"
android:textSize="20sp"
android:textStyle="bold"/> </LinearLayout>

top.xml

四个Tab对应页面的布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="30sp"
android:text="The Weixin Tab!"/>
</LinearLayout>

tab1.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="30sp"
android:text="The Friend Tab!"/>
</LinearLayout>

tab2.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="30sp"
android:text="The Address Tab!"/>
</LinearLayout>

tab3.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="30sp"
android:text="The Setting Tab!"/>
</LinearLayout>

tab4.xml

底部布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="55dp"
android:gravity="center"
android:background="@color/material_blue_grey_800"
android:orientation="horizontal"> <LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/id_tab_weixin"
android:gravity="center"
android:orientation="vertical"> <ImageButton
android:id="@+id/id_tab_weixin_img"
android:clickable="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/tab_weixin_pressed"
android:background="#00000000"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ffffff"
android:text="微信"/>
</LinearLayout>
<LinearLayout
android:id="@+id/id_tab_frd"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"> <ImageButton
android:id="@+id/id_tab_frd_img"
android:clickable="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/tab_find_frd_normal"
android:background="#00000000"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ffffff"
android:text="朋友"/>
</LinearLayout>
<LinearLayout
android:id="@+id/id_tab_address"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"> <ImageButton
android:id="@+id/id_tab_address_img"
android:clickable="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/tab_address_normal"
android:background="#00000000"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ffffff"
android:text="通讯录"/>
</LinearLayout>
<LinearLayout
android:id="@+id/id_tab_setting"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"> <ImageButton
android:id="@+id/id_tab_setting_img"
android:clickable="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/tab_settings_normal"
android:background="#00000000"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ffffff"
android:text="设置"/>
</LinearLayout> </LinearLayout>

bottom.xml

主布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/top"/> <android.support.v4.view.ViewPager
android:id="@+id/id_viewpager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"> </android.support.v4.view.ViewPager> <include layout="@layout/bottom"/>
</LinearLayout>

activity_main.xml

完整源码 : 点击下载

使用 ViewPager + Fragment 的方式综合了使用ViewPager和使用Fragment的优势,即:既能使用Fragment管理Tab对应页面的布局及业务逻辑的实现,使得Activity与Tab对应的页面分离,又能使用ViewPager实现左右滑动切换页面的效果。这种方式需要为ViewPager设置FragmentPagerAdapter适配器,关于适配器的知识可参考我之前写的一篇文章:Android必学之数据适配器BaseAdapter


作者:caobotao
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。

三种实现Android主界面Tab的方式的更多相关文章

  1. Android两种为ViewPager+Fragment添加Tab的方式

    在Android开发中ViewPager的使用是非常广泛的,而它不仅仅能够实现简单的开始引导页,还可以结合Fragment并添加Tab作为选项卡或为显示大批量页面实现强大的顺畅滑动 下面介绍两种为Vi ...

  2. 在.NET Core中三种实现“可插拔”AOP编程方式(附源码)

    一看标题肯定会联想到使用动态编织的方式实现AOP编程,不过这不是作者本文讨论的重点. 本文讨论另外三种在netcore中可实现的方式,Filter(过滤器,严格意义上它算是AOP方式),Dynamic ...

  3. 【IMOOC学习笔记】多种多样的App主界面Tab实现方法(三)

    FragmentPagerAdapter+ViewPager 与之前直接用ViewPager不同的是,数组里面放的不再是View,而是Fraagment; 使用FragmentPagerAdapter ...

  4. App主界面Tab实现方法

    ViewPager + FragmentPagerAdapter 这里模仿下微信APP界面的实现 国际惯例,先看下效果图:   activity_main.xml 布局文件: <?xml ver ...

  5. Android 主界面长按创建快捷方式

    Android中创建快捷方式主要有两种方式.一是在代码中直接加入生成桌面快捷方式的代码:二是通过小部件加入; 这篇文章主要讲另外一种方法! 1.通过在AndroidManifest文件里为Activi ...

  6. 66、多种多样的App主界面Tab(1)------ ViewPager实现Tab

    <?xml version="1.0" encoding="utf-8"?> <!-- bottom.xml --> <Linea ...

  7. 【IMOOC学习笔记】多种多样的App主界面Tab实现方法(四)

    ViewPagerIndicator+ViewPager 要想使用ViewPagerIndicator,要使用到viewPagerlibrary开源库 top.xml <?xml version ...

  8. 【IMOOC学习笔记】多种多样的App主界面Tab实现方法(二)

    Fragment实现Tab 首先把activity_main.xml 文件中的ViewPager标签改成Fragment标签 <FrameLayout android:id="@+id ...

  9. 【IMOOC学习笔记】多种多样的App主界面Tab实现方法(一)

    1.ViewPager实现Tab 首先实现底部和底部布局 <?xml version="1.0" encoding="utf-8"?> <Li ...

随机推荐

  1. Kubelet bootstrap 流程

    首先,什么是kubelet bootstrap?在安装 k8s worker node 时,基本上 worker 的初始状态仅仅是安装了 docker 和 kubelet,worker 需要一种机制跟 ...

  2. Keepalived+MySQL实现高可用

    MySQL的高可用方案有很多,比如Cluster,MMM,MHA,DRBD等,这些都比较复杂,我前面的文章也有介绍.最近Oracle官方也推出了Fabric.有时我们不需要这么复杂的环境,这些方案各有 ...

  3. electron-vue 淘宝源

    yarn-js config set registry https://registry.npm.taobao.org

  4. 426. Convert Binary Search Tree to Sorted Doubly Linked List把bst变成双向链表

    [抄题]: Convert a BST to a sorted circular doubly-linked list in-place. Think of the left and right po ...

  5. 写一份简单的webpack2 的配置文件,无比简单

    这是一份自己用到的webpack2的配置写法,从看webpack2开始,发现自己越来越懒了,现在html文件都不想自己写了,直接自己生成... 哈哈,这次是可以无比完美的导入css啦 开发的时候在命令 ...

  6. CentOS_mini下make安装

    执行make时显示: make: *** No targets specified and no makefile found. Stop. 用网上的教程: wget http://ftp.gnu.o ...

  7. 【转】权限管理学习 一、ASP.NET Forms身份认证

    [转]权限管理学习 一.ASP.NET Forms身份认证 说明:本文示例使用的VS2017和MVC5. 系统无论大小.牛逼或屌丝,一般都离不开注册.登录.那么接下来我们就来分析下用户身份认证. 简单 ...

  8. latex表格代码

     基本代码 \begin{table}[!h] \caption{Notations Used in Real-time Analysis.} \label{table:notation} \cent ...

  9. mongoDB实现MapReduce

    一.MongoDB Map Reduce Map-Reduce是一种计算模型,简单的说就是将大批量的工作(数据)分解(MAP)执行,然后再将结果合并成最终结果(REDUCE).MongoDB提供的Ma ...

  10. Memcache cpu占用过高

    分析应该是memcache的内存大小还是默认配置,已经满足不了当前的大数据量的需要了,大量的新缓存需要进入,同时大量的旧缓存又需要被淘汰出来,一进一出导致CPU占用过多.进入注册表,找到:HKEY_L ...