过去几天我一直在寻找我的问题的解决方案,但所有其他类似问题似乎都存在onClickListener问题,或者他们的解决方案不适用于手头的问题。 我在项目中使用的onClickListeners似乎按预期工作,只有SearchView不是。

我的起始清单包括一些物品及其成分/材料,一切都按预期工作。 当使用SearchView过滤时,新的过滤列表显示正确的项目名称但错误的成分。 从字面上看是过滤之前的旧位置,我似乎无法调试问题的来源。

MainAdapter.java

public class MainAdapter extends RecyclerView.Adapter<MainAdapter.ViewHolder> implements Filterable {
    private List<Item> mItemCard;
    private List<Item> mItemCardFull; //Needed for the getFilter() method

    static class ViewHolder extends RecyclerView.ViewHolder {


        // region Variables (Item Name, Icon, Expand Layout & Expand button)
        ImageView mItemIcon;
        TextView mItemName;
        ImageButton mExpandButton;
        // etc...

        // region Variables (Ingredients' Icons, Names & Amount)
        ImageView mIngredient_1_Icon;
        TextView mIngredient_1_Name;
        TextView mIngredient_1_amountTV;
        float mIngredient_1_amount;
        // etc...

        // region misc Variables
        boolean _isFirstTime = true; // Used in initialization & crafting method switch
        EditText editFactoryAmount;
        ImageView factoryAmountIcon;
        Button factoryAmountButton;
        // etc...


        ViewHolder(@NonNull View itemView) {
            super(itemView);
            mItemIcon = itemView.findViewById(R.id.itemIcon);
            mItemName = itemView.findViewById(R.id.itemName);
            mIngredient_1_Icon = itemView.findViewById(R.id.ingredient_1_icon);
            mIngredient_1_Name = itemView.findViewById(R.id.ingredient_1_name);
            mIngredient_1_amountTV = itemView.findViewById(R.id.ingredient_1_amount);
        // etc...
        }
    }

    public MainAdapter(List<Item> itemCard) {
        this.mItemCard = itemCard;
        this.mItemCardFull = new ArrayList<>(itemCard);
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
        final ViewHolder holder = new ViewHolder(v);
        return holder;
    }

