【发布时间】:2021-09-24 03:52:35
【问题描述】:
我想在回收站视图中选择多个项目,当它被选中时,我想将该项目的复选框设置为可见性。所以,我可以使用接口设置onlongClickListner 并在片段中处理onLongClick 事件。
每当用户长按任何项目时,应用程序的onCLick 逻辑都会更改。在长按应用程序之前在另一个活动中打开该项目,但是在长按onClick 后,逻辑被更改并且可以设置任何我想要的。我想在长按后选中与该项目对应的复选框。并希望从加载到回收站视图中的arrayList 添加它。
片段
...
@Override
public void onclick(int position) {
if (!isSelectionMode) {
Intent intent = new Intent(getActivity(), FullPhoto.class);
intent.putExtra("uri", arrayList.get(position).getUri());
startActivity(intent);
}
}
//Support fun to turn selectionMode on, onLongClick event.
@Override
public void onLongClick() {
isSelectionMode = true;
}
...
适配器
...
public static class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener,View.OnLongClickListener {
private final ImageView img;
public CheckBox selection;
OnImageClickListner listner;
OnImageLongClickListener longClickListener;
public MyViewHolder(@NonNull View itemView, OnImageClickListner listner,OnImageLongClickListener longClickListener) {
super(itemView);
this.listner = listner;
this.longClickListener = longClickListener;
itemView.setOnLongClickListener(this); //onLongClickListener is set to all of the RecyclerView Items for once rather than setting on each item in BindViewHolder for repeated times
itemView.setOnClickListener(this); //onClickListener is set to all of the RecyclerView Items for once rather than setting on each item in BindViewHolder for repeated times
img = itemView.findViewById(R.id.img);
selection = itemView.findViewById(R.id.checkbox);
}
@Override
public void onClick(View v) {
listner.onclick(getAdapterPosition()); //Returning the current clicked position
}
@Override
public boolean onLongClick(View v) {
longClickListener.onLongClick();
return true;
}
}
// inner class ends
public interface OnImageClickListner{ //Interface to generate call back when user clicked an image.
void onclick(int position);
}
public interface OnImageLongClickListener{ //Interface to generate call back when user long clicked an image.
void onLongClick();
}
...
在这种情况下,我无法理解如何实现选择跟踪器。我可以使用getAdapterPosition() 获取适配器位置,然后我可以从该索引上的arrayList 中删除元素。但是,我想突出显示position 处的复选框。在这种情况下,我无法实现代码。
我尝试过的事情
我确实尝试从onLongClick(View v) 传递View v,然后将selection 复选框传递给onCLick() 事件。但是,它没有用。
我想从回收站视图中选择项目并将所选项目的可见性设置为VISIBLE。
------ 更新 ------
我现在可以借助事件方法中的少量编辑将复选框的可见性设置为可见。
片段
@Override
public void onclick(int position, CheckBox selection) {
if (!isSelectionMode) {
Intent intent = new Intent(getActivity(), FullPhoto.class);
intent.putExtra("uri", arrayList.get(position).getUri());
startActivity(intent);
}
else
{
selection.setVisibility(View.VISIBLE);
selection.setChecked(true);
}
}
其中selection 是从适配器的MyViewHolder 类传递的复选框。但是,由于回收者视图的性质,我得到了双重选择。还有一个奇怪的问题是,如果我向下滚动选择项目后,选择会随机更改。
如您所见,在这张图片中,我只选择了 4 张图片,但是当我向下滚动时,其他图片也被选择了,当我再次向上滚动时,它弄乱了我选择的项目。
照片适配器
public class PhotosAdapter extends RecyclerView.Adapter<PhotosAdapter.MyViewHolder> {
public Context context;
ArrayList<ImageModel> arrayList;
Activity activity;
OnImageClickListner listener;
OnImageLongClickListener longClickListener;
/*=============================================================== CONSTRUCTOR ===============================================================*/
public PhotosAdapter(Context context, ArrayList<ImageModel> arrayList, Activity activity, OnImageClickListner listner, OnImageLongClickListener longClickListener) {
this.context = context;
this.arrayList = arrayList;
this.activity = activity;
this.listener = listner;
this.longClickListener = longClickListener;
}
/*=============================================================== OVERRIDDEN METHODS ===============================================================*/
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { //This methods returns single_view.xml as a view for RecyclerView.
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_view, parent, false);
return new MyViewHolder(view, listener, longClickListener);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) { //Binding the uris with each view depending upon the position of current view.
activity.runOnUiThread(() -> GlideApp.with(context)
.load(Uri.parse(arrayList.get(position).getUri()))
.apply(RequestOptions.overrideOf(150, 150)) //It overrides the value of original image and reduces it to the visible thumbnail size.
.diskCacheStrategy(DiskCacheStrategy.RESOURCE) //Then it caches the reduced size thumbnail for faster loading speed.
.into(holder.img));
}
@Override
public int getItemCount() {
return arrayList.size();
}
/*=============================================================== INNER VIEW HOLDER CLASS ===============================================================*/
public static class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
private final ImageView img;
public CheckBox selection;
OnImageClickListner listener;
OnImageLongClickListener longClickListener;
public final SparseBooleanArray selectedItems; ///////////////////////////////// ADDED LINE /////////////////////////////////
public MyViewHolder(@NonNull View itemView, OnImageClickListner listener, OnImageLongClickListener longClickListener) {
super(itemView);
this.listener = listener;
this.longClickListener = longClickListener;
itemView.setOnLongClickListener(this); //onLongClickListener is set to all of the RecyclerView Items for once rather than setting on each item in BindViewHolder for repeated times
itemView.setOnClickListener(this); //onClickListener is set to all of the RecyclerView Items for once rather than setting on each item in BindViewHolder for repeated times
img = itemView.findViewById(R.id.img);
selection = itemView.findViewById(R.id.checkbox);
selectedItems = new SparseBooleanArray(); ///////////////////////////////// ADDED LINE /////////////////////////////////
}
@Override
public void onClick(View v) {
listener.onclick(getAdapterPosition(), selection); //Returning the current clicked position and selection checkbox to the implemented method.
}
@Override
public boolean onLongClick(View v) {
longClickListener.onLongClick(getAdapterPosition(), v); //Returning the current clicked position and view to the implemented method.
return true;
}
//////////////////////////////////////////////////////////////////////////// ADDED LINES ////////////////////////////////////////////////////////////////////////////
boolean isSelected(int position) {
return getSelectedItems().contains(position);
}
public void toggleSelection(int position) {
if (selectedItems.get(position, false)) {
selectedItems.delete(position);
} else {
selectedItems.put(position, true);
}
notifyItemChanged(position);
}
public void selectAll() {
for (int i = 0; i < getItemCount(); i++) {
if (!(selectedItems.get(i, false))) {
selectedItems.put(i, true);
}
notifyItemChanged(i);
}
notifyDataSetChanged();
}
public void clearSelection() {
List<Integer> selection = getSelectedItems();
selectedItems.clear();
for (Integer i : selection) {
notifyItemChanged(i);
}
}
public int getSelectedItemCount() {
return selectedItems.size();
}
public List<Integer> getSelectedItems() {
List<Integer> items = new ArrayList<>(selectedItems.size());
for (int i = 0; i < selectedItems.size(); ++i) {
items.add(selectedItems.keyAt(i));
}
return items;
}
} //INNER CLASS ENDS
/*=============================================================== INTERFACES ===============================================================*/
public interface OnImageClickListner { //Interface to generate call back when user clicked an image.
void onclick(int position, CheckBox selection);
}
public interface OnImageLongClickListener { //Interface to generate call back when user long clicked an image.
void onLongClick(int position, View v);
}
}
【问题讨论】:
-
您想要多选项目吗?
-
@AnantaRaha 是的,但是,我已经实现了接口。我见过很多例子,其中开发人员在
onBindViewHolder中设置onClickListener和onLongClickListner,但是我发现如果用户有大量照片,这可能会导致问题。因此,我成功实现了onClickListener和onLongClickListner,但是无法设置选中项目对应的复选框的可见性。
标签: java android android-recyclerview multipleselection