![](/img/trans.png)
[英]How to prevent fragment to refresh recyclerview when after back from another fragment / save recyclerview position
[英]SearchView with RecyclerView (App closes when back to fragment which contains the recyclerview)
我的片段包含Recyclerview
和Searchview
(在 cardview 不是 appbar 中),關於搜索過程,應用程序正常工作,但問題是何時從包含 recyclerview 的片段到 go 並返回它,應用程序關閉。
日志貓:
java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.Object[] java.util.Collection.toArray()' on a null object reference
at java.util.ArrayList.addAll(ArrayList.java:588)
at com.quiltur.blocks.BlockListAdapter$3.publishResults(BlockListAdapter.java:174)
適配器:
public class BlockListAdapter extends RecyclerView.Adapter<BlockListAdapter.BlockViewHolder> implements Filterable {
private FirebaseFirestore firebaseFirestore;
private FirebaseAuth firebaseAuth;
private String userId;
public Context context;
private List<BlockListModel> blockListModels;
private List<BlockListModel> blockListModelsFull;
private OnBlockListItemClicked onBlockListItemClicked;
public BlockListAdapter(OnBlockListItemClicked onBlockListItemClicked) {
this.onBlockListItemClicked = onBlockListItemClicked;
}
public void setBlockListModels(List<BlockListModel> blockListModels) {
this.blockListModels = blockListModels;
blockListModelsFull = new ArrayList<>(blockListModels);
}
@NonNull
@Override
public BlockViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_list_item, parent, false);
context = parent.getContext();
return new BlockViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull BlockViewHolder holder, int position) {
holder.listTitle.setText(blockListModels.get(position).getName());
String blockId = blockListModels.get(position).getBlock_id();
String imageUrl = blockListModels.get(position).getImage();
Shimmer shimmer = new Shimmer.ColorHighlightBuilder()
.setDuration(1800) // how long the shimmering animation takes to do one full sweep
.setBaseAlpha(0.9f) //the alpha of the underlying children
.setHighlightAlpha(0.8f) // the shimmer alpha amount
.setDirection(Shimmer.Direction.LEFT_TO_RIGHT)
.setAutoStart(true)
.setBaseColor(Color.WHITE)
.build();
ShimmerDrawable shimmerDrawable = new ShimmerDrawable();
shimmerDrawable.setShimmer(shimmer);
Glide .with(holder.itemView.getContext())
.load(imageUrl)
.centerCrop()
.placeholder(shimmerDrawable)
.into(holder.listImage);
firebaseFirestore = FirebaseFirestore.getInstance();
firebaseAuth = FirebaseAuth.getInstance();
userId = firebaseAuth.getCurrentUser().getUid();
//Get Fav
firebaseFirestore.collection("Users/" + userId + "/Favorites").document(blockId).addSnapshotListener(new EventListener<DocumentSnapshot>() {
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onEvent(@Nullable DocumentSnapshot documentSnapshot, @Nullable FirebaseFirestoreException e) {
if (documentSnapshot.exists()){
holder.listFav.setImageDrawable(context.getDrawable(R.drawable.fav_btn_full));
}else {
holder.listFav.setImageDrawable(context.getDrawable(R.drawable.fav_btn_emp));
}
}
});
//Fav Feature
holder.listFav.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
firebaseFirestore.collection("Users/" + userId + "/Favorites").document(blockId).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if (!task.getResult().exists()){
Map<String,Object> favMap = new HashMap<>();
favMap.put("id", blockId);
firebaseFirestore.collection("Users/" + userId + "/Favorites").document(blockId).set(favMap);
}else {
firebaseFirestore.collection("Users/" + userId + "/Favorites").document(blockId).delete();
}
}
});
}
});
}
@Override
public int getItemCount() {
if(blockListModels == null){
return 0;
} else {
return blockListModels.size();
}}
@Override
public Filter getFilter() {
return blocksFilter;
}
private Filter blocksFilter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
List<BlockListModel> filteredList = new ArrayList<>();
if (constraint == null || constraint.length() == 0) {
filteredList.addAll(blockListModelsFull);
}else {
String filterPattern = constraint.toString().toLowerCase().trim();
for (BlockListModel item : blockListModelsFull) {
if (item.getName().toLowerCase().contains(filterPattern)) {
filteredList.add(item);
}
}
}
FilterResults results = new FilterResults();
results.values = filteredList;
results.count = filteredList.size();
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
blockListModels.clear();
blockListModels.addAll((List) results.values);
notifyDataSetChanged();
}
};
public class BlockViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private ImageView listImage;
private TextView listTitle;
private ImageButton listFav;
public BlockViewHolder(@NonNull View itemView) {
super(itemView);
listImage = itemView.findViewById(R.id.list_image);
listTitle = itemView.findViewById(R.id.list_title);
listFav = itemView.findViewById(R.id.favBtn);
listTitle.setOnClickListener(this);
listImage.setOnClickListener(this);
}
@Override
public void onClick(View v) { onBlockListItemClicked.onItemClicked(getAdapterPosition());
}
}
public interface OnBlockListItemClicked {
void onItemClicked(int position);
}
}
片段中的搜索功能:
searchView = view.findViewById(R.id.search_text);
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setQueryHint("Search");
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
if(newText.length() > 0){
recoView.setVisibility(View.GONE);
recommended.setVisibility(View.GONE);
}else {
recoView.setVisibility(View.VISIBLE);
recommended.setVisibility(View.VISIBLE);
}
adapter.getFilter().filter(newText);
return false;
}
});
注意:我按照本課將搜索添加到我的應用程序。
at java.util.ArrayList.addAll(ArrayList.java:588)
at com.quiltur.blocks.BlockListAdapter$3.publishResults(BlockListAdapter.java:174)
publishResults()
中存在導致 NPE 的問題。 我懷疑當你再次從片段返回到適配器時, blockListModels
會得到一個 null 值,不確定片段中是否有東西得到它 null; 因此,首先嘗試避免在設置其值之前對其調用方法
我注釋掉了舊代碼並添加了新代碼。
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
// blockListModels.clear();
// blockListModels.addAll((List) results.values);
blockListModels = (List<BlockListModel>) results.values;
notifyDataSetChanged();
}
更新
嘗試此代碼時,應用程序沒有關閉,但出現了兩個新問題。 第一個是當recyclerview 回到fragment 時消失。 第二個在搜索時,recyclerview 項目的位置出現不平衡(在舊代碼中不會發生這種情況)
現在回滾上述技巧以保持blockListModels
不是 null,並在performFiltering
內有意設置它
所以過濾器將是:
private Filter blocksFilter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
List<BlockListModel> filteredList = new ArrayList<>();
if (constraint == null || constraint.length() == 0) {
filteredList.addAll(blockListModelsFull);
}else {
String filterPattern = constraint.toString().toLowerCase().trim();
for (BlockListModel item : blockListModelsFull) {
if (item.getName().toLowerCase().contains(filterPattern)) {
filteredList.add(item);
}
}
}
// Setting the blockListModels
blockListModels = filteredList; // <<< Here is the change
FilterResults results = new FilterResults();
results.values = filteredList;
results.count = filteredList.size();
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
blockListModels.clear();
blockListModels.addAll((List) results.values);
notifyDataSetChanged();
}
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.