    @Override
    public void onBindViewHolder(@NonNull final ViewHolder holder, final int position) {
        final Item currentItem = mItemCard.get(position);

        final float craftingTime = currentItem.getCraftingTime();
        final float outputAmount = currentItem.getOutputAmount();

        holder.mItemIcon.setImageResource(currentItem.getItemIcon());
        holder.mItemName.setText(currentItem.getItemName());
        holder.mExpandButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                boolean show = toggleLayout(!currentItem.isExpanded(), view, holder.mExpandedLayout);
                currentItem.setExpanded(show);
            }
        });

        // region Textwatchers
        // region Editor Listeners
        /* Editor Listener: When actionDone is clicked on the soft keyboard, clear focus from editText */

        // other random methods included in the project which arent relevant
        // ......
    }

    /* Expands or collapses depending on item state */
    private boolean toggleLayout(boolean isExpanded, View v, ConstraintLayout expandedLayout) {
        Animations.toggleArrow(v, isExpanded);
        if (isExpanded) {
            Animations.expand(expandedLayout);
        } else {
            Animations.collapse(expandedLayout);
        }
        return isExpanded;
    }

    @Override
    public int getItemViewType(int position) {
        return position;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public int getItemCount() {
        return mItemCard.size();
    }

    /*~~~~~~~~~~~~~~~~~~~~~~~~~~ Search Filter Setup ~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    @Override
    public Filter getFilter() {
        return itemFilter;
    }

    private Filter itemFilter = new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            List<Item> filteredList = new ArrayList<>();

            if (constraint == null || constraint.length() == 0) {
                filteredList.addAll(mItemCardFull);
            } else {
                String filterPattern = constraint.toString().toLowerCase().trim();

                for (Item item : mItemCardFull) {
                    if (item.getItemName().toLowerCase().contains(filterPattern)) {
                        filteredList.add(item);
                    }
                }
            }

            FilterResults results = new FilterResults();
            results.values = filteredList;
            return results;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            mItemCard.clear();
            mItemCard.addAll((List) results.values);
            notifyDataSetChanged();
        }
    };
}

IntermediatesFragment.java

public class IntermediatesFragment extends Fragment {

    private RecyclerView mRecyclerView;
    private MainAdapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;


    public IntermediatesFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View thisFragment = inflater.inflate(R.layout.fragment_layout, container, false);
        setHasOptionsMenu(true);

        mRecyclerView = thisFragment.findViewById(R.id.recyclerView);
        mRecyclerView.setHasFixedSize(true);
        mLayoutManager = new LinearLayoutManager(getContext());


        createItemList();
        mRecyclerView.setLayoutManager(mLayoutManager);
        mRecyclerView.setAdapter(mAdapter);
        return thisFragment;
    }

    @Override
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);

        MenuItem searchItem = menu.findItem(R.id.action_search);
        SearchView searchView = (SearchView) searchItem.getActionView();

        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                mAdapter.getFilter().filter(newText);
                return false;
            }
        });
    }

    private void createItemList() {
        ArrayList<Item> itemList = new ArrayList<>();
        // region Intermediates Items
        // etc items ...

        mAdapter = new MainAdapter(itemList);
    }
}

如果我在Viewholder包含“ setIsRecyclable(false) ”,问题似乎就会消失,但是在低端手机上的性能很糟糕,并且卡在退出视图时会被破坏/重置,这不是一种理想的行为。

使用完整的onBindViewHolder编辑:

@Override
    public void onBindViewHolder(@NonNull final ViewHolder holder, final int position) {
        final Item currentItem = mItemCard.get(position);

        final float craftingTime = currentItem.getCraftingTime();
        final float outputAmount = currentItem.getOutputAmount();

        holder.mItemIcon.setImageResource(currentItem.getItemIcon());
        holder.mItemName.setText(currentItem.getItemName());
        holder.mExpandButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                boolean show = toggleLayout(!currentItem.isExpanded(), view, holder.mExpandedLayout);
                currentItem.setExpanded(show);
            }
        });

        // region Ingredients' Icons, Names & Amounts
        holder.mIngredient_1_Icon.setImageResource(currentItem.getIngredientIcon_1());
        holder.mIngredient_2_Icon.setImageResource(currentItem.getIngredientIcon_2());
        holder.mIngredient_3_Icon.setImageResource(currentItem.getIngredientIcon_3());
        holder.mIngredient_4_Icon.setImageResource(currentItem.getIngredientIcon_4());
        holder.mIngredient_5_Icon.setImageResource(currentItem.getIngredientIcon_5());
        holder.mIngredient_6_Icon.setImageResource(currentItem.getIngredientIcon_6());

        holder.mIngredient_1_Name.setText(currentItem.getIngredientName_1());
        holder.mIngredient_2_Name.setText(currentItem.getIngredientName_2());
        holder.mIngredient_3_Name.setText(currentItem.getIngredientName_3());
        holder.mIngredient_4_Name.setText(currentItem.getIngredientName_4());
        holder.mIngredient_5_Name.setText(currentItem.getIngredientName_5());
        holder.mIngredient_6_Name.setText(currentItem.getIngredientName_6());

        holder.mIngredient_1_amountTV.setText(String.valueOf(currentItem.getIngredientAmount_1()));
        holder.mIngredient_2_amountTV.setText(String.valueOf(currentItem.getIngredientAmount_2()));
        holder.mIngredient_3_amountTV.setText(String.valueOf(currentItem.getIngredientAmount_3()));
        holder.mIngredient_4_amountTV.setText(String.valueOf(currentItem.getIngredientAmount_4()));
        holder.mIngredient_5_amountTV.setText(String.valueOf(currentItem.getIngredientAmount_5()));
        holder.mIngredient_6_amountTV.setText(String.valueOf(currentItem.getIngredientAmount_6()));


        if (currentItem.getIngredientName_1() == R.string.item_null) {
            holder.mIngredient_1_Icon.setVisibility(View.GONE);
            holder.mIngredient_1_Name.setVisibility(View.GONE);
            holder.mIngredient_1_amountTV.setVisibility(View.GONE);\

        // if statements continue for the rest of the 5 ingredients
        // endregion Ingredients' Icons, Names & Amounts

        holder.factoryAmountButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                holder.button_f++;
                float factoryAmount = Float.parseFloat(holder.editFactoryAmount.getText().toString());
                float outputSpeed = Float.parseFloat((holder.editItemOutput.getText().toString()));
                if (currentItem.getCraftingMethod().equals("Assembler")) {
                    switch (holder.button_f) {
                        case 0:
                            holder.factoryAmountIcon.setImageResource(R.drawable.pf_assembling_machine_1);
                            holder.craftingSpeed = 0.50f;
                            if (holder.editItemOutput.isFocused()) {
                                holder.factoryAmount = (outputSpeed * craftingTime) / ((outputAmount * holder.craftingSpeed) * (1 + (holder.speedModuleAmount * holder.speed)) * (1 + (holder.prodModuleAmount * holder.productivity)));
                                holder.editFactoryAmount.setText(String.valueOf(holder.factoryAmount));
                                // region Edit Ingredients' Amount
                                holder.factoryAmount = Float.parseFloat(holder.editFactoryAmount.getText().toString());
                                holder.mIngredient_1_amount = (holder.factoryAmount * holder.craftingSpeed * currentItem.getIngredientAmount_1()) / craftingTime;
                                holder.mIngredient_1_amountTV.setText(String.valueOf(holder.mIngredient_1_amount));

                                holder.mIngredient_2_amount = (holder.factoryAmount * holder.craftingSpeed * currentItem.getIngredientAmount_2()) / craftingTime;
                                holder.mIngredient_2_amountTV.setText(String.valueOf(holder.mIngredient_2_amount));

                                holder.mIngredient_3_amount = (holder.factoryAmount * holder.craftingSpeed * currentItem.getIngredientAmount_3()) / craftingTime;
                                holder.mIngredient_3_amountTV.setText(String.valueOf(holder.mIngredient_3_amount));

                                holder.mIngredient_4_amount = (holder.factoryAmount * holder.craftingSpeed * currentItem.getIngredientAmount_4()) / craftingTime;
                                holder.mIngredient_4_amountTV.setText(String.valueOf(holder.mIngredient_4_amount));

                                holder.mIngredient_5_amount = (holder.factoryAmount * holder.craftingSpeed * currentItem.getIngredientAmount_5()) / craftingTime;
                                holder.mIngredient_5_amountTV.setText(String.valueOf(holder.mIngredient_5_amount));

                                holder.mIngredient_6_amount = (holder.factoryAmount * holder.craftingSpeed * currentItem.getIngredientAmount_6()) / craftingTime;
                                holder.mIngredient_6_amountTV.setText(String.valueOf(holder.mIngredient_6_amount));


            // it goes on in the same pattern depending on other circumstances


        /*~~~~~~~~~~~~ Initialization & Crafting Method Switch ~~~~~~~~~~~~~~~~~~*/
        if (holder.editFactoryAmount.getText().toString().isEmpty() && !holder.editFactoryAmount.isFocused()) {
            holder.editFactoryAmount.setText(String.valueOf(1.0f));
            holder.outputSpeed = ((Float.parseFloat(holder.editFactoryAmount.getText().toString()) * holder.craftingSpeed) * (1 + (holder.speedModuleAmount * holder.speed))) / craftingTime * (1 + (holder.prodModuleAmount * holder.productivity)) * outputAmount;
            holder.editItemOutput.setText(String.valueOf(holder.outputSpeed));
        }

        float factoryAmount = Float.parseFloat(holder.editFactoryAmount.getText().toString());
        switch (currentItem.getCraftingMethod()) {
            case "Assembler":
                // If it's the first time the app starts, set default crafting speed, else keep as it is.
                if (holder._isFirstTime) {
                    holder.craftingSpeed = 0.50f;
                    holder._isFirstTime = false;
                }
                if (holder.craftingSpeed == 0.50f) {
                    holder.factoryAmountIcon.setImageResource(R.drawable.pf_assembling_machine_1);
                    holder.button_f = 0;
                } else if (holder.craftingSpeed == 0.75f) {
                    holder.factoryAmountIcon.setImageResource(R.drawable.pf_assembling_machine_2);
                    holder.button_f = 1;
                } else {
                    holder.factoryAmountIcon.setImageResource(R.drawable.pf_assembling_machine_3);
                }
                holder.outputSpeed = ((factoryAmount * holder.craftingSpeed) * (1 + (holder.speedModuleAmount * holder.speed))) / craftingTime * (1 + (holder.prodModuleAmount * holder.productivity)) * outputAmount;
                holder.editItemOutput.setText(String.valueOf(holder.outputSpeed));
                // region Edit Ingredients' Amount
                holder.factoryAmount = Float.parseFloat(holder.editFactoryAmount.getText().toString());
                holder.mIngredient_1_amount = (holder.factoryAmount * holder.craftingSpeed * currentItem.getIngredientAmount_1()) / craftingTime;
                holder.mIngredient_1_amountTV.setText(String.valueOf(holder.mIngredient_1_amount));

                holder.mIngredient_2_amount = (holder.factoryAmount * holder.craftingSpeed * currentItem.getIngredientAmount_2()) / craftingTime;
                holder.mIngredient_2_amountTV.setText(String.valueOf(holder.mIngredient_2_amount));

                holder.mIngredient_3_amount = (holder.factoryAmount * holder.craftingSpeed * currentItem.getIngredientAmount_3()) / craftingTime;
                holder.mIngredient_3_amountTV.setText(String.valueOf(holder.mIngredient_3_amount));

                holder.mIngredient_4_amount = (holder.factoryAmount * holder.craftingSpeed * currentItem.getIngredientAmount_4()) / craftingTime;
                holder.mIngredient_4_amountTV.setText(String.valueOf(holder.mIngredient_4_amount));

                holder.mIngredient_5_amount = (holder.factoryAmount * holder.craftingSpeed * currentItem.getIngredientAmount_5()) / craftingTime;
                holder.mIngredient_5_amountTV.setText(String.valueOf(holder.mIngredient_5_amount));

                holder.mIngredient_6_amount = (holder.factoryAmount * holder.craftingSpeed * currentItem.getIngredientAmount_6()) / craftingTime;
                holder.mIngredient_6_amountTV.setText(String.valueOf(holder.mIngredient_6_amount));
                // endregion Edit Ingredients' Amount
                break;
            case "Smelter":
            // thing happening here and etc for all the other cases
        }
    }

