[英]I am having trouble applying SearchView with RecyclerView
我正在嘗試從支持庫中實現 SearchView。 我希望用戶使用 SearchView 過濾 RecyclerView 中的單詞列表。
到目前為止,我已經遵循了一些教程,並將 SearchView 添加到了 ActionBar,但是當應用程序啟動時一切正常,但是當我單擊搜索圖標時。 該應用程序在 Logcat 中顯示以下錯誤一秒鍾並自動重新啟動應用程序並且錯誤消失。 但是搜索功能不起作用
錯誤我收到錯誤圖片
這是我的搜索活動:
在此處輸入代碼
public class SearchActivity extends AppCompatActivity {
private Toolbar mToolbar;
private RecyclerView mRecyclerView;
private RecyclerViewAdpater mAdpater;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
mToolbar=findViewById(R.id.toolbarSearch);
setSupportActionBar(mToolbar);
mRecyclerView=findViewById(R.id.recyclerViewSearch);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mAdpater=new RecyclerViewAdpater(DataSevices.mChineseColors,this);
mRecyclerView.setAdapter(mAdpater);
}
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.toolbar_search_menu,menu);
MenuItem item=menu.findItem(R.id.action_search);
SearchView searchView=(SearchView) item.getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
mAdpater.getFilter().filter(newText);
return false;
}
});
return true;
}
}
這是我的 RecyclerView 適配器 Class
public class RecyclerViewAdpater extends RecyclerView.Adapter<RecyclerViewAdpater.MyViewHolder> implements Filterable {
private List<ChineseLanguage> mChineseLanguages;
private List<ChineseLanguage> mChineseLanguagesFull;
private Context mContext;
private MediaPlayer mMediaPlayer;
public RecyclerViewAdpater(List<ChineseLanguage> chineseLanguages, Context context) {
mChineseLanguages = chineseLanguages;
mChineseLanguagesFull=new ArrayList<>(mChineseLanguages);
mContext = context;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list,parent,false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, final int position) {
holder.txtEnglishWord.setText(mChineseLanguages.get(position).getEnglishAlphabet());
holder.txtChineseWord.setText(mChineseLanguages.get(position).getChineseAlphabet());
holder.txtPronunciation.setText(mChineseLanguages.get(position).getPronounciation());
holder.btnPlay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
releasaMedia();
mMediaPlayer=MediaPlayer.create(mContext,mChineseLanguages.get(position).getSound());
mMediaPlayer.start();
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
releasaMedia();
}
});
}
});
}
private void releasaMedia(){
if (mMediaPlayer!=null){
mMediaPlayer.release();
}
mMediaPlayer=null;
}
@Override
public int getItemCount() {
return mChineseLanguages.size();
}
@Override
public Filter getFilter() {
return filter;
}
private Filter filter=new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
List<ChineseLanguage> filteredList=new ArrayList<>();
if (constraint.toString().isEmpty()){
filteredList.addAll(mChineseLanguagesFull);
}else {
for(ChineseLanguage item: mChineseLanguagesFull){
if (item.getEnglishAlphabet().toLowerCase().contains(constraint.toString().toLowerCase().trim())){
filteredList.add(item);
}
}
}
FilterResults filterResults=new FilterResults();
filterResults.values=filteredList;
return filterResults;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
mChineseLanguages.clear();
mChineseLanguages.addAll((Collection<? extends ChineseLanguage>) results.values);
notifyDataSetChanged();
}
};
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView txtEnglishWord,txtChineseWord,txtPronunciation;
ImageButton btnPlay;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
txtEnglishWord=itemView.findViewById(R.id.txtEnglishWord);
txtChineseWord=itemView.findViewById(R.id.txtChineseWord);
txtPronunciation=itemView.findViewById(R.id.txtPronunciation);
btnPlay=itemView.findViewById(R.id.btnPlay);
}
}
}
如果我做錯了什么請糾正我
您的泄漏很可能發生,因為即使在活動結束后您的適配器仍然存在並且它攜帶活動的上下文導致 memory 泄漏。 不需要通過活動傳遞上下文,您可以從 class 中獲取它。 此處無需在適配器 class 中聲明全局 mContext 變量,您可以通過以下方式簡單地獲取上下文:
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView txtEnglishWord,txtChineseWord,txtPronunciation;
ImageButton btnPlay;
View mItemView; //declare a global view variable
public MyViewHolder(@NonNull View itemView) {
super(itemView);
mItemView = itemView; //assign itemView to the above declared global field
txtEnglishWord=itemView.findViewById(R.id.txtEnglishWord);
txtChineseWord=itemView.findViewById(R.id.txtChineseWord);
txtPronunciation=itemView.findViewById(R.id.txtPronunciation);
btnPlay=itemView.findViewById(R.id.btnPlay);
}
}
然后在你的 onBindViewHolder 從 itemView 獲取上下文
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, final int position) {
Context mContext = holder.itemView.getContext(); //access the declared field through the holder instance here
// your method here...
}
編輯:我還建議檢查您的 publishResults 方法。 要查看問題是否出在 notifydatasetchanged() 中,請嘗試在方法中重新初始化 mChineseLanguages 列表。 此外,在適配器的構造函數中初始化 mChineseLanguages 的方式與 mChineseLanguagesAll 相同。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.