【问题标题】:How to implement Recyclerview with EditText in each item and Filter the list with SearchView?如何在每个项目中使用 EditText 实现 Recyclerview 并使用 SearchView 过滤列表?
【发布时间】:2019-09-12 13:59:01
【问题描述】:

我在每个项目中实现了 EditText 并使用 SearchView 对其进行过滤,两者分别工作正常。但是,问题是当我在项目的 EditText 字段中输入一些值并使用搜索过滤列表时,输入的值保留在给出的位置相同。即新项目是搜索的结果,与我在搜索之前给项目的值相同

ItemMasterAdapter.java

public class ItemMasterAdapter extends RecyclerView.Adapter<ItemMasterAdapter.ItemMasterViewHolder> implements Filterable{
private Context context;
private List<Order> itemList;
private List<Order> itemListFull;
private LayoutInflater inflater;

public static ArrayList<EditModel> editModelArrayList;

public ItemMasterAdapter(Context context, List<Order> itemList, ArrayList<EditModel> editModelArrayList1)
{
    this.context = context;
    this.itemList = itemList;
    itemListFull=new ArrayList<>(itemList);
    this.inflater = LayoutInflater.from(context);
    this.editModelArrayList = editModelArrayList1;
}

@NonNull
@Override
public ItemMasterViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i)
{
    View imView = inflater.inflate(R.layout.list_item_master, viewGroup, false);
    return new ItemMasterViewHolder(imView);
}

@Override

public void onBindViewHolder(@NonNull ItemMasterViewHolder itemMasterViewHolder, int i)
{

    Order iList = itemList.get(i);
   itemMasterViewHolder.itemNameTextView.setText(iList.itemName);
   itemMasterViewHolder.inputQtyEditText.setText(editModelArrayList.get(i).getEditTextValue());
}

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

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

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

public class ItemMasterViewHolder extends RecyclerView.ViewHolder
{
    ImageView itemImageView;
    TextView itemNameTextView, itemQtyTextView, itemPriceTextView, itemStockTextView;
    EditText inputQtyEditText;

    public ItemMasterViewHolder(@NonNull View itemView)
    {
        super(itemView);

        itemNameTextView = itemView.findViewById(R.id.mtv_item_name);
        inputQtyEditText = itemView.findViewById(R.id.et_input_item_stock);
        inputQtyEditText.addTextChangedListener(new TextWatcher()
        {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after)
            {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                String inputValue=inputQtyEditText.getText().toString();
                Order iList = itemList.get(getAdapterPosition());
                editModelArrayList.get(itemList.indexOf(iList)).setEditTextValue(inputValue);
            }

            @Override
            public void afterTextChanged(Editable s)
            {

            }
        });
    }
}



@Override
public Filter getFilter()
{
    return itemFilter;
}

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

        if(constraint==null || constraint.length()==0)
        {
            filteredItemList.addAll(itemListFull);

        }

        else
        {
            String filteredPattern=constraint.toString().toLowerCase().trim();

            for(Order item : itemListFull)
            {
                if(item.itemName.toLowerCase().contains(filteredPattern))
                {
                    filteredItemList.add(item);
                }
            }
        }

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

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

ShopOrderActivity.java

import static com.mrcodekiddie.tobuytoday.ItemMasterAdapter.editModelArrayList;

public class ShopOrderActivity extends AppCompatActivity {
RecyclerView mRecyclerView;
List<Order> itemList;

private Toolbar toolbar;
ItemMasterAdapter itemMasterAdapter;

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_shop_order);
    toolbar=findViewById(R.id.app_bar_order);
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(false);
    getSupportActionBar().setTitle("KID");


    itemList=new ArrayList<Order>();

    itemList.add(new Order("001","burger"));
    itemList.add(new Order("002","pizza"));
    itemList.add(new Order("003","sandwich"));
    itemList.add(new Order("004","lemonade"));
    itemList.add(new Order("005","cold coffee"));
    itemList.add(new Order("006","hot coffee"));
    itemList.add(new Order("007","black coffee"));
    itemList.add(new Order("008","green tea"));
    itemList.add(new Order("010","Idly"));
    itemList.add(new Order("011","Dhosai"));
    itemList.add(new Order("012","Pongal"));
    itemList.add(new Order("013","Poori"));
    itemList.add(new Order("014","Ooothappam"));
    itemList.add(new Order("015","Vadai"));
    itemList.add(new Order("016","Parotta"));
    itemList.add(new Order("017","pani poori"));
    itemList.add(new Order("018","bele poori"));
    itemList.add(new Order("019","Omlete"));
    itemList.add(new Order("020","kalakki"));
    itemList.add(new Order("021","Half Boil"));
    itemList.add(new Order("022","Full Boil"));


    mRecyclerView=findViewById(R.id.mRecyclerView);
    mRecyclerView.setHasFixedSize(false);

    mRecyclerView.setLayoutManager(new LinearLayoutManager(ShopOrderActivity.this));
    editModelArrayList = populateList();

     itemMasterAdapter=new ItemMasterAdapter(this,
            itemList,editModelArrayList);
    mRecyclerView.setAdapter(itemMasterAdapter)
}

@Override
protected void onResume() {
    super.onResume();
    itemList=new ArrayList<Order>();

}

private ArrayList<EditModel> populateList() {
    ArrayList<EditModel> list = new ArrayList<>();

    for(int i = 0; i <itemList.size(); i++)
    {
        EditModel editModel = new EditModel();
        editModel.setEditTextValue("");
        list.add(editModel);
    }
    return list;
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater=getMenuInflater();
    inflater.inflate(R.menu.search_menu,menu);

    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) {

             itemMasterAdapter.getFilter().filter(newText);
             return false;
         }
     });
    return true;
}}

EditModel.java

public class EditModel {
private String editTextValue;

public EditModel(){ }

public String getEditTextValue()
{
    return editTextValue;
}

public void setEditTextValue(String editTextValue)
{
    this.editTextValue = editTextValue;
} }

list_item_master.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

<androidx.cardview.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    card_view:cardCornerRadius="6dp"
    card_view:cardElevation="4dp"
    card_view:cardUseCompatPadding="true">


    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="4dp">

        <EditText
            android:id="@+id/et_input_item_stock"
            android:layout_width="65dp"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_marginRight="10dp"
            android:backgroundTint="@color/accent"
            android:imeOptions="actionDone"
            android:inputType="numberDecimal"
            android:justificationMode="inter_word"
            android:textAlignment="center"
            android:textColor="@android:color/background_dark"
            />


        <TextView
            android:id="@+id/mtv_item_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="7dp"
            android:maxWidth="220dp"
            android:text="Dummy Item"
            android:textColor="@color/primary_text"
            android:textSize="12pt"

            />
    </RelativeLayout>

</androidx.cardview.widget.CardView>
</LinearLayout>

activity_shop_order.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ShopOrderActivity">

<androidx.appcompat.widget.Toolbar
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/app_bar_order"
    android:theme="@style/AppTheme"
    app:titleTextColor="@color/white"
    android:background="@color/primary"
    app:popupTheme="@style/AppTheme">

</androidx.appcompat.widget.Toolbar>
<RelativeLayout
    android:id="@+id/tv_item_header"
    android:layout_below="@id/app_bar_order"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">


</RelativeLayout>

<androidx.recyclerview.widget.RecyclerView
    android:layout_below="@id/tv_item_header"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/mRecyclerView"
   >

</androidx.recyclerview.widget.RecyclerView>

这是完整的代码link

【问题讨论】:

    标签: android android-studio android-layout android-recyclerview


    【解决方案1】:

    而不是:

    Order iList = itemList.get(getAdapterPosition());
    
    editModelArrayList.get(itemList.indexOf(iList)).setEditTextValue(inputValue);
    

    直接使用:

    editModelArrayList.get(getLayoutPosition()).setEditTextValue(inputValue);
    

    也不是使用位置 i:

    itemMasterViewHolder.inputQtyEditText.setText(editModelArrayList.get(i).getEditTextValue());
    

    你应该使用

    itemMasterViewHolder.inputQtyEditText.setText(editModelArrayList.get(itemMasterViewHolder.getLayoutPositon()).getEditTextValue());
    

    所以简单的问题是,当列表不断变化时,我的位置不可靠....当列表不断变化时,使用 viewholder 的 getAdapterPosition 或 getLayoutPosition。我更喜欢 getLayoutPosition 因为它总是返回正确的位置,而 getAdapterPosition 很少返回错误的位置

    如果您删除/添加/更改数据集中的任何项目并使用通知方法通知RecyclerView,RecyclerView将不会调用onBindViewHolder方法并更新所有项目的位置,它只会为新的调用更新新的位置onBindViewHolder 的值,这会导致显示的项目和位置值不一致。

    查看以下帖子了解更多详情:

    Why not to use position passed in mutable recycler view lists

    【讨论】:

    【解决方案2】:

    在你的视图中(它上面的recyclerview的Activity或Fragment)类实现

    SearchView.OnQueryTextListener

    那么你必须重写一些方法,其中之一是

    @Override public boolean onQueryTextChange(String s) {}

    当 serachView 文本更改时调用此方法(或者如果您使用编辑文本,您可以实现 OnTextChangeListener ) 在这种方法中:

    @Override
    public boolean onQueryTextChange(String s) {
        if (TextUtils.isEmpty(s)) { //check if text is empty show all items
            lstFiltered=items;
            setListAdapter(items);
        } else {
            filterInput(s);
        }
    
        return true;
    }
    

    lstFiltered 是 RecyclerView 项目模型的列表,当项目通过输入文本进行搜索时,我们将这些项目添加到此列表中

    items 是所有的项目

    而filterInput()方法是:

    private void filterInput(String s) {
    
        lstFiltered = new ArrayList<>();
        for (int i = 0; i < items.size(); i++) { //for filtering items
            if (/* condition that you want to filter items */) {
                lstFiltered.add(items.get(i));
            }
        }
        setListAdapter(lstFiltered); //set Recycler Adapter or mAdapter.notifyDataSetChanged(
    }
    

    【讨论】:

      猜你喜欢
      • 2018-12-09
      • 1970-01-01
      • 2015-08-04
      • 2016-10-29
      • 2019-08-08
      • 2020-02-07
      • 1970-01-01
      • 1970-01-01
      • 2023-03-09
      相关资源
      最近更新 更多