#1楼 票数:0

你能试试这个吗

class SectionRecyclerViewAdapter(
    var sectionModelArrayList: ArrayList<SectionModel>,
    val context: Activity
) : RecyclerView.Adapter<SectionRecyclerViewAdapter.MyViewHolder>(), Filterable {
    private val mSectionList: List<SectionModel>? = sectionModelArrayList

    override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): MyViewHolder {
        val view = LayoutInflater.from(viewGroup.context).inflate(R.layout.section_custom_row_layout, viewGroup, false)
        return MyViewHolder(view)
    }

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        val sectionModel = sectionModelArrayList[position]
        holder.tvStations.text = sectionModel.stations
        holder.ivLogo.setImageDrawable(sectionModel.logo)
        holder.ivArrow.setImageResource(R.mipmap.ic_arrow_dark)
        holder.view.setOnClickListener {
            when (position) {
                0 -> {
                    val intent = Intent(context, AllUserActivity::class.java)
                    context.startActivity(intent)
                    context.overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left)
                }
                1 -> {
                    Toast.makeText(context, "Nothing to Show", Toast.LENGTH_SHORT).show()
                }


            }
        }
    }

    override fun getItemCount(): Int {
        return sectionModelArrayList.size
    }

    inner class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val ivLogo: ImageView
        val tvStations: TextView
        val ivArrow: ImageView
        val view: View


        init {
            ivLogo = itemView.findViewById(R.id.ivLogo)
            tvStations = itemView.findViewById(R.id.tvStations)
            ivArrow = itemView.findViewById(R.id.ivArrow)
            view = itemView
        }
    }

    override fun getFilter(): Filter {
        return object : Filter() {
            protected override fun performFiltering(charSequence: CharSequence): FilterResults {
                val charString = charSequence.toString()
                if (charString.isEmpty()) {
                    sectionModelArrayList = mSectionList as ArrayList<SectionModel>
                } else {
                    var filteredList = ArrayList<SectionModel>()
                    if (mSectionList != null) {
                        for (row in mSectionList) {

                            // name match condition. this might differ depending on your requirement
                            // here we are looking for name or phone number match
                            if (row.stations.toLowerCase().contains(charString.toLowerCase())) {
                                filteredList.add(row)
                            }
                        }
                    }
                    sectionModelArrayList = filteredList
                }

                val filterResults = FilterResults()
                filterResults.values = sectionModelArrayList
                return filterResults
            }

            override fun publishResults(charSequence: CharSequence, filterResults: FilterResults) {
                sectionModelArrayList = filterResults.values as ArrayList<SectionModel>
                notifyDataSetChanged()
            }
        }
    }
}

