程序员人生 网站导航

[置顶] Android三种实现Tab界面效果的方法,ViewPager + Fragment

栏目:综合技术时间:2015-06-15 08:36:05

首先,第1种:

他是只使用了ViewPager控件,没有使用FragMent。

他的主要思路是:

在xml文件中添加1个ViewPager控件,然后通过在JAVA代码中使用ViewPager的适配器PagerAdapter来实现侧滑,然后当点击文字tab的时候也会切换不同的条目界面。ViewPager本身就是可以根据不同的需求显示动态不同的界面。

主要的效果如图:他们可以实现的是点击文字或侧滑时候,切换不同界面,文字色彩改变,而且标签条会随着点击或滑动移动

        

主要代码:这是MainActivity的

import android.app.Activity; import android.content.Context; import android.graphics.Color; import android.os.Bundle; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager.OnPageChangeListener; import android.util.DisplayMetrics; import android.view.Display; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; public class MainActivity extends Activity implements OnClickListener { private ViewPager viewPager; private TextView textView_01;// 3个tab标题 private TextView textView_02; private TextView textView_03; private List<View> datas;// 需要显示的3个界面 private ImageView tabline;// 标题和界面的分割线 private int widtd_1_3;// 屏幕的3分之1 private int currentPageIndex = 0;// 当前页 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); intiView(); intiEvent(); initTabline(); textView_01.setTextColor(Color.parseColor("#008000"));// 首次显示的默许界面条目 viewPager.setCurrentItem(0); } /** * 初始化tabline */ private void initTabline() { Display display = getWindow().getWindowManager().getDefaultDisplay(); DisplayMetrics outMetrics = new DisplayMetrics(); display.getMetrics(outMetrics); widtd_1_3 = outMetrics.widthPixels / 3; LayoutParams params = tabline.getLayoutParams(); params.width = widtd_1_3; tabline.setLayoutParams(params); } /** * 初始化事件处理 */ private void intiEvent() { textView_01.setOnClickListener(this); textView_02.setOnClickListener(this); textView_03.setOnClickListener(this); viewPager.setOnPageChangeListener(new MyOnPageChangeListener()); } /** * 初始化控件 */ private void intiView() { viewPager = (ViewPager) this.findViewById(R.id.viewpager); textView_01 = (TextView) this.findViewById(R.id.id_first_tv); textView_02 = (TextView) this.findViewById(R.id.id_second_tv); textView_03 = (TextView) this.findViewById(R.id.id_three_tv); datas = new ArrayList<View>(); LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); View view_01 = inflater.inflate(R.layout.tab01, null); View view_02 = inflater.inflate(R.layout.tab02, null); View view_03 = inflater.inflate(R.layout.tab03, null); datas.add(view_01); datas.add(view_02); datas.add(view_03); PagerAdapter adapetr = new PagerAdapter() { @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView(datas.get(position)); } @Override public Object instantiateItem(ViewGroup container, int position) { View v = datas.get(position); container.addView(v); return v; } @Override public int getCount() { return datas.size(); } @Override public boolean isViewFromObject(View arg0, Object arg1) { return arg0 == arg1; } }; viewPager.setAdapter(adapetr); tabline = (ImageView) this.findViewById(R.id.id_imageView); } class MyOnPageChangeListener implements OnPageChangeListener { @Override public void onPageScrollStateChanged(int arg0) { } /* (non-Javadoc) * 当用户正在滑动viewpager的时候触发改事件 */ @Override public void onPageScrolled(int arg0, float arg1, int arg2) { System.out.println(arg0 + "=arg0 " + arg1 + "=arg1 " + arg2 + "arg2 " + currentPageIndex + "currentPageIndex"); LinearLayout.LayoutParams lp = (android.widget.LinearLayout.LayoutParams) tabline .getLayoutParams(); if (currentPageIndex == arg0)// 从第1页移动到第2页,从第2页移动到第3页,此时的leftMargin应当是愈来愈大 { lp.leftMargin = (int) (widtd_1_3 * (currentPageIndex + arg1)); } else // 从第2页移动到第1页,从第3页移动到第2页,此时的leftMargin应当是愈来愈小 { lp.leftMargin = (int) (widtd_1_3 * (currentPageIndex - 1 + arg1)); } tabline.setLayoutParams(lp); } /* (non-Javadoc) * 当viewpager不再滑动的时候触发改事件 */ @Override public void onPageSelected(int arg0) { resetTextColor(); switch (arg0) { case 0: textView_01.setTextColor(Color.parseColor("#008000")); break; case 1: textView_02.setTextColor(Color.parseColor("#008000")); break; case 2: textView_03.setTextColor(Color.parseColor("#008000")); break; } currentPageIndex = arg0; } } // "#008000" @Override public void onClick(View v) { resetTextColor(); switch (v.getId()) { case R.id.id_first_tv: textView_01.setTextColor(Color.parseColor("#008000")); if (null != viewPager) { viewPager.setCurrentItem(0); } break; case R.id.id_second_tv: textView_02.setTextColor(Color.parseColor("#008000")); if (null != viewPager) { viewPager.setCurrentItem(1); } break; case R.id.id_three_tv: textView_03.setTextColor(Color.parseColor("#008000")); if (null != viewPager) { viewPager.setCurrentItem(2); } break; } } /** * 每次需要改变viewpager显示的界面时候先重置文字色彩 */ private void resetTextColor() { textView_01.setTextColor(Color.parseColor("#000000")); textView_02.setTextColor(Color.parseColor("#000000")); textView_03.setTextColor(Color.parseColor("#000000")); } }
布局文件是:

<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.example.mytabdemo_01.MainActivity" > <include layout="@layout/top_layout" /> <ImageView android:id="@+id/id_imageView" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/tabline" /> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="match_parent" > </android.support.v4.view.ViewPager> </LinearLayout>
还有文字tab

<?xml version="1.0" encoding="utf⑻"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="50dp" android:orientation="horizontal" > <TextView android:textColor="#000000" android:id="@+id/id_first_tv" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:text="first" android:textSize="20sp" android:textStyle="bold" /> <TextView android:textColor="#000000" android:id="@+id/id_second_tv" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:text="second" android:textSize="20sp" android:textStyle="bold" /> <TextView android:textColor="#000000" android:id="@+id/id_three_tv" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:text="three" android:textSize="20sp" android:textStyle="bold" /> </LinearLayout>
对显示的3个tab view,比较简单,就yigetextView就不贴出来了。这是第1种方式,这类方式不好的地方是很容易致使代码臃肿,很多的代码都会写在MainActivity中。1般逻辑比较简单的时候才会使用。

第2种实现方式:使用单纯的Fragment,类似于QQ,当在内容界面滑动的时候不会出现界面移动,只有点击按钮的时候android、才会切换切面。大家使用Fragment的时候需要注意的1点就是假设你使用V4包下的Fragment就1直使用该包下的不要使用app下的,反之亦然。

单纯使用Fragment的时候不能实现侧滑,然后在MainActivity的布局文件中需要使用到1个FramLayout,由于我是使用V4包下的Fragment,所以需要继承FragmentActivity,这样才能取得FragmentManager,通过getSupportFragmentManage,假设是使用app下的Fragment,则可以通过getFragmentManager()来取得Fragment管理器。

下面是主要实现代码:实现的效果与上面的类似,只是只有点击文字tab的时候界面才会改变,标签条也会随之改变。

MainActivity

import android.graphics.Color; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.util.DisplayMetrics; import android.view.Display; import android.view.View; import android.view.Window; import android.view.View.OnClickListener; import android.view.ViewGroup.LayoutParams; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; public class MainActivity extends FragmentActivity implements OnClickListener { private TextView textView_01;// 3个tab标题 private TextView textView_02; private TextView textView_03; private ImageView tabline;// 标题和界面的分割线 private int widtd_1_3;// 屏幕的3分之1 private Fragment firstFragment; private Fragment secondFragment; private Fragment threeFragment; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); initView(); initEvent(); initTabline(); select(0); } private void initTabline() { Display display = getWindow().getWindowManager().getDefaultDisplay(); DisplayMetrics outMetrics = new DisplayMetrics(); display.getMetrics(outMetrics); widtd_1_3 = outMetrics.widthPixels / 3; LayoutParams lp = tabline.getLayoutParams(); lp.width = widtd_1_3; tabline.setLayoutParams(lp); } private void initEvent() { textView_01.setOnClickListener(this); textView_02.setOnClickListener(this); textView_03.setOnClickListener(this); } private void initView() { textView_01 = (TextView) this.findViewById(R.id.id_first_tv); textView_02 = (TextView) this.findViewById(R.id.id_second_tv); textView_03 = (TextView) this.findViewById(R.id.id_three_tv); tabline = (ImageView) this.findViewById(R.id.id_imageView); } @Override public void onClick(View v) { resetTextColor(); switch (v.getId()) { case R.id.id_first_tv: textView_01.setTextColor(Color.parseColor("#008000")); select(0); break; case R.id.id_second_tv: textView_02.setTextColor(Color.parseColor("#008000")); select(1); break; case R.id.id_three_tv: textView_03.setTextColor(Color.parseColor("#008000")); select(2); break; } } /**实现切换不同的Fragment * @param i 点击的第几个按钮 */ private void select(int i) { FragmentManager fm = getSupportFragmentManager(); FragmentTransaction transaction = fm.beginTransaction(); LinearLayout.LayoutParams lp = (android.widget.LinearLayout.LayoutParams) tabline .getLayoutParams(); hideFragment(transaction); switch (i) { case 0: if (firstFragment == null) { firstFragment = new FirstFragment(); transaction.add(R.id.id_fragment, firstFragment); } else { transaction.show(firstFragment); lp.leftMargin = 0; } break; case 1: if (secondFragment == null) { secondFragment = new SecondFragment(); transaction.add(R.id.id_fragment, secondFragment); } else { transaction.show(secondFragment); lp.leftMargin = widtd_1_3; } break; case 2: if (threeFragment == null) { threeFragment = new ThreeFragment(); transaction.add(R.id.id_fragment, threeFragment); } else { transaction.show(secondFragment); lp.leftMargin = widtd_1_3 * 2; } break; } transaction.commit(); tabline.setLayoutParams(lp); } /** * 用于每显示不同的Fragment时候隐藏之前的所有可能显示的Fragment * @param transaction * 事物 */ private void hideFragment(FragmentTransaction transaction) { if (firstFragment != null) { transaction.hide(firstFragment); } if (secondFragment != null) { transaction.hide(secondFragment); } if (threeFragment != null) { transaction.hide(threeFragment); } } /** * 每次需要改变viewpager显示的界面时候先重置文字色彩 */ private void resetTextColor() { textView_01.setTextColor(Color.parseColor("#000000")); textView_02.setTextColor(Color.parseColor("#000000")); textView_03.setTextColor(Color.parseColor("#000000")); } }
主布局文件,其中Include中的布局文件与之前的1样,这里就不贴出来,3个Fragment也是继承v4包下的Fragment,他们的布局文件也是与上面的tab1样。

<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.example.mytabdemo_01.MainActivity" > <include layout="@layout/top_layout" /> <ImageView android:id="@+id/id_imageView" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/tabline" /> <FrameLayout android:id="@+id/id_fragment" android:layout_width="match_parent" android:layout_height="match_parent" > </FrameLayout> </LinearLayout>
这样就完成类似于手机qq的界面切换,他的不好的地方就是侧滑内容区域的时候不能改变,只有点击文字按钮才行,但是他的好处是可以为Activity分担代码,有时候可使用类似于QQ的那种侧滑Item的效果。

第3种:使用Fragment + ViewPager实现,他的大致效果是点击文字tab或是侧滑,都可以实现页面的改变。类似于第1个的效果,但是使用了Fragment。我这里还是使用了V4包下的Fragment。他需要使用到1个适配器是FragmentPagerAdapter适配器。

MainActivity

import java.util.ArrayList; import java.util.List; import android.graphics.Color; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager.OnPageChangeListener; import android.util.DisplayMetrics; import android.view.Display; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup.LayoutParams; import android.view.Window; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; public class MainActivity extends FragmentActivity implements OnClickListener { private TextView textView_01;// 3个tab标题 private TextView textView_02; private TextView textView_03; private ImageView tabline;// 标题和界面的分割线 private int widtd_1_3;// 屏幕的3分之1 private List<Fragment> datas; private ViewPager viewPager; private FragmentPagerAdapter adapter;//使用该adapter,实现fragment和viewpager的联系 int currentPageIndex = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); initView(); initEvent(); initTabline(); } private void initTabline() { Display display = getWindow().getWindowManager().getDefaultDisplay(); DisplayMetrics outMetrics = new DisplayMetrics(); display.getMetrics(outMetrics); widtd_1_3 = outMetrics.widthPixels / 3; LayoutParams lp = tabline.getLayoutParams(); lp.width = widtd_1_3; tabline.setLayoutParams(lp); } private void initEvent() { textView_01.setOnClickListener(this); textView_02.setOnClickListener(this); textView_03.setOnClickListener(this); viewPager.setOnPageChangeListener(new MyOnPageChangeListener()); } private void initView() { textView_01 = (TextView) this.findViewById(R.id.id_first_tv); textView_02 = (TextView) this.findViewById(R.id.id_second_tv); textView_03 = (TextView) this.findViewById(R.id.id_three_tv); tabline = (ImageView) this.findViewById(R.id.id_imageView); viewPager = (ViewPager) this.findViewById(R.id.viewpager); FirstFragment firstFragment = new FirstFragment(); SecondFragment secondFragment = new SecondFragment(); ThreeFragment threeFragment = new ThreeFragment(); datas = new ArrayList<Fragment>(); datas.add(firstFragment); datas.add(secondFragment); datas.add(threeFragment); adapter = new FragmentPagerAdapter(getSupportFragmentManager()) { @Override public int getCount() { return datas.size(); } @Override public Fragment getItem(int arg0) { return datas.get(arg0); } }; viewPager.setAdapter(adapter); } class MyOnPageChangeListener implements OnPageChangeListener { @Override public void onPageScrollStateChanged(int arg0) { } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { LinearLayout.LayoutParams lp = (android.widget.LinearLayout.LayoutParams) tabline .getLayoutParams(); if (currentPageIndex == arg0)// 从第1页移动到第2页,从第2页移动到第3页,此时的leftMargin应当是愈来愈大 { lp.leftMargin = (int) (widtd_1_3 * (currentPageIndex + arg1)); } else // 从第2页移动到第1页,从第3页移动到第2页,此时的leftMargin应当是愈来愈小 { lp.leftMargin = (int) (widtd_1_3 * (currentPageIndex - 1 + arg1)); } tabline.setLayoutParams(lp); } @Override public void onPageSelected(int arg0) { resetTextColor(); switch (arg0) { case 0: textView_01.setTextColor(Color.parseColor("#008000")); break; case 01: textView_02.setTextColor(Color.parseColor("#008000")); break; case 2: textView_03.setTextColor(Color.parseColor("#008000")); } currentPageIndex = arg0; } } /* (non-Javadoc) * 实现点击文字ta的时候改变不同的viewpager显示出来,同时更改标签条的位置 */ @Override public void onClick(View v) { LinearLayout.LayoutParams lp = (android.widget.LinearLayout.LayoutParams) tabline .getLayoutParams(); resetTextColor(); switch (v.getId()) { case R.id.id_first_tv://第1页 lp.leftMargin = 0; textView_01.setTextColor(Color.parseColor("#008000")); viewPager.setCurrentItem(0); break; case R.id.id_second_tv://第2页 lp.leftMargin = widtd_1_3; textView_02.setTextColor(Color.parseColor("#008000")); viewPager.setCurrentItem(1); break; case R.id.id_three_tv://第3页 lp.leftMargin = widtd_1_3 * 2; textView_03.setTextColor(Color.parseColor("#008000")); viewPager.setCurrentItem(2); break; } tabline.setLayoutParams(lp); } /** * 每次需要改变viewpager显示的界面时候先重置文字色彩 */ private void resetTextColor() { textView_01.setTextColor(Color.parseColor("#000000")); textView_02.setTextColor(Color.parseColor("#000000")); textView_03.setTextColor(Color.parseColor("#000000")); } }
其中,他的布局文件和第1个例子的1模1样就不贴出来了,fragment也是很简单的显示1个textview,也不贴出来了。使用Fragment + ViewPager的好处就是他可以有ViewPager 和Fragment的优点,既不会使得MainActivity的代码量很大,同时侧滑时也能够实现改变页面,每一个页面的逻辑代码可以写在不同对应的Fragment处。

------分隔线----------------------------
------分隔线----------------------------

最新技术推荐