[置頂] Android三種實現Tab界面效果的方法,ViewPager + Fragment
來源:程序員人生 發布時間:2015-06-15 08:36:05 閱讀次數:3900次
首先,第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處。
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