#2楼 票数:0

将过滤列表传递给适配器将解决该问题。

#3楼 票数:0 已采纳

如果没有完整的图片,很难确切地说出这里出什么问题,但是......

你拿着很多国家在你的ViewHolder,就像无论是第一次,成分含量等你真的想持有View那儿,因为他们可以不可预知的项目之间进行交换。 这就是为什么当你告诉它它们不可回收时它起作用的原因 - 它不再这样做了。

您还将事物设置为 GONE,但如果应显示它们则不可见。 这是回收的问题:

holder.mIngredient_1_Icon.setVisibility(View.GONE);

您的按钮 onClick 侦听器正在修改支架中的状态 - 这很糟糕,因为支架会在项目之间交换,并且可能会反弹。 你真的很想在你的Item类中包含这个状态。 一旦你这样做了,你的 RecyclerView 就变成了从Item到设置一切的 onBindViewHolder 的单向转换,推理起来会容易得多。

  ask by Ligkonakos translate from so

未解决问题?本站智能推荐:

1回复

使用SearchView过滤器后,无法对RecyclerView进行排序

我正在尝试使用SearchView实现一个简单的搜索按钮,以在RecyclerView中查找项目。 但是,此搜索按钮破坏了我的排序功能,因为在输入SearchView后,无法再对RecyclerView进行排序。 这是我的活动 现在,我怀疑它与onOptionsItemSelec
2回复

