【 Android 】ViewPager + TabLayout + Fragment 数据初始化问题

ViewPager Fragment 配合使用的时候,ViewPager 会使用预加载机制,使得我们在没有切换到到对应页面时,就已经加载好了,这是个非常不好的用户体验。

所以本示例项目就诞生了。

关键字:setUserVisibleHint

实例:

示例结构:
使用Activity嵌套Fragment

MainActivity

public class MainActivity extends AppCompatActivity {

    private ArrayList<Fragment> mFragments;

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

        initFragment();

        initView();
    }

    private void initFragment() {
        mFragments = new ArrayList<>();

        AFragment aFragment = AFragment.newInstance();
        BFragment bFragment = BFragment.newInstance();
        CFragment cFragment = CFragment.newInstance();

        mFragments.add(aFragment);
        mFragments.add(bFragment);
        mFragments.add(cFragment);
    }

    private void initView() {
        final TabLayout tabLayout = findViewById(R.id.tab_layout);
        final ViewPager viewPager = findViewById(R.id.viewpager);

        viewPager.setAdapter(new FragmentStatePagerAdapter(getSupportFragmentManager()) {
            @Override
            public Fragment getItem(int position) {
                return mFragments.get(position);
            }

            @Override
            public int getCount() {
                return mFragments.size();
            }
        });

        viewPager.setOffscreenPageLimit(mFragments.size());

        viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));

        tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                Log.d(TAG, "onTabSelected: ");

                viewPager.setCurrentItem(tabLayout.getSelectedTabPosition(), true);
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                Log.d(TAG, "onTabUnselected: ");
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {
                Log.d(TAG, "onTabReselected: ");
            }
        });
    }
}

AFragment 

public class AFragment extends Fragment {

    public AFragment() {
        // Requires empty public constructor
    }

    public static AFragment newInstance() {
        return new AFragment();
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater,
                             @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_a, container, false);

        initView(view);

        return view;
    }

    private void initView(View view) {
        
    }
}

BFragment

public class BFragment extends Fragment {

    private boolean isFirst = true;

    public BFragment() {
        // Requires empty public constructor
    }

    public static BFragment newInstance() {
        return new BFragment();
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater,
                             @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_b, container, false);

        initView(view);

        return view;
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);

        if (isVisibleToUser && isFirst) {
            Log.d(TAG, "BFragment 首次加载");

            isFirst = false;
        }
    }

    private void initView(View view) {
        
    }
}

CFragmentBFragment相似,就不赘述了。

MainActivity对应的布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    tools:context=".ui.activity.MainActivity">

    <android.support.design.widget.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        app:tabMode="scrollable"
        app:tabSelectedTextColor="@color/colorAccent">

        <android.support.design.widget.TabItem
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="A" />

        <android.support.design.widget.TabItem
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="B" />

        <android.support.design.widget.TabItem
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="C" />

    </android.support.design.widget.TabLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:overScrollMode="never"
        android:scrollbars="none" />

</LinearLayout>

AFragment、 BFragment、 CFragment 对应的布局文件就不赘述了,可以随意自定义。

源码下载:

https://github.com/cnwutianhao/ViewPager

使用ViewPager、TabLayout和Fragment组合可以在Android应用中创建一个多标签切换界面,允许用户在多个独立的页面间平滑切换。以下是基本步骤: 1. **添加依赖库**: 首先,在项目级别的build.gradle文件中添加RecyclerView和Support Design库的依赖。 ```gradle implementation 'com.android.support:recyclerview-v7:28.0.0' implementation 'com.android.support.constraint:constraint-layout:2.1.0' implementation 'com.google.android.material:material:1.5.0' ``` 2. **布局设计**: 创建XML布局文件,包含TabLayout和ViewPager。例如: - TabLayout: `activity_main.xml` ``` <androidx.constraintlayout.widget.ConstraintLayout> <com.google.android.material.tabs.TabLayout android:id="@+id/tab_layout" .../> <androidx.viewpager.widget.ViewPager android:id="@+id/view_pager" .../> </androidx.constraintlayout.widget.ConstraintLayout> ``` 3. **设置数据源和适配器**: 在Activity或Fragment中,初始化TabLayout并设置其Adapter,通常是`PagerAdapter`或`FragmentPagerAdapter`。这需要创建至少4个Fragment代表每个页面的内容。 ```java TabLayout tabLayout = findViewById(R.id.tab_layout); ViewPager viewPager = findViewById(R.id.view_pager); List<Fragment> fragments = new ArrayList<>(); // 添加四个Fragment实例到fragments列表 FragmentPagerAdapter adapter = new FragmentPagerAdapter(getSupportFragmentManager()) { @NonNull @Override public Fragment getItem(int position) { return fragments.get(position); } @Override public int getCount() { return fragments.size(); } }; viewPager.setAdapter(adapter); tabLayout.setupWithViewPager(viewPager); ``` 4. **响应事件**: TabLayout的onTabSelectedListener可以监听选中状态的变化,并相应地更新ViewPager的显示内容。 5. **配置Tab和Fragment**: 为TabLayout中的每个Tab设置标签标题,对应于Fragment的内容。也可以在Fragment里设置对应的视图,以便在切换时更新内容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值