呦!今天來講關於左右活動視窗(ViewPager+tabLayout)之設置

我之前每次一接到這種需求時就十分頭痛ಠ_ಠ

因為我之前一直都沒有一個很好的辦法去做這項功能

原因在於我之前都覺得設置不是太無法適應各項需求就是太過複雜

因此在我個人用今天介紹的方法之後(基本上也是自己湊出來的)

我將它整理得(我認為)比較簡單,以一個模組的方式呈現(・ω・)b

最後也希望今天的文章可以幫你解決問題~

那就上功能囉!

Gif_20200314164646550_by_gifguru

GitHub:

https://github.com/thumbb13555/ViewPagerExample/tree/master


1.載入需要的包以及畫介面

1-1 載入包

首先如果著手畫介面的話,會發現Android studio原生並沒有我們所需要的ViewPager&TabLayout

而這個包是包含在google所提供的material包裡(v7叫做design包)

而這個包的下載地址在這

->https://mvnrepository.com/artifact/com.google.android.material/material

這是androidx版的,舊版的我就不放囉(・ωー)~☆

 

打開build.gradle,將這個包載入dependencies

implementation 'com.google.android.material:material:1.2.0-alpha05'

 

截圖 2020-03-14 下午5.37.37

截圖 2020-03-14 下午5.38.47

最後按下右上角Sync now,完成載入(•ө•)♡

 

1-2 畫介面

這次的功能要畫兩個介面

一個是主畫面(就是置入ViewPager的地方)以及分畫面(每個被載入的頁面)

名稱為activity_main.xml (預設)以及my_pagers.xml

截圖 2020-03-14 下午5.46.04

這兩個畫面也沒放多少東西,我就直接貼了

activity_main.xml

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tab"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:tabMaxWidth="0dp"
        app:tabGravity="fill"
        app:tabMode="auto"

        />

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/mViewPager"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tab" />

 

my_pagers.xml

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

 

2.撰寫功能

2-1 配置所需要的檔案

在完成介面後,為了確認介面是否正常可先行按下執行

只是畫完不會有東西而已XD

再來就是撰寫所需要的功能~

首先這次的類別檔加上預設的MainActivity.java共有三個,可以先行創建

截圖 2020-03-14 下午11.15.55

MainActivity.java當然不多做解釋,就是主頁面(;・∀・)

Pagers.java的部分是設置每個小分頁的內容

最後MyPagerAdapter.java是掌管ViewPager跟TabLayout的適配器

2-2 設置PagerAdapter (檔案:MyPagerAdapter.java)

了解之後,首先先設置MyPagerAdapter.java

右鍵->New->Java Class創立一個檔案

截圖 2020-03-14 下午11.20.01

使檔案繼承PagerAdapter

截圖 2020-03-14 下午12.37.01

加入需要的方法(option+Enter)

截圖 2020-03-14 下午12.37.15

截圖 2020-03-14 下午12.37.33

 

這時候就是完成基礎配置了,但是我們再加入其他幾個複寫(control+o)

截圖 2020-03-14 下午11.25.15

分別是:

  1. instantiateItem
  2. isViewFromObject
  3. notifyDataSetChanged
  4. destroyItem
  5. getPageTitle

以上五個

完成後,一個一個解釋太麻煩了,我直接貼重點

MyPagerAdapter.java

public class MyPagerAdapter extends PagerAdapter {
    private List<View> mPager;//管理分頁陣列
    private int childCount = 0;//取得現在分頁位置

    public MyPagerAdapter(List<View> mPager) {//請記得新增建構子喔!(゚A゚;)
        this.mPager = mPager;//分頁陣列要由MainActivity傳入

    }


    @Override
    public int getItemPosition(@NonNull Object object) {//取得分頁位置
        if (childCount>0){
            childCount --;
            return POSITION_NONE;
        }
        return  super.getItemPosition(object);
    }

    @Override
    public int getCount() {
        return mPager.size();
    }//填入陣列長度
/**再加入....↓*/
    @NonNull
    @Override
    public Object instantiateItem(@NonNull ViewGroup container, int position) {
        mPager.get(position).setTag(position);
        ((ViewPager) container).addView(mPager.get(position));
        return mPager.get(position);//跑回圈增加View
    }