过滤结果后,RecyclerView 搜索过滤器位置错误

你好朋友,请帮助我,我正在使用 Recylerview 并实现了搜索过滤器,但问题是在 recylerview 中搜索项目后,当我单击项目时,它总是返回项目的 0 位置我想要列表项的实际位置请我帮忙这里是我的代码如何在 recylerview 中搜索项目后获取实际位置 recylerview 这是
2回复

如何在 RecyclerView 中添加搜索过滤器以过滤解析的 JSON 数据? 已编辑

我正在开发一个 android 应用程序,它显示受冠状病毒影响的国家列表、确诊病例总数和死亡总数。 我正在使用JSON API 来获取数据并使用RecyclerView显示它。 该应用程序运行良好,我得到了所有国家/地区的列表以及各自的案例计数。 我想添加一个搜索选项,以便用户可以过滤列表并查找特定
1回复

搜索过滤器后如何更新android RecyclerView项目?

我正在尝试使用Android Filterable类过滤RecyclerView 。 我已经按照本教程Android RecyclerView添加搜索过滤器来完成此任务。 该项目运行无错误,我在日志中显示了结果数组,得到了正确的结果, 但 UI 却没有任何变化。 这是我的适配器
1回复

recyclerview 中的 Searchview 重复数据

搜索视图在操作栏中实现,搜索工作正常,但例如,如果用户搜索两个字符pa ,我的列表包含与pa相关的 2 个数据,即 pack1,pack2 然后数据加载到回收站视图中。 现在如果用户输入另一个字符l到前面的字符 pa,现在我的搜索视图有pal ,但数组列表与搜索不匹配,列表不包含任何带有 pal 的
1回复

SearchView 和 RecyclerView(当返回包含 recyclerview 的片段时,应用程序关闭)

我有片段包含Recyclerview和Searchview (在 cardview 中不是 appbar),关于搜索过程,应用程序正常工作,但问题是什么时候从包含 recyclerview 的这个片段转到它,应用程序关闭。 日志猫: 适配器: 片段中的搜索功能: 注意:我按照本课将搜索
1回复

Android Searchview过滤器recyclerview volley实现

我正在使用搜索视图实现搜索过滤器,我成功加载了列表,当我单击searchview并在下面键入word application crash时出错,这是代码: 这是错误 java.lang.NullPointerException:尝试在androidx.recyclerv
1回复

如何使用相同的 RecyclerView 制作 SearchView?

我在 RecyclerView 中有一些片段,它们被添加到 MainActivity 主体容器中。 我有一个带有工具栏和 RecyclerView 的片段,它被添加到 MainActivity 头容器中。 我想要做的所有RecyclerView和化妆的所有元素搜索setVisibility(View