[英]How to avoid duplicates in ArrayList containing Fragments
I'm working on an app that has a ViewPager
with dynamic Fragment insertion,depending on what the user presses on witch Fragment. 我正在开发一个具有带有动态Fragment插入的ViewPager
的应用程序,具体取决于用户在女巫Fragment上按下的内容。
I've been digging for two days for finding a way to avoid duplicate Fragment creating in said ViewPager. 我已经花了两天的时间来寻找避免在ViewPager中创建重复的Fragment的方法。
First option, i tried: 第一种选择,我尝试过:
ArrayList.contains(fragment)
and always returned false. 并始终返回false。 I searched and it turns out i have to override the equals and hashCode
methods in the Fragment class, but hashCode
is declared final, so no luck there. 我搜索了一下,结果发现我必须重写Fragment类中的equals和hashCode
方法,但是hashCode
被声明为final,所以没有运气。
Second option, why not using a LinkedHashMap
? 第二种选择,为什么不使用LinkedHashMap
呢? I cant find a way to get the elements from it like you would on an ArrayList.get(index)
kinda way, so i tried: 我找不到像在ArrayList.get(index)
上那样从中获取元素的方法,所以我尝试了:
Fragment[] fragments = LinkedHashMap.toArray()
and iterate on that, but i cant cast from Object[]
to Fragment[]
, i don't know why since it inherits from it. 并对此进行迭代,但是我无法从Object[]
为Fragment[]
,我不知道为什么,因为它是从它继承的。
Third option, 第三选择
public boolean verifyDuplicates(Fragment f){
for(Fragment fragment: mFragments){
if(f.getClass().equals(fragment.getClass()) return true;
}
}
But i get a " unable to resolve symbol getClass() ".. 但是我得到一个“ 无法解析符号getClass() ”。
Fourth option, getting the Fragment id and if it matches to any of the ids of the existing Fragment inside the ArrayList, then don't add it. 第四个选项,获取Fragment ID,如果它与ArrayList中现有Fragment的任何ID相匹配,则不要添加它。 Well for some reason, if i create say a FragmentA two a first time and add it to the ArrayList, and then create a second FragmentA and compare their ids, they are completely different, so it gets added. 好吧,由于某种原因,如果我第一次创建一个FragmentA,然后将其添加到ArrayList中,然后创建第二个FragmentA,并比较它们的ID,它们是完全不同的,因此将其添加。 However, if i create a third FragmentA, its id matches to second FragmentA id, so i end up with two repeated FragmentA.(first and second) 但是,如果我创建第三个FragmentA,则其ID与第二个FragmentA ID相匹配,因此我最终会得到两个重复的FragmentA。(第一个和第二个)
Anyway, here is the code... Is there a way to identify the fragments? 无论如何,这是代码...有没有办法识别片段? a way to make sure you don't have duplicates? 一种确保没有重复的方法?
Thanks 谢谢
Method on charge of inserting new Fragment: 插入新片段的方法:
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);
}
}
Method comparing them: 比较它们的方法:
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: 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;
}
Additional Info: 附加信息:
The host activity handles a callback that is the same for every fragment, invoked by the fragment containing the button or element that triggers the new fragment insertion. 主机活动处理每个片段都相同的回调,由包含触发新片段插入的按钮或元素的片段调用。 That callback calls to nextView(v)
该回调调用nextView(v)
I am not sure if this is the best solution although it works. 我不确定这是否是最好的解决方案,尽管它可以工作。
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));
}
}
The first option should make it work. 第一个选项应该使其工作。 There's no need to implements hashCode
nor equals
. 无需实现hashCode
或equals
。
Following is a sample to use ArrayList.contains(obj)
以下是使用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");
}
Both of the log would print. 这两个日志都将打印。
So you may change compareDuplicates
like following, 因此,您可以像下面这样更改compareDuplicates
,
private boolean compareDuplicates(Fragment f){
return mFragments.contains(f);
}
Turns out that the: 原来是:
getClass()
method did work after doing a File -> Invalidate Caches / Restart and clean + rebuild. 方法在执行File-> Invalidate Caches /重新启动并清理+重建后确实起作用。
Android Studio bug i guess.. 我猜是Android Studio错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.