首页 > 代码库 > App主界面Tab实现方法

App主界面Tab实现方法

ViewPager + FragmentPagerAdapter

这里模仿下微信APP界面的实现

国际惯例,先看下效果图:

技术分享  技术分享

activity_main.xml 布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.kevin.viewpager_fragment.MainActivity">

    <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" />

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

</LinearLayout>


top.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="45dp"
    android:background="@mipmap/title_bar"
    android:gravity="center"
    android:orientation="vertical">

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

</LinearLayout>


bottom.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:background="@mipmap/bottom_bar"
    android:orientation="horizontal">

    <LinearLayout
        android:id="@+id/id_tab_weixin"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        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:background="#00000000"
            android:clickable="false"
            android:src="@mipmap/tab_weixin_pressed" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="微信"
            android:textColor="#ffffff" />

    </LinearLayout>

    <LinearLayout
        android:id="@+id/id_tab_frd"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        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:background="#00000000"
            android:clickable="false"
            android:src="@mipmap/tab_find_frd_normal" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="朋友"
            android:textColor="#ffffff" />

    </LinearLayout>

    <LinearLayout
        android:id="@+id/id_tab_address"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        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:background="#00000000"
            android:clickable="false"
            android:src="@mipmap/tab_address_normal" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="通讯录"
            android:textColor="#ffffff" />

    </LinearLayout>

    <LinearLayout
        android:id="@+id/id_tab_setting"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        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:background="#00000000"
            android:clickable="false"
            android:src="@mipmap/tab_settings_normal" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="设置"
            android:textColor="#ffffff" />

    </LinearLayout>

</LinearLayout>


 

tap01.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="match_parent"
    android:orientation="vertical">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="微信"
        android:textSize="30sp"
        android:textStyle="bold" />

</LinearLayout>


tap02.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="match_parent"
    android:orientation="vertical">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="微信2"
        android:textSize="30sp"
        android:textStyle="bold" />

</LinearLayout>


tap03.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="match_parent"
    android:orientation="vertical">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="微信3"
        android:textSize="30sp"
        android:textStyle="bold" />

</LinearLayout>


tap04.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="match_parent"
    android:orientation="vertical">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="微信4"
        android:textSize="30sp"
        android:textStyle="bold" />

</LinearLayout>

 

