Android進階:步驟四:Viewpager的基本使用
借鑑:https://blog.csdn.net/weixin_39251617/article/details/79399592
大致內容:
ViewPager實踐的三種效果
- 1. 引導介面 ViewPager
- 2. FragmentPageAdapter
- 3. 常見Tab切換效果
一、簡介
Viewpager,檢視翻頁工具,提供了多頁面切換的效果。Android 3.0後引入的一個UI控制元件,位於v4包中。低版本使用需要匯入v4包,但是現在我們開發的APP一般不再相容3.0及以下的系統版本,另外現在大多數使用Android studio進行開發,預設匯入v7包,v7包含了v4,所以不用導包,越來越方便了。
Viewpager使用起來就是我們通過建立adapter給它填充多個view,左右滑動時,切換不同的view。Google官方是建議我們使用Fragment來填充ViewPager的,這樣 可以更加方便的生成每個Page,以及管理每個Page的生命週期
二、基本使用
1.xml(主佈局main_acitivity.xml作為容器)
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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" tools:context=".MainActivity"> <android.support.v4.view.ViewPager android:id="@+id/id_viewpager" android:layout_width="match_parent" android:layout_height="match_parent"> </android.support.v4.view.ViewPager> </RelativeLayout>
2.pager佈局(可以複用一個,也可以建立多個)我這裡寫了first...four四個佈局都是一樣的
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:text="first" android:textSize="30dp" /> </RelativeLayout>
3.MainAcitivity中
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import com.demo.viewpagerdemo.adapter.MyPagerAdapter;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
//全域性變數
private ViewPager mViewPager;
private int[] mLayoutIDs = {//每一個檢視id陣列
R.layout.view_first,
R.layout.view_second,
R.layout.view_third,
R.layout.view_four
};
private List<View> views;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mViewPager = findViewById(R.id.id_viewpager);
//初始化資料即檢視
views = new ArrayList<>();
for (int index = 0; index < mLayoutIDs.length; index++) {
//1.構造檢視
View view = getLayoutInflater().inflate(mLayoutIDs[index], null);
views.add(view);
// //2.也可以直接用圖片檢視
// ImageView imageView = new ImageView(this);
// imageView.setImageResource(R.mipmap.ic_launcher);
// views.add(imageView);
}
//設定adapter
mViewPager.setAdapter(new MyPagerAdapter(this, views));
//將頁面快取不回收
mViewPager.setOffscreenPageLimit(4);
}
}
總結三步:
1.設定檢視源(你要展示的檢視)
2.構造介面卡(自定義MyPageraAdapter基礎PagerAdapter)
3. 設定介面卡(檢視源和元件的連線)
4.自定義介面卡
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;
import java.util.List;
public class MyPagerAdapter extends PagerAdapter {
//全域性變數
private Context context;
private List<View> views;
/**
* 建構函式
* 傳入上下文和檢視集合地址
*/
public MyPagerAdapter(Context context, List<View> views) {
//當前定義的context和views指向傳進來的
this.context = context;
this.views = views;
}
/**
* 1.獲取view的數量
*
* @return
*/
@Override
public int getCount() {
return views.size();
}
/**
* instantiateItem方法中返回的檢視是否等於這個物件
* 以便下次再利用
*/
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view == object;
}
/**
* 例項化檢視
*
* @param container
* @param position
* @return
*/
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
View child = views.get(position);//找到該位置的檢視
container.addView(child);//將檢視加進去
return child;//返回
}
/**
* 釋放檢視
* @param container 檢視容器
* @param position 位置
* @param object 物件
*/
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
container.removeView(views.get(position));
}
}
PageAdapter 必須重寫的四個函式:
- int getCount() 獲取檢視數量
- boolean isViewFromObject(View view, Object object) 判斷檢視是否為當前物件,如果是即可以重新利用
- void destroyItem(ViewGroup container, int position,Object object) 釋放檢視避免oom
- Object instantiateItem(ViewGroup container, int position) 例項化檢視
簡單的效果
直接載入圖片的做法:不需要建立佈局
views = new ArrayList<>();
for (int index = 0; index < mLayoutIDs.length; index++) {
//直接用圖片檢視
//1.新建一個圖片
ImageView imageView = new ImageView(this);
//2.給圖片設定圖片資源,如果想載入不同的圖片,可以參考載入不同佈局,設定一個圖片陣列
imageView.setImageResource(R.mipmap.ic_launcher);
//3.新增到list裡面去
views.add(imageView);
}
三、使用ViewPager實現引導頁
1.新增底部的引導點
在主佈局xml中新增一個引導點的容器Linearlayout佈局設定id為dot_layout
<!--下方引導點的容器-->
<LinearLayout
android:id="@+id/dot_layout"
android:layout_width="120dp"
android:layout_height="30dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="30dp"
android:gravity="center"
android:orientation="horizontal">
</LinearLayout>
2.動態新增引導點
import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; import com.demo.viewpagerdemo.adapter.MyPagerAdapter; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { //全域性變數 private ViewPager mViewPager; private int[] mLayoutIDs = {//每一個檢視id陣列 R.layout.view_first, R.layout.view_second, R.layout.view_third, R.layout.view_four }; private List<View> views; //裝dot的容器 private ViewGroup mDotViewGroup; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mViewPager = findViewById(R.id.id_viewpager); //初始化裝dot的容器 mDotViewGroup = findViewById(R.id.dot_layout); //初始化資料即檢視 views = new ArrayList<>(); for (int index = 0; index < mLayoutIDs.length; index++) { //1.構造檢視 View view = getLayoutInflater().inflate(mLayoutIDs[index], null); views.add(view); //// //2.也可以直接用圖片檢視 // ImageView imageView = new ImageView(this); // imageView.setImageResource(R.mipmap.ic_launcher); // views.add(imageView); //給dot檢視新增圖片 ImageView dot = new ImageView(this); dot.setImageResource(R.mipmap.ic_launcher); //給每個dot通過程式碼來設定每個圖片的引數 寬高為20 LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(20, 20); layoutParams.leftMargin = 20;//每個距離左邊20 dot.setLayoutParams(layoutParams);//將這個程式碼的引數新增到dot這個圖片裡面 dot.setEnabled(false);//不可點選 //新增到dot檢視集合中才能顯示出來 mDotViewGroup.addView(dot); } //設定adapter mViewPager.setAdapter(new MyPagerAdapter(this, views)); //將頁面快取不回收 mViewPager.setOffscreenPageLimit(4); } }
增加一內容
1.設定dot的容器就是上面增加的linearlayout
//裝dot的容器
private ViewGroup mDotViewGroup;
2.oncreate中初始化
//初始化裝dot的容器
mDotViewGroup = findViewById(R.id.dot_layout);
3.在迴圈中動態新增(有多少個頁面就有多少個點)
for (int index = 0; index < mLayoutIDs.length; index++) {
//1.構造檢視
View view = getLayoutInflater().inflate(mLayoutIDs[index], null);
views.add(view);
//給dot檢視新增圖片
ImageView dot = new ImageView(this);
dot.setImageResource(R.mipmap.ic_launcher);
//給每個dot通過程式碼來設定每個圖片的引數 寬高為20
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(20, 20);
layoutParams.leftMargin = 20;//每個距離左邊20
dot.setLayoutParams(layoutParams);//將這個程式碼的引數新增到dot這個圖片裡面
dot.setEnabled(false);//不可點選
//新增到dot檢視集合中才能顯示出來
mDotViewGroup.addView(dot);
}
實現效果:發現只是出現了響應的點而已,並不會隨著頁面顯示而改變,怎麼辦?往下看3
3.實現翻頁的監聽
1. 設定方法
addOnPageChangeListener()
2. 翻頁監聽介面
ViewPager.OnPageChangeListener
3. 重寫方法
onPageScrolled(int position, float positionOffset, int positionOffsetPixels) //頁面滑動狀態停止前一直呼叫(滑動中)
position:當前點選滑動頁面的位置
positionOffset:當前頁面偏移的百分比
positionOffsetPixels:當前頁面偏移的畫素位置
onPageSelected(int position) //滑動後顯示的頁面和滑動前不同,呼叫(滑動的頁面)
position:選中顯示頁面的位置
onPageScrollStateChanged(int state) //頁面狀態改變時呼叫(滑動的狀態改變)
state:當前頁面的狀態
SCROLL_STATE_IDLE:空閒狀態
SCROLL_STATE_DRAGGING:滑動狀態
SCROLL_STATE_SETTLING:滑動後滑翔的狀態
4. 使用
1.定義一個集合裝要顯示的dot
//設定dot的檢視資源集合
private List<ImageView> mDotViews = new ArrayList<>();
2.在上面的for迴圈中將定義好的dot裝進去
//將dot放到點集合中
mDotViews.add(dot);
3.設定滑動監聽
只用到了OnpageSelected方法
/**
* 滑動監聽
*/
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
//頁面在滑動中
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
//選中的頁面
@Override
public void onPageSelected(int position) {
setDotView(position);
}
//頁面的狀態
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
setDotView的方法:引數是position當前的頁面的位置,如果等於原來的圖片的位置,就要更換成另外一張的圖片
private void setDotView(int position) {
for (int index = 0; index < mDotViews.size(); index++) {
//當頁面滑到對應位置的圖片時,對應位置的圖片做出改變
//使用的是三目運算子 如果==好為true執行第一個,否則執行第二個
mDotViews.get(index).setImageResource(
position == index ? R.drawable.dot : R.mipmap.ic_launcher);
}
}
4.設定頁面初始的位置在oncreate方法中
//設定初始是展示第一頁的
mViewPager.setCurrentItem(0);
//對應的dot也是要顯示出來
setDotView(0);
實現效果:
5.拓展 翻頁動畫:開源框架ViewPagerTransforms
要想實現選款的翻頁效果
裡面有十幾種翻頁動畫,基本夠用了
Github地址:ViewPagerTransforms
四、使用ViewPager配合Fragment
參考:https://blog.csdn.net/weixin_39251617/article/details/79399592
與Fragment結合使用其實也一樣,只是用Fragment代替原先的View,填充Viewpager;然後就是Adapter不一樣,配合Fragment使用的有兩個Adapter:
FragmentPagerAdapter和FragmentStatePagerAdapter。
相同點:
FragmentPagerAdapter和FragmentStatePagerAdapter都繼承自PagerAdapter
不同點:
解除安裝不再需fragment時,各自採用的處理方法有所不同
1.FragmentStatePagerAdapter會銷燬不需要的fragment。
事務提交後, activity的FragmentManager中的fragment會被徹底移除。 FragmentStatePagerAdapter類名中的“state”表明:在銷燬fragment時,可在onSaveInstanceState(Bundle)方法中儲存fragment的Bundle資訊。使用者切換回來時,儲存的例項狀態可用來恢復生成新的fragment
2.FragmentPagerAdapter有不同的做法。
對於不再需要的fragment, FragmentPagerAdapter會選擇呼叫事務的detach(Fragment)方法來處理它,而非remove(Fragment)方法。也就是說, FragmentPagerAdapter只是銷燬了fragment的檢視, fragment例項還保留在FragmentManager中。因此,FragmentPagerAdapter建立的fragment永遠不會被銷燬
也就是:在destroyItem()方法中,FragmentStatePagerAdapter呼叫的是remove()方法,適用於頁面較多的情況;FragmentPagerAdapter呼叫的是detach()方法,適用於頁面較少的情況。但是有頁面資料需要重新整理的情況,不管是頁面少還是多,還是要用FragmentStatePagerAdapter,否則頁面會因為沒有重建得不到重新整理
3.簡單使用
1.主頁面佈局xml fragment_viewpager.xml
<?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="match_parent">
<android.support.v4.view.ViewPager
android:id="@+id/id_fragment_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
</LinearLayout>
2.fragment的fragment_test.xml佈局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:text="我是fragment"
android:textSize="36dp" />
</RelativeLayout>
3.Fragment建立的程式碼 TestFragment.java
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class TestFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_test, null);
return view;
}
}
4.主介面程式碼TabViewPagerAdapter.java
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
public class TabViewPagerAdapter extends AppCompatActivity {
private ViewPager viewPager;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_viewpager);
viewPager = findViewById(R.id.id_fragment_viewpager);
//設定 介面卡
viewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager())
{
@Override
public Fragment getItem(int position) {
//這是自定義的fragment
return new TestFragment();
}
@Override
public int getCount() {
//定義數量
return 4;
}
});
}
}
這樣就可以實現了
效果:
5.給fragment傳值
每次的頁面都是一樣的,怎麼在不同的頁面顯示不同的東西呢?
簡單實現:將每個fragment裡面的textview顯示當前的position
1.在FragmentPagerAdapter的getItem(int position)將position傳到Fragment裡面去顯示
2.不建議直接在new testFragment()中傳
3.在TestFragment中寫一個獲取Fragment例項的靜態方法,同時將position傳進去
具體實現:
TestFragment.java增加
- 一個建立例項並傳參的方法 (setArguments)
- 一個oncreate接受傳進來的引數(getArgument)
- oncreate拿到引數後oncreateView顯示
public class TestFragment extends Fragment {
public static final String POSITION = "position";
private String position;
private TextView fragment_tv;
/**
* 在主介面中獲取fragment的方法
* 並且將position的傳進來在對應的佈局上顯示
*
* @param position
* @return
*/
public static TestFragment newInstance(int position) {
TestFragment fragment = new TestFragment();
Bundle b = new Bundle();
b.putInt(POSITION, position);
fragment.setArguments(b);
return fragment;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//接受傳進來的值
//setArguments 之後通過 getArguments來拿
if (getArguments() != null) {
//將int轉成String以便顯示
position = String.valueOf(getArguments().getInt(POSITION));
}
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_test, null);
fragment_tv = view.findViewById(R.id.fragment_tv);
fragment_tv.setText(position);
return view;
}
}
TabViewPagerAdapter.java程式碼中
設定介面卡,的 getItem方法中返回的是
TestFragment.newInstance(position); 將position傳到當前fragment中顯示了
viewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {
@Override
public Fragment getItem(int position) {
//這是自定義的fragment
//position是當前fragment的位置
return TestFragment.newInstance(position);
}
@Override
public int getCount() {
//定義數量
return 4;
}
});
具體效果:
五、結合上面的fragment案例實現底部導航和ViewPager聯動效果
先了解一下TabHost
1. TabHost常用元件
TabWidget : 該元件就是TabHost標籤頁中上部 或者 下部的按鈕, 可以點選按鈕切換選項卡;
TabSpec : 代表了選項卡介面, 新增一個TabSpec即可新增到TabHost中;
-- 建立選項卡 : newTabSpec(String tag), 建立一個選項卡;
-- 新增選項卡 : addTab(tabSpec);
2. TabHost使用步驟
a. 定義佈局 : 在XML檔案中使用TabHost元件, 並在其中定義一個FrameLayout選項卡內容;
(下面的案例FrameLayout設定為不可見,因為它的是ViewPager,FragmentLayout就用不上了)
b. 繼承TabActivity : 顯示選項卡元件的Activity繼承TabActivity;
c. 獲取元件 : 通過呼叫getTabHost()方法, 獲取TabHost物件;
d. 建立新增選項卡 : 通過TabHost建立新增選項卡;
1.主佈局的xml要改變
底部的按鈕是用tabHost來實現
- tabHost作為根部局
- 新增tabWidget id命名要為@android:id/tabs
- 要想tabWidget顯示還有加一個id 為@android:id/tabcontent 的FragmentLayout 設定為不可見就好
<?xml version="1.0" encoding="utf-8"?>
<TabHost
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tab_host"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="@+id/id_fragment_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/tab_divider">
</android.support.v4.view.ViewPager>
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/tab_divider"
android:visibility="gone">
</FrameLayout>
<View
android:id="@+id/tab_divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_above="@android:id/tabs"
android:background="#000" />
<!--tabhost 裡面包含tabwidget-->
<!--tabwidget要想顯示必須有一個id為:
@android:id/tabcontent的fragment-->
<!--不設定分割線android:showDividers="none"-->
<TabWidget
android:id="@android:id/tabs"
android:layout_width="match_parent"
android:layout_height="60dp"
android:showDividers="none"
android:layout_alignParentBottom="true">
</TabWidget>
</RelativeLayout>
</TabHost>
2.給每個TabWidget設定佈局
TabWidget : 該元件就是TabHost標籤頁中上部 或者 下部的按鈕, 可以點選按鈕切換選項卡;
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/tab_img"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginTop="4dp"
android:background="@mipmap/ic_launcher" />
<TextView
android:id="@+id/tab_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
tools:text="我是標題" />
</LinearLayout>
</RelativeLayout>
3.給標題和按鈕圖片設定selector,要實現點選下變換顏色的效果
color_tab_txt.xml 在color目錄下建立color_tab_txt.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!--選中的顏色-->
<item android:color="#4dd0c8" android:state_selected="true" />
<!--按下的顏色-->
<item android:color="#4dd0c8" android:state_pressed="true" />
<!--預設的顏色-->
<item android:color="#dddd" />
</selector>
圖片的selector:在drawable目錄下建立tab_main_icon_home.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!--注意寫的順序,預設載入按順序來的-->
<item android:drawable="@drawable/tabbar_home_pressed" android:state_selected="true" />
<item android:drawable="@drawable/tabbar_home_pressed" android:state_pressed="true" />
<item android:drawable="@drawable/tabbar_home" />
</selector>
其他兩個類似
4.實現顯示到主介面上
- 1.設定tab的標題資料、和圖片icon
- 2.將設定好的資料利用迴圈來顯示到tab上
- 3.實現聯動效果是tab對viewpager進行監聽和viewpager對tab進行監聽
- 4.在TabHost新增選項卡有個setContent(this)是要實現介面的TabHost.TabContentFactory 返回一個空view即可以了
private void initTabHost() {
mTabHost = findViewById(R.id.tab_host);
mTabHost.setup();
//三個tab做出來
//1.init data 設定標題的資料來源,我這裡定義在string裡也可以直接寫
int[] titleIDs = {
R.string.home,
R.string.msg,
R.string.me
};
//設定按鈕圖片的資料來源(定義好的selector)
int[] drawableIDs = {
R.drawable.tab_main_icon_home,
R.drawable.tab_main_icon_msg,
R.drawable.tab_main_icon_me
};
//2、 data 顯示到——>view上
for (int index = 0; index < titleIDs.length; index++) {
//這是每一個Tab的佈局
//解析成view
View view = getLayoutInflater().inflate(R.layout.tab_layout, null, false);
ImageView icon = view.findViewById(R.id.tab_img);
TextView title = view.findViewById(R.id.tab_title);
//設定圖示資源
icon.setImageResource(drawableIDs[index]);
//設定標題資源
title.setText(titleIDs[index]);
//給每個Tag根部局設定背景色
View tab = view.findViewById(R.id.tab_bg);
tab.setBackgroundColor(getResources().getColor(R.color.white));
//3。新增選項卡
mTabHost.addTab(
mTabHost.newTabSpec(getString(titleIDs[index]))
.setContent(this)//要實現TabHost.TabContentFactory實現createTabContent方法
.setIndicator(view));
//4.tab控制viewpager的顯示
//點選第幾個tab就顯示第幾個viewpager
mTabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() {
@Override
public void onTabChanged(String s) {
if (mTabHost != null) {
int position = mTabHost.getCurrentTab();
viewPager.setCurrentItem(position);
}
}
});
//5.viewpager控制tab的顯示
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
//滑動到第幾頁就第幾個tab就被選中
if (mTabHost != null) {
mTabHost.setCurrentTab(position);
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
}
//返回的view就是addTab()裡面的content,這裡用不上這個view
@Override
public View createTabContent(String s) {
View view = new View(this);
return view;
}
當然fragment也可以定義陣列來顯示(這裡變成了字串型別,之前是int型別要修改一下)
// 三個fragment組成的viewpager
final Fragment[] fragments = new Fragment[]{
TestFragment.newInstance("home"),
TestFragment.newInstance("message"),
TestFragment.newInstance("me")
};
返回這個陣列讓它對應就好
public Fragment getItem(int position) {
return fragments[position];
}
完整程式碼
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;
import android.widget.TabHost;
import android.widget.TextView;
public class TabViewPagerAdapter extends AppCompatActivity implements TabHost.TabContentFactory {
private ViewPager viewPager;
private TabHost mTabHost;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_viewpager);
viewPager = findViewById(R.id.id_fragment_viewpager);
//設定 介面卡
viewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {
@Override
public Fragment getItem(int position) {
//這是自定義的fragment
//position是當前fragment的位置
return TestFragment.newInstance(position);
}
@Override
public int getCount() {
//定義數量
return 4;
}
});
initTabHost();
}
private void initTabHost() {
mTabHost = findViewById(R.id.tab_host);
mTabHost.setup();
//三個tab做出來
//1.init data 設定標題的資料來源,我這裡定義在string裡也可以直接寫
int[] titleIDs = {
R.string.home,
R.string.msg,
R.string.me
};
//設定按鈕圖片的資料來源(定義好的selector)
int[] drawableIDs = {
R.drawable.tab_main_icon_home,
R.drawable.tab_main_icon_msg,
R.drawable.tab_main_icon_me
};
//2、 data 顯示到——>view上
for (int index = 0; index < titleIDs.length; index++) {
//這是每一個Tab的佈局
//解析成view
View view = getLayoutInflater().inflate(R.layout.tab_layout, null, false);
ImageView icon = view.findViewById(R.id.tab_img);
TextView title = view.findViewById(R.id.tab_title);
//設定圖示資源
icon.setImageResource(drawableIDs[index]);
//設定標題資源
title.setText(titleIDs[index]);
//給每個Tag根部局設定背景色
View tab = view.findViewById(R.id.tab_bg);
tab.setBackgroundColor(getResources().getColor(R.color.white));
//3。新增選項卡
mTabHost.addTab(
mTabHost.newTabSpec(getString(titleIDs[index]))
.setContent(this)//要實現TabHost.TabContentFactory實現createTabContent方法
.setIndicator(view));
//4.tab控制viewpager的顯示
//點選第幾個tab就顯示第幾個viewpager
mTabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() {
@Override
public void onTabChanged(String s) {
if (mTabHost != null) {
int position = mTabHost.getCurrentTab();
viewPager.setCurrentItem(position);
}
}
});
//5.viewpager控制tab的顯示
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
//滑動到第幾頁就第幾個tab就被選中
if (mTabHost != null) {
mTabHost.setCurrentTab(position);
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
}
//返回的view就是addTab()裡面的content,這裡用不上這個view
@Override
public View createTabContent(String s) {
View view = new View(this);
return view;
}
}
完成.
TabHost用起來很麻煩,推薦BottomNavigationView