0

Я работаю над приложением, которое имеет ViewPager с динамической вставкой фрагментов, в зависимости от того, что пользователь нажимает на фрагмент ведьмы.Как избежать дубликатов в ArrayList, содержащих фрагменты

Я искал два дня, чтобы найти способ избежать создания дублирующего фрагмента в указанном ViewPager.

Первый вариант, я пробовал:

ArrayList.contains(fragment) 

и всегда возвращается ложь. Я искал, и оказалось, что мне нужно переопределить равные и hashCode методы в классе Fragment, но 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()» ..

Четвертый вариант, получить Идентификатор фрагмента и, если он соответствует любому из ids существующего фрагмента внутри ArrayList, то не добавляйте его. Ну почему-то, если я создаю, сначала скажу FragmentA два и добавлю его в ArrayList, а затем создаем второй FragmentA и сравниваем их идентификаторы, они совершенно разные, поэтому он добавляется. Однако, если я создаю третий FragmentA, его идентификатор совпадает со вторым идентификатором FragmentA, поэтому я получаю два повторных 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; 
} 

Дополнительная информация:

Активность хоста обрабатывает обратный вызов, который является одним и тем же для каждого фрагмента, вызывается фрагментом, содержащим кнопку или элемент, который запускает вставку нового фрагмента. Этот обратный вызов вызывает nextView(v)

+0

Первый вариант использования ArrayList является хорошим решением, может быть, где-то другие ошибки. мог бы показать весь код, как и использовать его? – yummy

ответ

0

Оказывается, что:

getClass() 

метод сделал работу после выполнения Файл -> Invalidate кэшей/Restart и чистый + перестраивать.

Android Студия ошибка я догадываюсь ..

0

Я не уверен, что это лучшее решение, хотя оно работает.

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)); 
     } 
} 
0

Первый вариант должен заставить его работать.Нет необходимости вводить hashCode или equals.

Ниже приведен пример использования 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); 
} 
Смежные вопросы