Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/188.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用viewpager2和fragmentstateadapter动态添加和删除片段?_Java_Android_Android Fragments_Android Viewpager2_Fragmentstateadapter - Fatal编程技术网

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

Java 如何使用viewpager2和fragmentstateadapter动态添加和删除片段?,java,android,android-fragments,android-viewpager2,fragmentstateadapter,Java,Android,Android Fragments,Android Viewpager2,Fragmentstateadapter,几个月来,我一直在尝试从我的应用程序中动态添加和删除片段。我最近迁移到viewpager2和fragmentstateadapter,但没有用。我的目标是完全删除特定位置的片段,但能够在没有先前数据的情况下将新片段添加到列表末尾。但是,当我这样做时,应用程序会复制片段。以下是我的适配器代码: package com.dc.shark_reel_t5.ui.main; import android.content.Intent; import android.content.Context; i

几个月来,我一直在尝试从我的应用程序中动态添加和删除片段。我最近迁移到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);
    }

}
package com.dc.shark_reel_t5.ui.main;
导入android.content.Intent;
导入android.content.Context;
导入android.os.Bundle;
导入androidx.annotation.NonNull;
导入androidx.annotation.Nullable;
导入androidx.annotation.StringRes;
导入androidx.fragment.app.fragment;
导入androidx.fragment.app.FragmentManager;
导入androidx.fragment.app.FragmentPagerAdapter;
导入androidx.fragment.app.FragmentStatePagerAdapter;
导入androidx.fragment.app.FragmentTransaction;
导入androidx.lifecycle.lifecycle;
导入androidx.recyclerview.widget.recyclerview;
导入androidx.viewpager.widget.PagerAdapter;
导入androidx.viewpager2.adapter.FragmentStateAdapter;
进口商品dc.shark_reel_t5.R;
导入java.util.ArrayList;
/**
*一个[FragmentPagerAdapter],它返回一个对应于
*其中一个部分/选项卡/页面。
*/
公共类SectionsPagerAdapter扩展了FragmentStateAdapter{
私人碎片管理器MFFragmentManager;
私有碎片事务currTransaction=null;
私有整数计数=0;
private ArrayList mTitles=新的ArrayList();
私有ArrayList MFFragments=新ArrayList();
私有ArrayList MFFragmentId=新ArrayList();
公共部分SpagerAdapter(碎片管理器fm、生命周期lc){
超级(fm、lc);
MFFragmentManager=fm;
}
@非空
@凌驾
公共片段createFragment(int位置){
返回mFragments.get(位置);
}
@可空
public CharSequence getPageTitle(int位置){return(CharSequence)mTitles.get(position);}
公共字符串getTitle(int位置){
返回mTitles.get(位置);
}
//动态(运行时)方法:
//On call:在UI中的列表末尾添加一个钩子(尚未更改后端变量)
公共无效addHookFrag(){
添加(“Hook”+(mffragments.size()+1));
PlaceholderFragment currFrag=PlaceholderFragment.newInstance(mffragments.size()+1);
add(currFrag.getId());
加上(货币);
notifyItemInserted(mffragments.size()-1);
}
公共区域(内部位置){
拆卸(位置);
MFFragmentId.移除(位置);
notifyDataSetChanged();
}
@凌驾
public int getItemCount(){
返回mffragments.size();
}
@凌驾
公共长getItemId(int位置){
如果(位置>=getItemCount()| |位置<0)
返回RecyclerView.NO\u ID;
返回MFFragmentId.get(位置);
}
@凌驾
公共布尔containsItem(长项目ID){
返回MFFragmentId.contains((int)itemId);
}
}
谢谢

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

class StoriesPagerAdapter(fragment:fragment,var-dataList:MutableList=mutableListOf()):FragmentStateAdapter(fragment){
重写getItemCount():Int{
返回dataList.size
}
重写片段(位置:Int):片段{
返回StoryViewFragment.newInstance(数据列表[position],position)
}
伴星{
var currentItem=0
get()=字段
设置(值){
字段=值
}
}}

我开发了一个解决方案。事实证明,传递给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方法很容易完成)。祝大家好运,这个问题花了我足够长的时间

是否仍有将其转换为java源代码的方法?我还没学过kotlin yetAlso,所以这不会真正影响删除或添加。为什么不在这里显示它?试试这个
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);
    }

...

}