    @Override
    public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
        return object == view;//不管他,直接照打
    }

    @Override
    public void notifyDataSetChanged() {
        childCount = getCount();//動態新增
        super.notifyDataSetChanged();
    }

    @Override
    public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
        container.removeView((View) object);
    }

    @Nullable
    @Override
    public CharSequence getPageTitle(int position) {
        //設置TabLayout上面的文字標籤內容
        return "第"+(position+1)+"頁";
    }
    /**再加入....↑*/

}

 

完成紅字部分後,就完成基本配置了(´・з・)

2-3 設置每個分頁的內容 (檔案:Pagers.java)

程式很少,一樣直接貼,並用註解解釋

public class Pagers extends RelativeLayout {//繼承別的Layout亦可
    public Pagers(Context context, int pageNumber) {//pageNumber是由MainActivity.java那邊傳入頁碼

        super(context);

        LayoutInflater inflater = LayoutInflater.from(context);
        View view = inflater.inflate(R.layout.my_pagers, null);//連接頁面
        TextView textView = view.findViewById(R.id.textView);//取得頁面元件
        textView.setText("第"+pageNumber+"頁");

        addView(view, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        //將元件放入ViewPager
    }
}

 

記得我之前的專案是在Pager內再設計RecyclerView,請注意就是每個Pagers可視為獨立運作,因此如果遇到RecyclerView即時更新的話,請記得在這個檔案裡面撰寫呦!

2-4 設置主頁面 (檔案:MainActivity.java)

最後要來做最後步驟了(・∀・)

基本上程式也不長,就是將剛才的材料做一個綁定而已

程式也很少,直接PO

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ArrayList<View> mPages = new ArrayList<>();
        for (int i=0;i<5;i++) {//新增5個分頁
            mPages.add(new Pagers(this, (i + 1)));
        }

        ViewPager viewPager = findViewById(R.id.mViewPager);
        TabLayout tab = findViewById(R.id.tab);
        MyPagerAdapter myPagerAdapter = new MyPagerAdapter(mPages);

        tab.setupWithViewPager(viewPager);//將TabLayout綁定給ViewPager
        viewPager.setAdapter(myPagerAdapter);//綁定適配器
        viewPager.setCurrentItem(0);//指定跳到某頁,一定得設置在setAdapter後面
    }
}

 

OK,按下執行(`・ω・´)+

沒意外的話,到這邊就可以看到功能囉!

3.其他注意要點

關於TabLayout標籤是這樣

請注意activity_main.xml檔案中的紅字

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tab"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:tabMaxWidth="0dp"
        app:tabGravity="fill"
        app:tabMode="auto"

        />

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/mViewPager"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tab" />

</androidx.constraintlayout.widget.ConstraintLayout>

萬一今天你的專案有十幾二十頁

結果可能會變這樣

Screenshot_20200314-151919_ViewPagerExample

( ´_ゝ`)( ´_ゝ`)( ´_ゝ`)( ´_ゝ`)

這時候就將紅字部分改為

app:tabGravity="fill"

app:tabMode="scrollable"

就可以設為捲動模式了~

Screenshot_20200314-152048_ViewPagerExample

那如果已經知道頁數不會很多者

亦可將tabMode設為fixed

像這樣

app:tabGravity="fill"

app:tabMode="fixed"

結果就會變這樣

Screenshot_20200314-151850_ViewPagerExample

關於要怎麼設置,真的只能看你的專案而定了...要兩全其美的話就從程式那邊控制吧(´υ`)

xml設置永遠是死的(╯=▃=)╯︵┻━┻


結語

誠如開頭所述,我之前都一直沒有整理一個筆記來搞這麻煩的東西

而且之前也覺得這功能很麻煩...

但是我這種寫法是我從我寫過的專案中整理出來的(・ωー)~☆

理論上應該是可以適應大多數嘰嘰歪歪的情況吧!((希望是...

最後,希望這篇文章對你有幫助

喜歡我的文記得加入書籤額~讓小弟的文章來守護您的一天(????

下載

arrow
arrow
    創作者介紹
    創作者 碼農日常 的頭像
    碼農日常

    碼農日常大小事

    碼農日常 發表在 痞客邦 留言(1) 人氣()