簡體   English   中英

SearchView 與 RecyclerView(應用程序在返回包含 recyclerview 的片段時關閉)

[英]SearchView with RecyclerView (App closes when back to fragment which contains the recyclerview)

我的片段包含RecyclerviewSearchview (在 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM