Цель: отслеживать выбранные элементы в recyclerview, используя изменяющийся Imageview для каждой строки. Практически я устанавливаю своего рода флажок.
Проверка работает нормально:
но когда я пытаюсь найти некоторые элементы, отмеченные элементы меняются: проверяется только первый элемент моего списка:
Я отправлю свой код ниже:
Выбранный интерфейс магазина
public interface NearestShopActivityAdapterListener {
void onShopSelected(FShop shop, View view);
}
Держатель My View
public class MyHolder extends RecyclerView.ViewHolder{
public TextView name, address;
public ImageView logo;
public MyHolder(View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.activityNearestShopListItemUhop);
address = (TextView) itemView.findViewById(R.id.activityNearestShopListItemAddress);
logo = (ImageView) itemView.findViewById(R.id.activityNearestShopListItemImage);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
listener.onShopSelected(filteredShopList.get(getAdapterPosition()),view);
}
});
}
onShopSelected функция
@Override
public void onShopSelected(FShop shop, View view) {
if (checkList.contains(shop.getShopId())){
mImgViewCheckBox = (ImageView) view.findViewById(R.id.checkBoxNearestShop);
mImgViewCheckBox.setImageResource(R.drawable.checkbox_selector_not_checked);
checkList.remove(shop.getShopId());
}else {
mImgViewCheckBox = (ImageView) view.findViewById(R.id.checkBoxNearestShop);
mImgViewCheckBox.setImageResource(R.drawable.ic_checked);
checkList.add(shop.getShopId());
}
}
Где я не прав? Я бы попытался связать ImageView mImgViewCheckBox с идентификатором магазина, а не с его позицией в recyclerview, но я понятия не имею, как это сделать. Спасибо заранее.
Я попытался лучше объяснить свою проблему. Благодарю за ответ.
Попробуйте вызвать notifyDataSetChanged (); в onShopSelected () после внесения изменений в контрольный список
Всякий раз, когда вы проверяете свой флажок .. обновите в своей модели, а затем примените notifydatasetChanged.
вы должны сохранить флажок в массиве или хеш-карте.
я сделал это в контактных данных. Я предоставляю свой адаптер и метод, в котором вы можете изменить код в соответствии с вашими потребностями.
InviteContactAdapter.java
public class InviteContactAdapter extends RecyclerView.Adapter<InviteContactAdapter.ItemViewHolder> implements Filterable {
private List<UserContact> mContactList = new ArrayList<>();
private List<UserContact> mContectFilter = new ArrayList<>();
private Context mContext;
private CustomFilter mFilter;
public List<String> mEmailList = new ArrayList<>();
public InviteContactAdapter(Context context, List<UserContact> mContactList) {
mContext = context;
this.mContactList = mContactList;
this.mContectFilter = mContactList;
mFilter = new CustomFilter();
}
public onItemClickListener onItemClickListener;
public void setOnItemClickListener(InviteContactAdapter.onItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
@Override
public ItemViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.invite_contact_row_layout, viewGroup, false);
return new ItemViewHolder(view);
}
public interface onItemClickListener {
void onClick(UserContact contact);
}
@Override
public Filter getFilter() {
return mFilter;
}
@Override
public void onBindViewHolder(final ItemViewHolder itemViewHolder, int i) {
final UserContact contact = mContectFilter.get(i);
itemViewHolder.mTvUserNane.setText(contact.getUserName().trim());
itemViewHolder.mTvUserEmail.setText(contact.getUserEmail().trim());
if (contact.isSelect())
itemViewHolder.mIvSelect.setImageResource(R.drawable.check_contect);
else
itemViewHolder.mIvSelect.setImageResource(R.drawable.un_check_contact);
itemViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (contact.isSelect()) {
contact.setSelect(false);
itemViewHolder.mIvSelect.setImageResource(R.drawable.un_check_contact);
} else {
contact.setSelect(true);
itemViewHolder.mIvSelect.setImageResource(R.drawable.check_contect);
}
}
});
}
@Override
public int getItemCount() {
return mContectFilter.size();
}
public class ItemViewHolder extends RecyclerView.ViewHolder {
private TextView mTvUserNane, mTvUserEmail;
private ImageView mIvSelect;
public ItemViewHolder(View itemView) {
super(itemView);
mTvUserEmail = itemView.findViewById(R.id.icrlTvUserEmail);
mTvUserNane = itemView.findViewById(R.id.icrlTvUserName);
mIvSelect = itemView.findViewById(R.id.icrlIvSelect);
}
}
public List<String> getEmail() {
mEmailList.clear();
for (UserContact contact : mContectFilter) {
if (contact.isSelect()) {
mEmailList.add(contact.getUserEmail());
}
}
return mEmailList;
}
/**
* this class for filter data.
*/
class CustomFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
FilterResults results = new FilterResults();
if (charSequence != null && charSequence.length() > 0) {
ArrayList<UserContact> filters = new ArrayList<>();
charSequence = charSequence.toString().toUpperCase();
for (int i = 0; i < mContactList.size(); i++) {
if (mContactList.get(i).getUserName().toUpperCase().contains(charSequence) || mContactList.get(i).getUserEmail().toUpperCase().contains(charSequence)) {
UserContact contact = new UserContact();
contact.setUserName(mContactList.get(i).getUserName());
contact.setUserEmail(mContactList.get(i).getUserEmail());
filters.add(contact);
}
}
results.count = filters.size();
results.values = filters;
} else {
results.count = mContactList.size();
results.values = mContactList;
}
return results;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
mContectFilter = (ArrayList<UserContact>) filterResults.values;
notifyDataSetChanged();
}
}
}
затем после привязки контактных данных к просмотру ресайклера и поиску данных на основе имени и адреса электронной почты .. сделать набор адаптеров метод ..
private void setAdapter(){
if (!mContactList.isEmpty()) {
inviteContactAdapter = new InviteContactAdapter(getActivity(), mContactList);
mRvData.setAdapter(inviteContactAdapter);
inviteContactAdapter.setOnItemClickListener(new InviteContactAdapter.onItemClickListener() {
@Override
public void onClick(UserContact contact) {
mEmailList.add(contact.getUserEmail());
}
});
} else {
mTvEmpty.setVisibility(View.VISIBLE);
}
}
затем после создания метода данных поиска ...
/**
* this method sort data.
*/
private void sortData(View root) {
mEtSearchData = (EditText) root.findViewById(R.id.icffEtSearch);
mEtSearchData.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) {
if (inviteContactAdapter != null) {
inviteContactAdapter.getFilter().filter(s);
}
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
после получения контактных данных будет работать. и вы можете изменить свой код в соответствии с.
Я изменил свой код на основе вашего, и он отлично работал! Спасибо, мужик!
У меня также есть несколько шаблонов, которые я использую каждый раз, когда мне нужен режим ресайклера.
Разница в том, что я использую еще одно дополнительное свойство в каждом элементе списка, поэтому в основном вы не зависите от фильтрации, сортировки или чего-то еще.
Это XML для активности:
<?xml version = "1.0" encoding = "utf-8"?>
<android.support.constraint.ConstraintLayout 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 = "com.arnela.nihad.expresssaladbar.RecyclerViewExample.RecyclerViewActivity">
<SearchView
android:id = "@+id/searchViewBox"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:layout_marginEnd = "8dp"
android:layout_marginStart = "8dp"
android:layout_marginTop = "8dp"
android:layout_marginBottom = "8dp"
android:layout_weight = "1"
android:iconifiedByDefault = "false"
android:queryHint = "HINT"
app:layout_constraintEnd_toEndOf = "parent"
app:layout_constraintStart_toStartOf = "parent"
app:layout_constraintTop_toTopOf = "parent" />
<android.support.v7.widget.RecyclerView
android:id = "@+id/recycler_view"
android:layout_width = "0dp"
android:layout_height = "0dp"
android:layout_marginTop = "8dp"
android:clipToPadding = "false"
app:layout_constraintBottom_toBottomOf = "parent"
app:layout_constraintEnd_toEndOf = "parent"
app:layout_constraintStart_toStartOf = "parent"
app:layout_constraintTop_toBottomOf = "@+id/searchViewBox" />
</android.support.constraint.ConstraintLayout>
Следующий Java-класс RecyclerViewActivity:
public class RecyclerViewActivity extends AppCompatActivity {
private RecyclerView mRecyclerList;
private RecyclerViewAdapter mRecyclerAdapter;
private List<DataVm> mSourceList = new ArrayList<>();
private SearchView txtSearchBox;
private Data data;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recyler_view);
data = new Data();
mSourceList.addAll(data.getSourceList(""));
// this is recycler view from xml
mRecyclerList = findViewById(R.id.recycler_view);
InitRecyclerView();
txtSearchBox = findViewById(R.id.searchViewBox);
txtSearchBox.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) {
mSourceList.clear();
mSourceList.addAll(data.getSourceList(s));
mRecyclerAdapter.notifyDataSetChanged();
return false;
}
@Override
public boolean onQueryTextChange(String s) {
mSourceList.clear();
mSourceList.addAll(data.getSourceList(s));
mRecyclerAdapter.notifyDataSetChanged();
return false;
}
});
}
public void InitRecyclerView() {
mRecyclerList.setLayoutManager(new LinearLayoutManager(RecyclerViewActivity.this));
mRecyclerAdapter = new RecyclerViewAdapter(mSourceList, new IClickListenerAddRemove() {
@Override
public void onPositionClicked(int position, boolean isPicked) {
mSourceList.get(position).setPicked(isPicked);
}
});
mRecyclerList.setAdapter(mRecyclerAdapter);
}
}
Затем у меня есть два вспомогательных класса, один для создания данных макета с методом поиска:
public class Data {
private List<DataVm> sourceList = null;
public Data() {
this.sourceList = new ArrayList<>();
// Items of the list and set all items to isPicked to false
sourceList.add(new DataVm(1, "Title 1", "Description 1", "", false));
sourceList.add(new DataVm(2, "Title 2", "Description 2", "", false));
sourceList.add(new DataVm(3, "Title 3", "Description 3", "", false));
sourceList.add(new DataVm(4, "Title 4", "Description 4", "", false));
sourceList.add(new DataVm(5, "Title 5", "Description 5", "", false));
sourceList.add(new DataVm(6 , "Title 6 ", "Description 6 ", "", false));
sourceList.add(new DataVm(7 , "Title 7 ", "Description 7 ", "", false));
sourceList.add(new DataVm(8 , "Title 8 ", "Description 8 ", "", false));
sourceList.add(new DataVm(9 , "Title 9 ", "Description 9 ", "", false));
sourceList.add(new DataVm(10, "Title 10", "Description 10", "", false));
sourceList.add(new DataVm(11, "Title 11", "Description 11", "", false));
sourceList.add(new DataVm(12, "Title 12", "Description 12", "", false));
}
public List<DataVm> getSourceList(String searchTitle) {
if (searchTitle.equals(""))
return sourceList;
List<DataVm> filteredList = new ArrayList<>();
for (DataVm item : sourceList) {
if (item.getTitle().contains(searchTitle)) {
filteredList.add(item);
}
}
return filteredList;
}
public void setSourceList(List<DataVm> sourceList) {
this.sourceList = sourceList;
}
}
А второй вспомогательный класс - это в основном элемент класса для каждой строки:
public class DataVm {
private int ItemId;
private String Title;
private String Description;
private String Image;
private boolean IsPicked;
public DataVm (int itemId, String title, String description, String image, boolean isPicked) {
ItemId = itemId;
Title = title;
Description = description;
Image = image;
IsPicked = isPicked;
}
public int getItemId() {
return ItemId;
}
public void setItemId(int itemId) {
ItemId = itemId;
}
public String getTitle() {
return Title;
}
public void setTitle(String title) {
Title = title;
}
public String getDescription() {
return Description;
}
public void setDescription(String description) {
Description = description;
}
public String getImage() {
return Image;
}
public void setImage(String image) {
Image = image;
}
public boolean isPicked() {
return IsPicked;
}
public void setPicked(boolean picked) {
IsPicked = picked;
}
}
Наконец, два последних класса - это адаптер для списка и держатель представления для него.
Класс адаптера:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<DataVm> mItemList;
private IClickListenerAddRemove listener;
public RecyclerViewAdapter(List<DataVm> itemList, IClickListenerAddRemove listener) {
mItemList = itemList;
this.listener = listener;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.salad_creation_item_template, parent, false);
return new RecyclerViewHolder(view, listener);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
RecyclerViewHolder holder = (RecyclerViewHolder) viewHolder;
DataVm item = mItemList.get(position);
holder.setTitle(item.getTitle());
holder.setDescription(item.getDescription());
holder.setIsPicked(item.isPicked());
if (item.isPicked())
holder.setButtonDrawable(R.drawable.ic_remove_24dp);
else
holder.setButtonDrawable(R.drawable.ic_add_24dp);
}
@Override
public int getItemCount() {
return mItemList == null ? 0 : mItemList.size();
}
}
И последний - держатель просмотра для списка:
public class RecyclerViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView txtTitle;
private TextView txtDescription;
private ImageButton btnChecking;
private WeakReference<IClickListenerAddRemove> listenerRef;
private boolean mIsPicked = false;
public RecyclerViewHolder(View root, IClickListenerAddRemove listener) {
super(root);
listenerRef = new WeakReference<>(listener);
txtTitle = root.findViewById(R.id.txtTitle);
txtDescription = root.findViewById(R.id.txtDescription);
btnChecking = root.findViewById(R.id.btnAction);
btnChecking.setOnClickListener(this);
}
public void setIsPicked(boolean mIsPicked) {
this.mIsPicked = mIsPicked;
}
public void setTitle(CharSequence text) {
txtTitle.setText(text);
}
public void setDescription(CharSequence text) {
txtDescription.setText(text);
}
public void setButtonDrawable(int drawableId) {
btnChecking.setImageResource(drawableId);
}
@Override
public void onClick(View v) {
if (v.getId() == btnChecking.getId()) {
if (!mIsPicked) {
btnChecking.setImageResource(R.drawable.ic_remove_24dp);
mIsPicked = true;
}
else {
btnChecking.setImageResource(R.drawable.ic_add_24dp);
mIsPicked = false;
}
listenerRef.get().onPositionClicked(getAdapterPosition(), mIsPicked);
}
}
}
Я не уверен, что полностью следую первым двум абзацам. Возможно, вы сможете обновить его немного подробнее.