您的位置:首页 > 移动开发 > Android开发

android-多种方式实现主界面的Tab

2016-09-20 09:37 555 查看
本人水平有限,文章中如果出现什么不正确或者模糊的地方,还请各位小伙伴留下评论,多多指教 : )

前言

使用Fragment实现
思路

效果

具体讲解
底部布局

顶部布局

Fragment的布局

Java控制代码

使用ViewPager实现
思路

效果

具体实现

使用ViewPagerFragmentPagerAdapter方法实现
思路

效果

补充

具体代码

使用框架

前言

这篇文章主要介绍多种方式实现主界面的tab,包括:

(1)使用Fragment实现

(2)使用ViewPage实现

(3)使用ViewPage+FragmentPageAdapter

(4)使用框架实现

在线的视频课程来自慕课网——多种多样的App主界面Tab实现方法。觉得文字不好理解的小伙伴可以去看视频,然后再回头自己敲一遍。

使用Fragment实现

比较常规的使用方法,需要大家对Fragment有基本了解,这里推荐hongyang大神的几篇博文:

Android Fragment 真正的完全解析(上)

Android Fragment 真正的完全解析(下)

相信各位看完之后对Fragment就能有一个比较清楚的了解。

思路

这种方式实现的思路比较简单:

1、首先在主布局中加入FragmentLayout

2、然后在Java代码中监听底部的按钮,当点击时,只需让FragmentLayout加载相应的Fragment即可



效果



可以看到,如果单纯地使用Fragment,实际上是不能实现左右滑动的效果,页面的切换,只能靠点击底部的Button来实现。

具体讲解

底部布局

首先是底部的一个布局文件bottom.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="65dp"
android:background="@drawable/bottom_bar">
<LinearLayout
android:id="@+id/id_tab_weixin"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<ImageButton
android:id="@+id/id_tab_weixin_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/tab_weixin_pressed"
android:background="#0000"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#fff"
android:text="微信"/>

</LinearLayout>
<LinearLayout
android:id="@+id/id_tab_frd"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<ImageButton
android:id="@+id/id_tab_frd_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/tab_find_frd_normal"
android:background="#0000"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#fff"
android:text="朋友"/>

</LinearLayout>

<LinearLayout
android:id="@+id/id_tab_address"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<ImageButton
android:id="@+id/id_tab_address_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/tab_address_normal"
android:background="#0000"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#fff"
android:text="通讯录"/>

</LinearLayout>

<LinearLayout
android:id="@+id/id_tab_setting"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<ImageButton
android:id="@+id/id_tab_setting_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/tab_settings_normal"
android:background="#0000"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#fff"
android:text="设置"/>

</LinearLayout>

</LinearLayout>


简单的线性布局,放置我们的按钮。



这个布局在后面的栗子中也会使用。

顶部布局

接下来是一个顶部的title

<?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="45dp"
android:gravity="center"
android:background="@drawable/title_bar">

<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="微信"
android:textColor="#ffffff"
android:textSize="20sp"
android:textStyle="bold"
android:layout_gravity="center"/>

</LinearLayout>


就一个TextView。

Fragment的布局



为了简单起见,这里面的布局只放置一个TextView

Java控制代码

TestActivity2

public class TestActivity2 extends Activity implements View.OnClickListener {
private LinearLayout mTabWeixin;
private LinearLayout mTabFrd;
private LinearLayout mTabAddress;
private LinearLayout mTabSetting;
//底部的按钮
private ImageButton mWeiXin;
private ImageButton mFriend;
private ImageButton mAddress;
private ImageButton mSetting;
//FragmentLayout要加载的四个Fragment
private WeiXinFragment weiXinFragment;
private FriendFragment friendFragment;
private AddressFragment addressFragment;
private SettingFragment settingFragment;
//顶部的标题
private TextView tvTitle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.test_ac_2);

initView();

initEvents();

setSelect(0);
}

private void initEvents() {
mWeiXin.setOnClickListener(this);
mFriend.setOnClickListener(this);
mAddress.setOnClickListener(this);
mSetting.setOnClickListener(this);

}

private void initView() {
//初始化

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

mWeiXin= (ImageButton) findViewById(R.id.id_tab_weixin_img);
mFriend= (ImageButton) findViewById(R.id.id_tab_frd_img);
mAddress= (ImageButton) findViewById(R.id.id_tab_address_img);
mSetting= (ImageButton) findViewById(R.id.id_tab_setting_img);

tvTitle= (TextView) findViewById(R.id.tv_title);
}

