如何避免包含片段的 ArrayList 中的重复项

How to avoid duplicates in ArrayList containing Fragments

我正在开发一个具有 ViewPager 动态片段插入的应用程序,具体取决于用户在 片段上按下的内容。

为了找到避免在上述 ViewPager 中创建重复 Fragment 的方法,我已经研究了两天。

第一个选项,我试过:

ArrayList.contains(fragment) 

并且始终返回 false。我搜索了一下,结果发现我必须重写片段 class 中的 equals 和 hashCode 方法,但是 hashCode 被声明为最终方法,所以运气不好。

第二个选项,为什么不使用LinkedHashMap?我找不到像 ArrayList.get(index) 那种方式那样从中获取元素的方法,所以我尝试了:

Fragment[] fragments =  LinkedHashMap.toArray() 

并对此进行迭代,但我无法从 Object[] 转换为 Fragment[],我不知道为什么,因为它继承自它。

第三个选项,

public boolean verifyDuplicates(Fragment f){
   for(Fragment fragment: mFragments){
      if(f.getClass().equals(fragment.getClass()) return true;

   }
}

但我收到“无法解析符号 getClass()”..

第四个选项,获取片段 ID,如果它与 ArrayList 中现有片段的任何 ID 匹配,则不添加它。 好吧,出于某种原因,如果我第一次创建两个 FragmentA 并将其添加到 ArrayList,然后创建第二个 FragmentA 并比较它们的 ID,它们是完全不同的,因此它被添加。但是,如果我创建第三个 FragmentA,它的 ID 与第二个 FragmentA 的 ID 匹配,所以我最终会得到两个重复的 FragmentA。(第一个和第二个)

无论如何,这是代码... 有没有办法识别碎片?确保没有重复的方法?

谢谢

负责插入新片段的方法:

private void nextView(View v){


    Log.d("onViewSwipe", String.valueOf(v.getId()));
    Fragment f = getNextFragment(v.getId());


    if(f == null){
        Log.e("FRAGMENT", "NULL");
    }
    else{
        Log.e("FRAGMENT", f.toString());
    }

    /*Verify that that page doesnt already exist*/
    if(!compareDuplicates(f)) {
        Log.d("FRAGMENT", "DOESNT EXISTS");
        mFragments.add(f);
        mViewPagerAdapter.notifyDataSetChanged();
        mViewPager.setCurrentItem(mFragments.size()-1);
    }



} 

比较方法:

 private boolean compareDuplicates(Fragment f){


    for(Fragment fragment: mFragments){

        int idF = f.getId(); //for debugging
        int idFrag = fragment.getId(); //for debugging

        if(f.getId() == fragment.getId()){
            return true;
        }

    }

    return false;

}

ViewPagerAdapter:

public class ViewPagerAdapter extends FragmentStatePagerAdapter {

ArrayList<Fragment> mFragments;
Context context;


public ViewPagerAdapter(FragmentManager fm, ArrayList<Fragment> mFragments, Context context) {
    super(fm);
    this.mFragments = mFragments;
    this.context = context;
}

public void setmFragments(ArrayList<Fragment> mFragments) {
    this.mFragments = mFragments;
}

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

@Override
public int getCount() {
    return (mFragments != null) ? mFragments.size():0;
}

附加信息:

主机 activity 处理每个片段都相同的回调,由包含触发新片段插入的按钮或元素的片段调用。该回调调用 nextView(v)

虽然可行,但我不确定这是否是最佳解决方案。

public class deleteDup<T> {
      public ArrayList<T> deleteDup(ArrayList<T> al) {

        ArrayList<T> alNew=new ArrayList<>();
        HashSet<T> set = new HashSet<>(alNew);
          for (T al1 : al) {
              if (!set.contains(al1)) {
                  alNew.add(al1);
                  set.add(al1);
              }
          }
         return alNew;   
        }  

      public static void main(String[] args){
          ArrayList<String> list = new ArrayList<>();
            list.add("A");
            list.add("B");
            list.add("A");
            deleteDup<String> dD=new deleteDup<>();
            System.out.println(dD.deleteDup(list));
      }
}

第一个选项应该可以正常工作。无需实施 hashCodeequals.

以下是使用示例 ArrayList.contains(obj)

    ArrayList<Fragment>  list = new ArrayList<Fragment>();
    Fragment f1 = new Fragment();
    Fragment f2 = new Fragment();
    list.add(f1);
    if(!list.contains(f2)){
        Log.d("Main", "contains no f2");
    }
    if(list.contains(f1)){
        Log.d("Main", "contains f1");
    }

两个日志都会打印。

所以你可以像下面那样改变compareDuplicates

private boolean compareDuplicates(Fragment f){
    return mFragments.contains(f);
}

结果是:

getClass() 

方法在执行 File -> Invalidate Caches / Restart and clean + rebuild 后有效。

Android 我猜是工作室错误..