[置頂] Android三種實(shí)現(xiàn)Tab界面效果的方法,ViewPager + Fragment
來(lái)源:程序員人生 發(fā)布時(shí)間:2015-06-15 08:36:05 閱讀次數(shù):3906次
首先,第1種:
他是只使用了ViewPager控件,沒(méi)有使用FragMent。
他的主要思路是:
在xml文件中添加1個(gè)ViewPager控件,然后通過(guò)在JAVA代碼中使用ViewPager的適配器PagerAdapter來(lái)實(shí)現(xiàn)側(cè)滑,然后當(dāng)點(diǎn)擊文字tab的時(shí)候也會(huì)切換不同的條目界面。ViewPager本身就是可以根據(jù)不同的需求顯示動(dòng)態(tài)不同的界面。
主要的效果如圖:他們可以實(shí)現(xiàn)的是點(diǎn)擊文字或側(cè)滑時(shí)候,切換不同界面,文字色彩改變,而且標(biāo)簽條會(huì)隨著點(diǎn)擊或滑動(dòng)移動(dòng)

主要代碼:這是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個(gè)tab標(biāo)題
private TextView textView_02;
private TextView textView_03;
private List<View> datas;// 需要顯示的3個(gè)界面
private ImageView tabline;// 標(biāo)題和界面的分割線
private int widtd_1_3;// 屏幕的3分之1
private int currentPageIndex = 0;// 當(dāng)前頁(yè)
@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)
* 當(dāng)用戶正在滑動(dòng)viewpager的時(shí)候觸發(fā)改事件
*/
@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頁(yè)移動(dòng)到第2頁(yè),從第2頁(yè)移動(dòng)到第3頁(yè),此時(shí)的leftMargin應(yīng)當(dāng)是愈來(lái)愈大
{
lp.leftMargin = (int) (widtd_1_3 * (currentPageIndex + arg1));
} else
// 從第2頁(yè)移動(dòng)到第1頁(yè),從第3頁(yè)移動(dòng)到第2頁(yè),此時(shí)的leftMargin應(yīng)當(dāng)是愈來(lái)愈小
{
lp.leftMargin = (int) (widtd_1_3 * (currentPageIndex - 1 + arg1));
}
tabline.setLayoutParams(lp);
}
/* (non-Javadoc)
* 當(dāng)viewpager不再滑動(dòng)的時(shí)候觸發(fā)改事件
*/
@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顯示的界面時(shí)候先重置文字色彩
*/
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>
對(duì)顯示的3個(gè)tab view,比較簡(jiǎn)單,就yigetextView就不貼出來(lái)了。這是第1種方式,這類方式不好的地方是很容易致使代碼臃腫,很多的代碼都會(huì)寫在MainActivity中。1般邏輯比較簡(jiǎn)單的時(shí)候才會(huì)使用。
第2種實(shí)現(xiàn)方式:使用單純的Fragment,類似于QQ,當(dāng)在內(nèi)容界面滑動(dòng)的時(shí)候不會(huì)出現(xiàn)界面移動(dòng),只有點(diǎn)擊按鈕的時(shí)候android、才會(huì)切換切面。大家使用Fragment的時(shí)候需要注意的1點(diǎn)就是假設(shè)你使用V4包下的Fragment就1直使用該包下的不要使用app下的,反之亦然。
單純使用Fragment的時(shí)候不能實(shí)現(xiàn)側(cè)滑,然后在MainActivity的布局文件中需要使用到1個(gè)FramLayout,由于我是使用V4包下的Fragment,所以需要繼承FragmentActivity,這樣才能取得FragmentManager,通過(guò)getSupportFragmentManage,假設(shè)是使用app下的Fragment,則可以通過(guò)getFragmentManager()來(lái)取得Fragment管理器。
下面是主要實(shí)現(xiàn)代碼:實(shí)現(xiàn)的效果與上面的類似,只是只有點(diǎn)擊文字tab的時(shí)候界面才會(huì)改變,標(biāo)簽條也會(huì)隨之改變。
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個(gè)tab標(biāo)題
private TextView textView_02;
private TextView textView_03;
private ImageView tabline;// 標(biāo)題和界面的分割線
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;
}
}
/**實(shí)現(xiàn)切換不同的Fragment
* @param i 點(diǎn)擊的第幾個(gè)按鈕
*/
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時(shí)候隱藏之前的所有可能顯示的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顯示的界面時(shí)候先重置文字色彩
*/
private void resetTextColor()
{
textView_01.setTextColor(Color.parseColor("#000000"));
textView_02.setTextColor(Color.parseColor("#000000"));
textView_03.setTextColor(Color.parseColor("#000000"));
}
}
主布局文件,其中Include中的布局文件與之前的1樣,這里就不貼出來(lái),3個(gè)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>
這樣就完成類似于手機(jī)qq的界面切換,他的不好的地方就是側(cè)滑內(nèi)容區(qū)域的時(shí)候不能改變,只有點(diǎn)擊文字按鈕才行,但是他的好處是可以為Activity分擔(dān)代碼,有時(shí)候可使用類似于QQ的那種側(cè)滑Item的效果。
第3種:使用Fragment + ViewPager實(shí)現(xiàn),他的大致效果是點(diǎn)擊文字tab或是側(cè)滑,都可以實(shí)現(xiàn)頁(yè)面的改變。類似于第1個(gè)的效果,但是使用了Fragment。我這里還是使用了V4包下的Fragment。他需要使用到1個(gè)適配器是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個(gè)tab標(biāo)題
private TextView textView_02;
private TextView textView_03;
private ImageView tabline;// 標(biāo)題和界面的分割線
private int widtd_1_3;// 屏幕的3分之1
private List<Fragment> datas;
private ViewPager viewPager;
private FragmentPagerAdapter adapter;//使用該adapter,實(shí)現(xiàn)fragment和viewpager的聯(lián)系
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頁(yè)移動(dòng)到第2頁(yè),從第2頁(yè)移動(dòng)到第3頁(yè),此時(shí)的leftMargin應(yīng)當(dāng)是愈來(lái)愈大
{
lp.leftMargin = (int) (widtd_1_3 * (currentPageIndex + arg1));
} else
// 從第2頁(yè)移動(dòng)到第1頁(yè),從第3頁(yè)移動(dòng)到第2頁(yè),此時(shí)的leftMargin應(yīng)當(dāng)是愈來(lái)愈小
{
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)
* 實(shí)現(xiàn)點(diǎn)擊文字ta的時(shí)候改變不同的viewpager顯示出來(lái),同時(shí)更改標(biāo)簽條的位置
*/
@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頁(yè)
lp.leftMargin = 0;
textView_01.setTextColor(Color.parseColor("#008000"));
viewPager.setCurrentItem(0);
break;
case R.id.id_second_tv://第2頁(yè)
lp.leftMargin = widtd_1_3;
textView_02.setTextColor(Color.parseColor("#008000"));
viewPager.setCurrentItem(1);
break;
case R.id.id_three_tv://第3頁(yè)
lp.leftMargin = widtd_1_3 * 2;
textView_03.setTextColor(Color.parseColor("#008000"));
viewPager.setCurrentItem(2);
break;
}
tabline.setLayoutParams(lp);
}
/**
* 每次需要改變viewpager顯示的界面時(shí)候先重置文字色彩
*/
private void resetTextColor()
{
textView_01.setTextColor(Color.parseColor("#000000"));
textView_02.setTextColor(Color.parseColor("#000000"));
textView_03.setTextColor(Color.parseColor("#000000"));
}
}
其中,他的布局文件和第1個(gè)例子的1模1樣就不貼出來(lái)了,fragment也是很簡(jiǎn)單的顯示1個(gè)textview,也不貼出來(lái)了。使用Fragment + ViewPager的好處就是他可以有ViewPager 和Fragment的優(yōu)點(diǎn),既不會(huì)使得MainActivity的代碼量很大,同時(shí)側(cè)滑時(shí)也能夠?qū)崿F(xiàn)改變頁(yè)面,每一個(gè)頁(yè)面的邏輯代碼可以寫在不同對(duì)應(yīng)的Fragment處。
生活不易,碼農(nóng)辛苦
如果您覺(jué)得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)