[英]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>
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.