@Override
public void onClick(View view) {

switch (view.getId()){
case R.id.id_tab_weixin_img:
setSelect(0);
break;
case R.id.id_tab_frd_img:
setSelect(1);
break;
case R.id.id_tab_address_img:
setSelect(2);
break;
case R.id.id_tab_setting_img:
setSelect(3);
break;
}

}

private void hideFragment(FragmentTransaction fragmentTransaction) {
if (weiXinFragment!=null){
fragmentTransaction.hide(weiXinFragment);
}
if (friendFragment!=null){
fragmentTransaction.hide(friendFragment);
}
if (addressFragment!=null){
fragmentTransaction.hide(addressFragment);
}
if (settingFragment!=null){
fragmentTransaction.hide(settingFragment);
}
}

/*
* 重置所有的图片,让其恢复到灰色状态
* */
private void resetImage() {
mSetting.setImageResource(R.drawable.tab_settings_normal);
mWeiXin.setImageResource(R.drawable.tab_weixin_normal);
mAddress.setImageResource(R.drawable.tab_address_normal);
mFriend.setImageResource(R.drawable.tab_find_frd_normal);
}

/*
* 设置某个Fragment
* */
private void setSelect(int i){
FragmentManager fm=getFragmentManager();
FragmentTransaction fragmentTransaction=fm.beginTransaction();

//重置图片状态
resetImage();
hideFragment(fragmentTransaction);
switch (i){
case 0:
//设置标题
tvTitle.setText("微信");
if (weiXinFragment==null){
//如果Fragment还没实例化,实例化,并在fragmentTransaction中添加
weiXinFragment=new WeiXinFragment();
fragmentTransaction.add(R.id.id_content,weiXinFragment);
}else{
//如果已经实例化了,就显示
fragmentTransaction.show(weiXinFragment);

}
fragmentTransaction.commit();
//改变底部图标的状态
mWeiXin.setImageResource(R.drawable.tab_weixin_pressed);

break;
case 1:
tvTitle.setText("朋友");
if (friendFragment==null){
friendFragment=new FriendFragment();
fragmentTransaction.add(R.id.id_content,friendFragment);

}else{
fragmentTransaction.show(friendFragment);
}

fragmentTransaction.commit();
mFriend.setImageResource(R.drawable.tab_find_frd_pressed);

break;
case 2:
tvTitle.setText("通讯录");
if (addressFragment==null){
addressFragment=new AddressFragment();
fragmentTransaction.add(R.id.id_content,addressFragment);

}else{
fragmentTransaction.show(addressFragment);

}
fragmentTransaction.commit();
mAddress.setImageResource(R.drawable.tab_address_pressed);
break;
case 3:
tvTitle.setText("设置");
if (settingFragment==null){
settingFragment=new SettingFragment();
fragmentTransaction.add(R.id.id_content,settingFragment);

}else{
fragmentTransaction.show(settingFragment);

}
fragmentTransaction.commit();
mSetting.setImageResource(R.drawable.tab_settings_pressed);
break;
}

}
}


代码逻辑很清楚,中间需要提醒的地方已经用注释表明,这个小栗子其实就是Fragment的常规使用,涉及到的内容也都是Fragment基础知识,需要各位小伙伴烂熟于心。

使用ViewPager实现

思路

在上一个栗子当中,我们使用的是FragmentLayout来作为填充Fragment的容器。当使用ViewPage,我们需要把布局文件中的Layout替换成ViewPager。这就要求开发者对ViewPager的使用有基本的了解。

效果



可以看到使用了ViewPager之后不仅可以实现左右的滑动,而且还能通过底部的点击来实现页面切换的效果

具体实现

首先是布局文件

<?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_weight="1"
android:layout_height="0dp">

</android.support.v4.view.ViewPager>

<include
layout="@layout/bottom"/>

</LinearLayout>


非常简单,就是把中间的FragmentLayout换成了ViewPager。

重点在于接下里的Java代码当中,里面涉及到了ViewPager的基本使用。

public class TestActivity1 extends Activity implements View.OnClickListener {
private ViewPager viewPager;
private PagerAdapter pagerAdapter;
private List<View> mViews =new ArrayList<>();
private FragmentPagerAdapter fragmentPagerAdapter;
private FragmentStatePagerAdapter fragmentStatePagerAdapter;

private LinearLayout mTabWeixin;
private LinearLayout mTabFrd;
private LinearLayout mTabAddress;
private LinearLayout mTabSetting;

private ImageButton mWeiXin;
private ImageButton mFriend;
private ImageButton mAddress;
private ImageButton mSetting;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.test_ac_1);

initView();

initEvents();
}

