繁体   English   中英

你如何在 android 的 recylerview 中突出显示项目

[英]How do you Highlight items in recylerview in android

我想在长按时突出显示 recylerview 中的项目,我可以做其中的一部分。 问题是,当我在 recylerview 中滚动时,这些项目失去了突出显示的 state 并且当您在滚动后单击它们时, selectList的大小会减小。 唯一的问题是滚动后如何保留他们的 state?

这是适配器 class 中的实现

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder>  {
    private Context mContext;
    public static List<ItemFiles> itemFiles = new ArrayList<>();
    Activity activity;
    public  List<ItemFiles> selectList = new ArrayList<>();
    boolean isModeEnabled = false;

    public MyAdapter(Activity activity,List<ItemFiles> itemFiles,Context mContext) {
        this.activity = activity;
        MyAdapter.itemFiles = itemFiles;
        this.mContext = mContext;

    }

    @NonNull
    @Override
    public MyAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.view,parent,false);
        return new MyViewHolder(view);
    }
    
      public void onBindViewHolder(@NonNull MyAdapter.MyViewHolder holder, int
                position) {
       holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
           if (!isModeEnabled) {
              ActionMode d = new ActionMode.Callback() {
               @Override
               public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                mode.getMenuInflater().inflate(R.menu.mode_menu,menu);
    
                return true;
        }
              @Override
              public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                 isActionModeEnabled = true;
                 ClickItem(holder);
               }
          });
                   return true;
              }
    
     holder.itemView.setOnClickListener(new View.OnClickListener() {
               @Override
               public void onClick(View v) {
                   if (isActionModeEnabled) {
                        ClickItem(holder);
                   }
    
     public void ClickItem(MyViewHolder holder) {
            isSelectMode = true;
    
        ItemFiles s = itemFiles.get(holder.getAdapterPosition());
        if (holder.checkbox.getVisibility() == View.GONE && !selectList.contains(s)){
            selectList.add(s);
            holder.itemView.setBackgroundColor(Color.LTGRAY);
    
        } else {
            holder.itemView.setBackgroundColor(Color.TRANSPARENT);
            selectList.remove(s);
        }
    }
    
    
       public class MyViewHolder extends RecyclerView.ViewHolder {
           ImageView thm_img;
           TextView tv;
            public MyViewHolder(@NonNull View itemView) {
                super(itemView);
                thm_img= itemView.findViewById(R.id.thm_img);
                tv= itemView.findViewById(R.id.vname);
            }
    }

这是 xml 文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:tools="http://schemas.android.com/tools"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical">

  
    <ImageView
        android:id="@+id/th_img"
        android:layout_width="130dp"
        android:layout_height="90dp"
        android:src="@drawable/download"
        android:scaleType="centerCrop"> 
   
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/vname"     
        android:layout_marginStart="10dp"
        android:layout_marginRight="10dp">

    </TextView>
   
  
</RelativeLayout>

这是recyclerview的活动class的xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".Fragment">

         <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize">
         </androidx.appcompat.widget.Toolbar>
 
         <androidx.recyclerview.widget.RecyclerView
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:id="@+id/filesRV"/>
 
      </LinearLayout>

</RelativeLayout>

Model class 是

public class ItemFiles {
    public String id;
    public String path;
    public String title;
    public String fileName;
    public String size;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public String getSize() {
        return size;
    }

    public void setSize(String size) { this.size = size; }

    public ItemFiles(String id, String path, String title, String fileName, String size) {
        this.id = id;
        this.path = path;
        this.title = title;
        this.fileName = fileName;
        this.size = size;
    }

}

我很遗憾地承认,但你正在经历的事情是应该的。

当 Google 创建 RecyclerView 时,他们希望它具有 Data-Driven-UI 模式,这意味着 UI 是有状态的。什么是 state?

所以根据有状态的定义,你必须把每一个有状态的数据放在 Model 上,在这种情况下,长按 state。

尝试复制粘贴下面的代码:

首先,将长按state添加到model:

public class ItemFiles {
  public String id;
  public String path;
  public String title;
  public String fileName;
  public String size;
  public boolean isLongPressed //long press state
  
  //add getters and setters
 
  public String getId() {
    return id;
  }

  ...

二、用户长按时,改变model的值

 public void ClickItem(MyViewHolder holder) {
        isSelectMode = true;
        //Send your model to your viewholder so that you can reference the original model
        //s.setIsLongPressed(true) <-- I have used the code that you provided.
 ...

第三,确保根据您的 state 值对 UI 进行更改以在onBindViewHolder中显示 Highlight。

//A. In your viewholder class, make a method to receieve longPressState value.
public class MyViewHolder extends RecyclerView.ViewHolder {
     ImageView thm_img;
     TextView tv;
     public MyViewHolder(@NonNull View itemView) {
         super(itemView);
         thm_img= itemView.findViewById(R.id.thm_img);
         tv= itemView.findViewById(R.id.vname);
    }
    
    public void setHightLightState(boolean isHighlighted) {
        if (isHighlighted) {
          //make highlight UI changes 
        } else {
          //make NON-highlight UI changes 
        }
    }
}


//B. Then, in your adapter, inside onBindViewHolder, call the new method above from the given holder.
public void onBindViewHolder(@NonNull MyAdapter.MyViewHolder holder, int position) { 
    holder.setHightLightState(/* pass in value from getIsLongPressed() */)
 }

第四,不要忘记刷新你的 recyclerview 以反映它的变化,因为它的数据已经改变了。 您可以使用notifyItemChanged(int position)更新单个项目或使用notifydatasetchanged更新所有项目。

最后,当用户完成长按时,不要忘记在 model 中重置您的长按 state。 否则,longpress state 会一直被回收,这是使用 RecyclerView 时的常见错误。

如果您还有其他问题,请告诉我。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM