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

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

2016-02-22 11:12 866 查看
转载:http://blog.csdn.net/liweijie_chengxuyuan/article/details/45410617

向原作者致敬。

首先,第一种:

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

他的主要思路是:

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

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





主要代码:这是MainActivity的

[java] view
plain copy

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;// 三个tab标题

private TextView textView_02;

private TextView textView_03;

private List<View> datas;// 需要显示的三个界面

private ImageView tabline;// 标题和界面的分割线

private int widtd_1_3;// 屏幕的三分之一

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)// 从第一页移动到第二页,从第二页移动到第三页,此时的leftMargin应该是越来越大

{

lp.leftMargin = (int) (widtd_1_3 * (currentPageIndex + arg1));

} else

// 从第二页移动到第一页,从第三页移动到第二页,此时的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"));

}

}

布局文件是:

[html] view
plain copy

<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

[html] view
plain copy

<?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="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>

对于显示的三个tab view,比较简单,就yigetextView就不贴出来了。这是第一种方式,这种方式不好的地方是很容易导致代码臃肿,很多的代码都会写在MainActivity中。一般逻辑比较简单的时候才会使用。

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

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

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

MainActivity

[java] view
plain copy

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;// 三个tab标题

private TextView textView_02;

private TextView textView_03;

private ImageView tabline;// 标题和界面的分割线

private int widtd_1_3;// 屏幕的三分之一

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中的布局文件与之前的一样,这里就不贴出来,三个Fragment也是继承v4包下的Fragment,他们的布局文件也是与上面的tab一样。

[html] view
plain copy

<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的效果。

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

MainActivity

[java] view
plain copy

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;// 三个tab标题

private TextView textView_02;

private TextView textView_03;

private ImageView tabline;// 标题和界面的分割线

private int widtd_1_3;// 屏幕的三分之一

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)// 从第一页移动到第二页,从第二页移动到第三页,此时的leftMargin应该是越来越大

{

lp.leftMargin = (int) (widtd_1_3 * (currentPageIndex + arg1));

} else

// 从第二页移动到第一页,从第三页移动到第二页,此时的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://第一页

lp.leftMargin = 0;

textView_01.setTextColor(Color.parseColor("#008000"));

viewPager.setCurrentItem(0);

break;

case R.id.id_second_tv://第二页

lp.leftMargin = widtd_1_3;

textView_02.setTextColor(Color.parseColor("#008000"));

viewPager.setCurrentItem(1);

break;

case R.id.id_three_tv://第三页

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

}

}

其中,他的布局文件和第一个例子的一模一样就不贴出来了,fragment也是很简单的显示一个textview,也不贴出来了。使用Fragment + ViewPager的好处就是他可以有ViewPager 和Fragment的优点,既不会使得MainActivity的代码量很大,同时侧滑时也可以实现改变页面,每个页面的逻辑代码可以写在不同对应的Fragment处。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: