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. ie the new items comes as a result of search has the same value I gave to the item before searching
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();
}
};}
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;
} }
<?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>
<?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:
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 prefer getLayoutPosition as it always returns the correct position whereas getAdapterPosition very rarely returns the wrong position
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.
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
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 :
@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
and
items is all of items
and filterInput() method is :
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(
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.