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 }
SettingFragment.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。