MainActivity.class 主类。 使用的是FragmentPagerAdapter,这个承载的是一个个Fragment,需要注意的是,这里需要继承自 FragmentActivity 。 上源码吧,看了就知道是多么简单了。

  1 package com.kevin.viewpager_fragment;
  2 
  3 import android.os.Bundle;
  4 import android.support.v4.app.Fragment;
  5 import android.support.v4.app.FragmentActivity;
  6 import android.support.v4.app.FragmentPagerAdapter;
  7 import android.support.v4.view.ViewPager;
  8 import android.view.View;
  9 import android.widget.ImageButton;
 10 import android.widget.LinearLayout;
 11 
 12 import java.util.ArrayList;
 13 import java.util.List;
 14 
 15 import fragment.AddressFragment;
 16 import fragment.FrdFragment;
 17 import fragment.SettingFragment;
 18 import fragment.WeiXinFragment;
 19 
 20 public class MainActivity extends FragmentActivity implements View.OnClickListener {
 21 
 22     private ViewPager mViewPager;
 23     private FragmentPagerAdapter mAdapter;
 24     private List<Fragment> mFragments;
 25 
 26     private LinearLayout mTabWeixin;
 27     private LinearLayout mTabFrd;
 28     private LinearLayout mTabAddress;
 29     private LinearLayout mTabSetting;
 30 
 31     private ImageButton mImgWeixin;
 32     private ImageButton mImgFrd;
 33     private ImageButton mImgAddress;
 34     private ImageButton mImgSetting;
 35 
 36     @Override
 37     protected void onCreate(Bundle savedInstanceState) {
 38         super.onCreate(savedInstanceState);
 39         setContentView(R.layout.activity_main);
 40 
 41         initView();
 42         initEvent();
 43     }
 44 
 45     private void initEvent() {
 46         mTabWeixin.setOnClickListener(this);
 47         mTabFrd.setOnClickListener(this);
 48         mTabAddress.setOnClickListener(this);
 49         mTabSetting.setOnClickListener(this);
 50     }
 51 
 52     private void initView() {
 53         mViewPager = (ViewPager) findViewById(R.id.id_viewpager);
 54 
 55         mTabWeixin = (LinearLayout) findViewById(R.id.id_tab_weixin);
 56         mTabFrd = (LinearLayout) findViewById(R.id.id_tab_frd);
 57         mTabAddress = (LinearLayout) findViewById(R.id.id_tab_address);
 58         mTabSetting = (LinearLayout) findViewById(R.id.id_tab_setting);
 59 
 60         mImgWeixin = (ImageButton) findViewById(R.id.id_tab_weixin_img);
 61         mImgFrd = (ImageButton) findViewById(R.id.id_tab_frd_img);
 62         mImgAddress = (ImageButton) findViewById(R.id.id_tab_address_img);
 63         mImgSetting = (ImageButton) findViewById(R.id.id_tab_setting_img);
 64 
 65         mFragments = new ArrayList<>();
 66         Fragment mTab01 = new WeiXinFragment();
 67         Fragment mTab02 = new FrdFragment();
 68         Fragment mTab03 = new AddressFragment();
 69         Fragment mTab04 = new SettingFragment();
 70         mFragments.add(mTab01);
 71         mFragments.add(mTab02);
 72         mFragments.add(mTab03);
 73         mFragments.add(mTab04);
 74 
 75         mAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) {
 76             @Override
 77             public Fragment getItem(int position) {
 78                 return mFragments.get(position);
 79             }
 80 
 81             @Override
 82             public int getCount() {
 83                 return mFragments.size();
 84             }
 85         };
 86 
 87         mViewPager.setAdapter(mAdapter);
 88 
 89         mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
 90             @Override
 91             public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
 92 
 93             }
 94 
 95             @Override
 96             public void onPageSelected(int position) {
 97                 int currentItem = mViewPager.getCurrentItem();//拿到当前显示的那一个item页面
 98                 setTab(currentItem);
 99             }
100 
101             @Override
102             public void onPageScrollStateChanged(int state) {
103 
104             }
105         });
106     }
107 
108     @Override
109     public void onClick(View v) {
110 
111         switch (v.getId()) {
112             case R.id.id_tab_weixin:
113                 setSelect(0);
114                 break;
115             case R.id.id_tab_frd:
116                 setSelect(1);
117                 break;
118             case R.id.id_tab_address:
119                 setSelect(2);
120                 break;
121             case R.id.id_tab_setting:
122                 setSelect(3);
123                 break;
124             default:
125                 break;
126         }
127     }
128 
129     /*
130     *  切换所有图片为暗色
131     * */
132     private void resetImgs() {
133         mImgWeixin.setImageResource(R.mipmap.tab_weixin_normal);
134         mImgFrd.setImageResource(R.mipmap.tab_find_frd_normal);
135         mImgAddress.setImageResource(R.mipmap.tab_address_normal);
136         mImgSetting.setImageResource(R.mipmap.tab_settings_normal);
137     }
138 
139     private void setSelect(int i) {
140 
141         setTab(i);
142 
143         mViewPager.setCurrentItem(i);
144 
145     }
146 
147     private void setTab(int i) {
148 
149         resetImgs();//调用这个方法,设置所有的tab图片为暗色
150 
151         // 设置图片为亮色
152         //切换内容区域
153         switch (i) {
154             case 0:
155                 mImgWeixin.setImageResource(R.mipmap.tab_weixin_pressed);
156                 break;
157             case 1:
158                 mImgFrd.setImageResource(R.mipmap.tab_find_frd_pressed);
159                 break;
160             case 2:
161                 mImgAddress.setImageResource(R.mipmap.tab_address_pressed);
162                 break;
163             case 3:
164                 mImgSetting.setImageResource(R.mipmap.tab_settings_pressed);
165                 break;
166         }
167     }
168 }


 除了主类,接下来是4个Fragment页面。这里没什么内容,只是加载一个布局。

