繁体   English   中英

如何使用 viewpager2 和 fragmentstateadapter 动态添加和删除片段?

[英]How do I dynamically add and delete fragments with viewpager2 and fragmentstateadapter?

所以几个月来我一直在尝试从我的应用程序中动态添加和删除片段。 我最近迁移到 viewpager2 和 fragmentstateadapter 但无济于事。 我的目标是完全删除特定位置的片段,但能够在没有以前数据的情况下将新片段添加到列表末尾。 但是,当我这样做时,应用程序会复制片段。 这是我的适配器代码:

package com.dc.shark_reel_t5.ui.main;

import android.content.Intent;
import android.content.Context;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.Lifecycle;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager2.adapter.FragmentStateAdapter;

import com.dc.shark_reel_t5.R;

import java.util.ArrayList;

/**
 * A [FragmentPagerAdapter] that returns a fragment corresponding to
 * one of the sections/tabs/pages.
 */
public class SectionsPagerAdapter extends FragmentStateAdapter {

    private FragmentManager mFragmentManager;
    private FragmentTransaction currTransaction = null;
    private int count = 0;
    private ArrayList<String> mTitles = new ArrayList<String>();
    private ArrayList<Fragment> mFragments = new ArrayList<Fragment>();
    private ArrayList<Integer> mFragmentIDs = new ArrayList<Integer>();


    public SectionsPagerAdapter(FragmentManager fm, Lifecycle lc) {
        super(fm, lc);
        mFragmentManager = fm;
    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        return mFragments.get(position);
    }

    @Nullable
    public CharSequence getPageTitle(int position) { return (CharSequence) mTitles.get(position); }


    public String getTitle(int position) {
        return mTitles.get(position);
    }

    //Dynamic(runtime) methods:

    //On call: adds a hook to the end of the list in UI(DOES NOT CHANGE BACK END VARIABLES YET)
    public void addHookFrag(){
        mTitles.add("Hook " + (mFragments.size() + 1));
        PlaceholderFragment currFrag = PlaceholderFragment.newInstance(mFragments.size() + 1);
        mFragmentIDs.add(currFrag.getId());
        mFragments.add(currFrag);
        notifyItemInserted(mFragments.size()-1);
    }

    public void delHookFrag(int position){
        mFragments.remove(position);
        mFragmentIDs.remove(position);
        notifyDataSetChanged();
    }

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

    @Override
    public long getItemId(int position){
        if(position >= getItemCount() || position < 0)
            return RecyclerView.NO_ID;

        return mFragmentIDs.get(position);
    }

    @Override
    public boolean containsItem(long itemId){
        return mFragmentIDs.contains((int)itemId);
    }

}

谢谢。

我开发了一个解决方案。 原来传递给 containsItem 的 ID 来自 getItemID,所以整个系统依赖于程序员想出一个创建唯一 ID 的方法。 我使用了一个计数器,因为唯一应该区分片段的是时间顺序,在这种情况下它是线性增加的。 以下是帮助我的适配器的相关属性:

public class SectionsPagerAdapter extends FragmentStateAdapter {

...

    private int idGen = 0;

    @Override
    public long getItemId(int position) {
        return (long)mFragmentIDs.get(position);
    }

    @Override
    public boolean containsItem(long itemId) {
        return mFragmentIDs.contains((int)itemId);
    }

...

}

我没有在这里展示它,但我管理一个片段 ID 列表。 添加新片段时,我增加 idGen 并将增加的值添加到列表中。 删除时,我从它们各自的列表中删除 ID 和片段,并更新所有受影响片段的节号(使用片段类中的 setter 方法轻松完成)。 祝大家好运解决这个问题,花了我足够长的时间!

下面的代码有 FragmentStateAdapter。 Viewpager2 使用回收器视图来重用视图。 您可以将新页面添加到数据列表并使用 notifyDataSetChanged 或 notifyItemInserted 方法将新页面添加到 viewpager。 同样 notifyItemRemoved 可用于从 position 中动态删除页面并调整 viewpager

class StoriesPagerAdapter(fragment: Fragment, var dataList:MutableList<Content> = mutableListOf()) : FragmentStateAdapter(fragment) {
override fun getItemCount(): Int {
    return dataList.size
}

override fun createFragment(position: Int): Fragment {
    return StoryViewFragment.newInstance(dataList[position], position)
}

companion object {
    var currentItem = 0
        get() = field
        set(value) {
            field = value
        }
}}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM