[英]How to implement Recyclerview with EditText in each item and Filter the list with SearchView?
我在每個項目中實現了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;
}}
編輯模型
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>
這是整個代碼鏈接 !
代替 :
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());
因此,簡單的問題是,當列表不斷變化時,位置i是不可靠的。...當列表不斷變化時,請使用viewholder的getAdapterPosition或getLayoutPosition。 我更喜歡getLayoutPosition,因為它總是返回正確的位置,而getAdapterPosition很少返回錯誤的位置
如果刪除/添加/更改數據集中的任何項目並使用notify方法通知RecyclerView,則RecyclerView不會調用onBindViewHolder方法並更新所有項目的位置,它只會為onBindViewHolder和的新調用更新新項目的位置。這將導致顯示的項目和位置值之間不一致。
有關更多詳細信息,請參見以下帖子:
在您的視圖(recyclerview在其上的Activity或Fragment)類中實現
SearchView.OnQueryTextListener
那么您必須重寫一些方法,其中之一是
@Override public boolean onQueryTextChange(String s) {}
此方法在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是RecyclerView項目模型的列表,當通過輸入文本進行搜索的項目我們將這些項目添加到此列表中
和
項目是所有項目
而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.