WeiXinFragment.class :

 1 package fragment;
 2 
 3 import android.os.Bundle;
 4 import android.support.annotation.Nullable;
 5 import android.support.v4.app.Fragment;
 6 import android.view.LayoutInflater;
 7 import android.view.View;
 8 import android.view.ViewGroup;
 9 
10 import com.kevin.viewpager_fragment.R;
11 
12 /**
13  * Created by ${火龙裸先生} on 2016/11/4.
14  * 邮箱:791335000@qq.com
15  */
16 public class WeiXinFragment extends Fragment {
17 
18     @Nullable
19     @Override
20     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
21 
22         View view = inflater.inflate(R.layout.tab01, container, false);
23 
24         return view;
25     }
26 }


FrdFragment.class :

 1 package fragment;
 2 
 3 import android.os.Bundle;
 4 import android.support.annotation.Nullable;
 5 import android.support.v4.app.Fragment;
 6 import android.view.LayoutInflater;
 7 import android.view.View;
 8 import android.view.ViewGroup;
 9 
10 import com.kevin.viewpager_fragment.R;
11 
12 /**
13  * Created by ${火龙裸先生} on 2016/11/4.
14  * 邮箱:791335000@qq.com
15  */
16 public class FrdFragment extends Fragment {
17 
18     @Nullable
19     @Override
20     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
21         View view = inflater.inflate(R.layout.tab02, container, false);
22 
23         return view;
24     }
25 }


AddressFragment.class :

 1 package fragment;
 2 
 3 import android.os.Bundle;
 4 import android.support.annotation.Nullable;
 5 import android.support.v4.app.Fragment;
 6 import android.view.LayoutInflater;
 7 import android.view.View;
 8 import android.view.ViewGroup;
 9 
10 import com.kevin.viewpager_fragment.R;
11 
12 /**
13  * Created by ${火龙裸先生} on 2016/11/4.
14  * 邮箱:791335000@qq.com
15  */
16 public class AddressFragment extends Fragment {
17 
18     @Nullable
19     @Override
20     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
21         View view = inflater.inflate(R.layout.tab03, container, false);
22 
23         return view;
24     }
25 }


Setting.class :

package fragment;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.kevin.viewpager_fragment.R;

/**
 * Created by ${火龙裸先生} on 2016/11/4.
 * 邮箱:791335000@qq.com
 */
public class SettingFragment extends Fragment {

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.tab04, container, false);

        return view;
    }
}

 

就是这些代码了。
总结一下:实现这样功能的实现,不止这一种方法,但是,采用ViewPager + FragmentPagerAdapter, 这里的内容区域是Fragment,所以优势就出来了,Fragment管理自己的布局内部所有控件的事件等各种东西,不需要把代码都冗余在MainActivity.class中, 我们的MainActivity只作为一个调度器,调度显示不同的Fragment、隐藏不同的Fragment。 这样的话,便于后期的复用,也便于后期的维护。  然后,我们用的ViewPager,肯定有ViewPager的优势,如果大家希望能够左右拖动,大家就选择 “ViewPager + FragmentPagerAdapter”作为实现,如果大家不需要左右去拖动,比如QQ,一个页面有LitView或者RecyclerView,并且Item需要“侧滑删除”的一个效果,所以这个时候可能就不需要ViewPager的这样一个效果,这就可以选择直接使用Fragment去实现。也建议尽量去使用Fragment。

App主界面Tab实现方法