Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TabLayout&ViewPager2梦幻联动 #142

Open
soapgu opened this issue May 11, 2022 · 0 comments
Open

TabLayout&ViewPager2梦幻联动 #142

soapgu opened this issue May 11, 2022 · 0 comments
Labels

Comments

@soapgu
Copy link
Owner

soapgu commented May 11, 2022

  • 标签布局

标签布局最早出现的地方是windows,在WPF中使用的是TabControl。而WPF中是一个包含了标签项和内容项目集成在一起的。
而在Android的世界不同,TabLayout只负责标签的渲染,并不负责标签对应内容的呈现。

  • TabLayout的黄金搭档ViewPager2(ViewPager)

既然是官网专门宣传一个页面,那么黄金组合是没得跑了。ViewPager/ViewPager2都可以配,没有历史包袱,我们果断选更新的控件ViewPager2。

  • 界面定义

<?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <data>
        <variable
            name="dataContext"
            type="com.soapgu.tabapplication.viewmodels.MainViewModel" />
    </data>
    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#F7F7F9"
        tools:context=".MainActivity">

        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{dataContext.title}"
            android:textSize="24sp"
            android:textStyle="bold"
            app:layout_constraintBottom_toTopOf="@+id/pager"
            app:layout_constraintEnd_toStartOf="@+id/tab_layout"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <com.google.android.material.tabs.TabLayout
            android:id="@+id/tab_layout"
            android:layout_width="300dp"
            android:layout_height="wrap_content"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:ignore="SpeakableTextPresentCheck" />

        <androidx.viewpager2.widget.ViewPager2
            android:id="@+id/pager"
            android:layout_width="match_parent"
            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_layout" />


    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

界面的定义只要把TabLayout和ViewPager2放上去就可以了

  • 实现FragmentStateAdapter并赋值

public class MyFragmentAdapter extends FragmentStateAdapter {

    public MyFragmentAdapter(@NonNull FragmentActivity fragmentActivity) {
        super(fragmentActivity);
    }

    public MyFragmentAdapter(@NonNull Fragment fragment) {
        super(fragment);
    }

    public MyFragmentAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle) {
        super(fragmentManager, lifecycle);
    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        if( position == 0 ){
            return HomeFragment.newInstance();
        }
        else if( position == 1 ){
            return MutiLayoutFragment.newInstance();
        }
        return MemberFragment.newInstance();
    }

    @Override
    public int getItemCount() {
        return 3;
    }
}

ViewPager2可以接受Adapter,不过针对和Tab联动的情况下,我们使用FragmentStateAdapter 的实现类
代码里面我们提供了,实现三个标签内容,所有标签的内容必须是Fragment ,
注意这里有三个构造,保险起见最好都实现一下

 MyFragmentAdapter adapter = new MyFragmentAdapter(this);
        viewPager = findViewById(R.id.pager);
        viewPager.setAdapter(adapter);

赋值Adapter代码如下

  • 和TabLayout联动

        TabLayout tabLayout = this.findViewById(R.id.tab_layout);
        new TabLayoutMediator(tabLayout, viewPager,
                (tab, position) -> {
                    String title = "";
                    switch (position){
                        case 0:
                            title = "本地控制";
                            break;
                        case 1:
                            title = "多画面控制";
                            break;
                        case 2:
                            title = "参会人员";
                            break;
                    }
                    tab.setText(title);
                }
        ).attach();

通过TabLayoutMediator实现联动,主要是把 TabLayout和Viewpager2连接起来,同时建立position和title的对应关系

  • 生命周期部分

  • 首先:子Fragment 的加载时lazy load,App启动后,只会加载第一个Fragment,往后滑动才会加载其他Fragment

  • 所有Fragment 处于平级关系,生命周期和父级页面管理。简单测试一下,第一个Fragment的数据,在滑倒第三个Fragment以后,再滑回来是保存的。反之亦然。

  • 相关代码以及链接

  • Demo TabApplication

  • 使用 ViewPager2 创建包含标签的滑动视图

  • Material Design Tabs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant