简体   繁体   English

如何在每个项目中使用带有EditText的Recyclerview以及如何使用SearchView过滤列表?

[英]How to implement Recyclerview with EditText in each item and Filter the list with SearchView?

I implemented EditText in each item and filtered it using SearchView , both are working fine separately .But, the problem is when I input some value in EditText field of an item and filter the list using search, the value entered stays in the same position where it's given. 我在每个项目中实现了EditText并使用SearchView对其进行了过滤,但两者都可以正常工作。但是,问题是,当我在项目的EditText字段中输入一些值并使用搜索过滤列表时,输入的值会保持在相同的位置它给出了。 ie the new items comes as a result of search has the same value I gave to the item before searching 即,由于搜索到的新项目具有与我在搜索前赋予该项目相同的值

ItemMasterAdapter.java 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 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 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 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>

Here's the whole code link ! 这是整个代码链接

Instead of : 代替 :

Order iList = itemList.get(getAdapterPosition());

editModelArrayList.get(itemList.indexOf(iList)).setEditTextValue(inputValue);

Directly use : 直接使用:

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

Also instead of using the position i: 另外,不要使用位置i:

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

You should use 你应该用

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

So the simple issue is, that position i is not reliable when the list keeps changing.... when the list keeps changing use getAdapterPosition or getLayoutPosition of the viewholder. 因此,简单的问题是,当列表不断变化时,位置i是不可靠的。...当列表不断变化时,请使用viewholder的getAdapterPosition或getLayoutPosition。 I prefer getLayoutPosition as it always returns the correct position whereas getAdapterPosition very rarely returns the wrong position 我更喜欢getLayoutPosition,因为它总是返回正确的位置,而getAdapterPosition很少返回错误的位置

if you delete/add/change any item in the data set and notify the RecyclerView Using notify methods, RecyclerView will not call onBindViewHolder method and update all item's positions, It will only update the position of the new ones for the new calls of onBindViewHolder and this will cause inconsistency between displayed items and position value. 如果删除/添加/更改数据集中的任何项目并使用notify方法通知RecyclerView,则RecyclerView不会调用onBindViewHolder方法并更新所有项目的位置,它只会为onBindViewHolder和的新调用更新新项目的位置。这将导致显示的项目和位置值之间不一致。

see the following post for more details: 有关更多详细信息,请参见以下帖子:

Why not to use position passed in mutable recycler view lists 为什么不使用可变回收者视图列表中传递的位置

in Your view (Activity or Fragment that the recyclerview on it ) class implement 在您的视图(recyclerview在其上的Activity或Fragment)类中实现

SearchView.OnQueryTextListener SearchView.OnQueryTextListener

then you have to override some methods one of them is 那么您必须重写一些方法,其中之一是

@Override public boolean onQueryTextChange(String s) {}

this method called when the serachView Text changes(or if u use Edit Text You can implements OnTextChangeListener ) and in this method : 此方法在serachView Text更改时(或如果您使用Edit Text可以实现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 is a List of RecyclerView Item Model that when items that passed input text for search we add these items in this List lstFiltered是RecyclerView项目模型的列表,当通过输入文本进行搜索的项目我们将这些项目添加到此列表中

and

items is all of items 项目是所有项目

and filterInput() method is : 而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(
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM