ViewPager缓存使SearchView结果看起来很奇怪



小上下文

我在activity_main.xml中有一个SearchView和一个ViewPager

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.MainActivity">
<androidx.appcompat.widget.SearchView
android:id="@+id/homeSearchView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:layout_constraintBottom_toTopOf="@id/viewPager"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPager"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@id/homeMenuIcon"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/homeSearchView" />

<ImageView
android:id="@+id/homeMenuIcon"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_margin="8dp"
android:contentDescription="Overflow Menu Icon"
android:scaleType="fitXY"
android:src="@drawable/ic_menu"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/viewPager"
tools:ignore="HardcodedText" />
</androidx.constraintlayout.widget.ConstraintLayout>

我已在MainActivity.java中将OnQueryTextListener附加到SearchView


ViewPager viewPager = findViewById(R.id.viewPager);
List<Quote> allQuotesList = getQuotes();//From `Volley` Request
QuoteViewPagerAdapter adapter = new QuoteViewPagerAdapter(getSupportFragmentManager(), allQuotesList);
viewPager.setAdapter(adapter);

SearchView searchView = findViewById(R.id.homeSearchView);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
getFilter().filter(query);
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
getFilter().filter(newText);
return false;
}
});
private Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
ArrayList<Quote> filteredResults = new ArrayList<>();
if (constraint.toString().isEmpty())
filteredResults.addAll(allQuotesList);
else
for (Quote quote : allQuotesList) {
if (quote.getQuote().toLowerCase().contains(constraint.toString().toLowerCase())
|| quote.getAuthor().toLowerCase().contains(constraint.toString().toLowerCase()))
filteredResults.add(quote);
}
FilterResults filterResult = new FilterResults();
filterResult.values = filteredResults;
return filterResult;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
adapter.setQuoteList((List<Quote>) results.values);
adapter.notifyDataSetChanged();
}
};
}

这是QuoteViewPagerAdapter.java

public class QuoteViewPagerAdapter extends FragmentPagerAdapter {
private List<Quote> quoteList;
public QuoteViewPagerAdapter(FragmentManager fm, List<Quote> fragmentList) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
quoteList = fragmentList;
}
@androidx.annotation.NonNull
@Override
public Fragment getItem(int position) {
return QuoteFragment.newInstance(quoteList.get(position));
}
@Override
public int getCount() {
return quoteList.size();
}
@Override
public int getItemPosition(@androidx.annotation.NonNull Object object) {
return POSITION_NONE;
}
public void setQuoteList(List<Quote> quoteList) {
this.quoteList = quoteList;
}
}

这是Quote.java

public class Quote {
private String quote;
private String author;
public Quote() {
}
public Quote(String quote, String author) {
this.quote = quote;
this.author = author;
}
public String getQuote() {
return quote;
}
public void setQuote(String quote) {
this.quote = quote;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}

问题

当搜索到某个内容时,QuoteViewPagerAdapter中的quoteList (List<Quote>)被更新为setQuoteList()。因此,getCount()返回新的大小。

但是,旧片段(其中2个(仍保留在ViewPager中。这使得搜索结果在滚动ViewPager2次之后出现。此外,这导致最后2个结果被省略。

此外,如果只有1个搜索结果的大小,则ViewPager冻结,使得滚动不可能(因为getCount()返回1,所以ViewPager仅显示旧的第一片段(

我尝试了什么

//inside publishResults()
adapter = null;
viewPager.setAdapter(null);
viewPager.removeAllViews();
viewPager.removeAllViewsInLayout();
viewPager.destroyDrawingCache();
adapter = new QuoteViewPagerAdapter(getSupportFragmentManager(), (List<Quote>) results.values);
viewPager.setAdapter(adapter);
adapter.notifyDataSetChanged();
//inside onCreate()
viewPager.setSaveFromParentEnabled(false);
viewPager.setSaveEnabled(false);

预期行为

ViewPager显示从位置0到的搜索结果的新列表

期待来自StackOverflow社区的帮助。提前谢谢。

通过在QuoteViewPagerAdapter.java中将FragmentPagerAdapter更改为FragmentStatePagerAdapter,可以按预期工作

有点晚了,但是,为未来的读者写下这个答案。。。

相关内容

最新更新