/*
* 初始化事件
* */
private void initEvents() {
mWeiXin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
viewPager.setCurrentItem(0);
mWeiXin.setImageResource(R.drawable.tab_weixin_pressed);
}
});
mSetting.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
viewPager.setCurrentItem(3);
mSetting.setImageResource(R.drawable.tab_settings_pressed);
}
});
mAddress.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
viewPager.setCurrentItem(2);
mAddress.setImageResource(R.drawable.tab_address_pressed);
}
});
mFriend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
viewPager.setCurrentItem(1);
mFriend.setImageResource(R.drawable.tab_find_frd_pressed);
}
});

viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
int currentItem =viewPager.getCurrentItem();
resetImage();
switch (currentItem){
case 0:
mWeiXin.setImageResource(R.drawable.tab_weixin_pressed);
break;
case 1:
mFriend.setImageResource(R.drawable.tab_find_frd_pressed);
break;
case 2:
mAddress.setImageResource(R.drawable.tab_address_pressed);
break;
case 3:
mSetting.setImageResource(R.drawable.tab_settings_pressed);
break;
}
}

@Override
public void onPageSelected(int position) {

}

@Override
public void onPageScrollStateChanged(int state) {

}
});
}

private void initView() {
//初始化
viewPager= (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);

mWeiXin= (ImageButton) findViewById(R.id.id_tab_weixin_img);
mFriend= (ImageButton) findViewById(R.id.id_tab_frd_img);
mAddress= (ImageButton) findViewById(R.id.id_tab_address_img);
mSetting= (ImageButton) findViewById(R.id.id_tab_setting_img);

LayoutInflater mLayoutInfater=LayoutInflater.from(this);
View view1=mLayoutInfater.inflate(R.layout.tab01,null);
View view2=mLayoutInfater.inflate(R.layout.tab02,null);
View view3=mLayoutInfater.inflate(R.layout.tab03,null);
View view4=mLayoutInfater.inflate(R.layout.tab04,null);

mViews.add(view1);
mViews.add(view2);
mViews.add(view3);
mViews.add(view4);

pagerAdapter=new PagerAdapter() {

@Override
public Object instantiateItem(ViewGroup container, int position) {
View view=mViews.get(position);
container.addView(view);
return view;
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(mViews.get(position));
}

@Override
public int getCount() {
return mViews.size();
}

@Override
public boolean isViewFromObject(View view, Object object) {
return view==object;
}
};

viewPager.setAdapter(pagerAdapter);

}

@Override
public void onClick(View view) {
Log.d("--tab--","tab click");
//重置所有的图片
resetImage();
switch (view.getId()){
case R.id.id_tab_weixin:
viewPager.setCurrentItem(0);
mWeiXin.setImageResource(R.drawable.tab_weixin_pressed);
Log.d("--tab--","tab weixin");
break;
case R.id.id_tab_frd:
viewPager.setCurrentItem(1);
mFriend.setImageResource(R.drawable.tab_find_frd_pressed);
Log.d("--tab--","tab friend");
break;
case R.id.id_tab_address:
viewPager.setCurrentItem(2);
mAddress.setImageResource(R.drawable.tab_address_pressed);
Log.d("--tab--","tab address");
break;
case R.id.id_tab_setting:
viewPager.setCurrentItem(3);
mSetting.setImageResource(R.drawable.tab_settings_pressed);
Log.d("--tab--","tab setting");
break;
}
}

/*
* 让所有的图片都变暗
* */
private void resetImage() {
mSetting.setImageResource(R.drawable.tab_settings_normal);
mWeiXin.setImageResource(R.drawable.tab_weixin_normal);
mAddress.setImageResource(R.drawable.tab_address_normal);
mFriend.setImageResource(R.drawable.tab_find_frd_normal);
}
}


使用ViewPager+FragmentPagerAdapter方法实现

思路

同ViewPager实现相同

效果

同ViewPager实现相同

补充

既然这种方式使用的思路和效果和直接使用ViewPager的相同,那么采用FragmenAdapter的方式来实现Tab页面切换有什么好处呢?

首先单纯使用ViewPager时,里面的View是通过LayoutInfater装载进去的,虽然也能够实现和和采用FragmentPagerAdapter一样的效果,但是如果这么做,必然所有的逻辑控制都放在MainActivity当中,对于后期代码的维护十分不利。

使用FragmentPagerAdapter的好处之一就是能够使得当前页面的逻辑处理仅有当前Fragment来承担,相当于把MainActivity里面的事件逻辑分派给了Fragment来处理。这个优点,其实在使用Fragment的时候也能体现出来。

