[置顶] Android三种实现Tab界面效果的方法,ViewPager + Fragment
来源:程序员人生 发布时间:2015-06-15 08:36:05 阅读次数:3709次
首先,第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处。
生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