所以说,如果仅仅是页面的展示(如图片轮播),直接使用ViewPager就好了,但如果ViewPager的每个页面中包含比较复杂的逻辑,就应该使用ViewPager+FragmentPagerAdapter的方式来完成Tab页面的切换。

具体代码

xml与ViewPager实现的相同,不再重复。

Java代码:

public class TestActivity3 extends FragmentActivity implements View.OnClickListener {
private ViewPager viewPager;
private FragmentPagerAdapter mAdapter;
private List<Fragment> fragments;
private LinearLayout mTabWeixin;
private LinearLayout mTabFrd;
private LinearLayout mTabAddress;
private LinearLayout mTabSetting;

private ImageButton mWeiXin;
private ImageButton mFriend;
private ImageButton mAddress;
private ImageButton mSetting;
private int select;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.test_ac_3);

initView();

initEvent();
}

private void initEvent() {
mWeiXin.setOnClickListener(this);
mFriend.setOnClickListener(this);
mAddress.setOnClickListener(this);
mSetting.setOnClickListener(this);
}

private void initView() {
//初始化
viewPager= (ViewPager) findViewById(R.id.id_viewpager3);
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);

mWeiXin= (ImageButton) findViewById(R.id.id_tab_weixin_img);
mFriend= (ImageButton) findViewById(R.id.id_tab_frd_img);
mAddress= (ImageButton) findViewById(R.id.id_tab_address_img);
mSetting= (ImageButton) findViewById(R.id.id_tab_setting_img);
fragments=new ArrayList<>();
WeiXinFragment weiXinFragment=new WeiXinFragment();
FriendFragment friendFragment=new FriendFragment();
AddressFragment addressFragment=new AddressFragment();
SettingFragment settingFragment=new SettingFragment();

fragments.add(weiXinFragment);
fragments.add(friendFragment);
fragments.add(addressFragment);
fragments.add(settingFragment);

mAdapter=new FragmentPagerAdapter(getSupportFragmentManager()) {
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}

@Override
public int getCount() {
return fragments.size();
}
};

viewPager.setAdapter(mAdapter);
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

}

@Override
public void onPageSelected(int position) {
resetImage();
switch (position){
case 0:
mWeiXin.setImageResource(R.drawable.tab_weixin_pressed);
viewPager.setCurrentItem(0);
break;
case 1:
mFriend.setImageResource(R.drawable.tab_find_frd_pressed);
viewPager.setCurrentItem(1);
break;
case 2:
mAddress.setImageResource(R.drawable.tab_address_pressed);
viewPager.setCurrentItem(2);
break;
case 3:
mSetting.setImageResource(R.drawable.tab_settings_pressed);
viewPager.setCurrentItem(3);
break;
}
}

@Override
public void onPageScrollStateChanged(int state) {

}
});
}

@Override
public void onClick(View view) {
resetImage();
switch (view.getId()) {
case R.id.id_tab_weixin_img:
setSelect(0);
break;
case R.id.id_tab_frd_img:
setSelect(1);
break;
case R.id.id_tab_address_img:
setSelect(2);
break;
case R.id.id_tab_setting_img:
setSelect(3);
break;
}
}

public void setSelect(int select) {

switch (select){
case 0:
mWeiXin.setImageResource(R.drawable.tab_weixin_pressed);
viewPager.setCurrentItem(0);
break;
case 1:
mFriend.setImageResource(R.drawable.tab_find_frd_pressed);
viewPager.setCurrentItem(1);
break;
case 2:
mAddress.setImageResource(R.drawable.tab_address_normal);
viewPager.setCurrentItem(2);
break;
case 3:
mSetting.setImageResource(R.drawable.tab_settings_pressed);
viewPager.setCurrentItem(3);
break;
}
}

private void resetImage() {
mSetting.setImageResource(R.drawable.tab_settings_normal);
mWeiXin.setImageResource(R.drawable.tab_weixin_normal);
mAddress.setImageResource(R.drawable.tab_address_normal);
mFriend.setImageResource(R.drawable.tab_find_frd_normal);
}

}


使用框架

如果每一次在开发的过程当中都去写一个这样的Tab页面,无疑耗时耗力,当然,对于初学者而言,这种“耗时耗力”能够帮助他们了解效果实现的基本实现原理。

在这里推荐给大家一款比较不错的ViewPager框架:

LuckyJayce/ViewPagerIndicator

里面的介绍比较详细,这里就不多讲了,对这个框架感兴趣的小伙伴可以去github上仔细研读一下~

最后附上下载的源码:github
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  app viewpager