Android开发--长按打开编辑操作,支持全选、反选等

1.项目效果图

2.实现技术

(1)长按点击的操作与外部SwipeRecyclerView结合进行使用,这一块具体的操作可以看之前的博客里面有介绍。

(2)其次就是view的显示,当进行长按或者点击编辑时显示checkbox,当正常情况时不显示checkbox

(3)用什么数据结构存储选中状态。Map数据结构Map<Integer,boolean>:

key值为item所在的position,value值为checkbox状态,选中为true,未选中为false

(4)获取选中数据的个数:遍历map集合,统计value值为true

(5)取消:直接将map中的value值全为false

(6)全选:直接将map中的value值全为true

(7)反选:将map中value的值设为当前value值取反后的值

3.代码实现

Activity实现:

这里的代码主要是实现编辑和长按的操作,对于数据的获取没有进行代码展示,这块可以直接看recyclerview的博客:http://t.csdn.cn/ry0Pp

package com.dcampus.weblib.resource;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;

import android.Manifest;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcelable;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.PopupMenu;
import android.widget.TextView;
import android.widget.Toast;


import com.yanzhenjie.recyclerview.OnItemClickListener;
import com.yanzhenjie.recyclerview.OnItemLongClickListener;
import com.yanzhenjie.recyclerview.OnItemMenuClickListener;
import com.yanzhenjie.recyclerview.SwipeMenu;
import com.yanzhenjie.recyclerview.SwipeMenuBridge;
import com.yanzhenjie.recyclerview.SwipeMenuCreator;
import com.yanzhenjie.recyclerview.SwipeMenuItem;
import com.yanzhenjie.recyclerview.SwipeRecyclerView;

import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.schedulers.Schedulers;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import static com.dcampus.weblib.set.SetFragment.mIsWifiMode;

public class MyResourceActivity extends AppCompatActivity{

    //编辑模式
    private final static int CHECK_MODE=0;
    private final static int EDIT_MODE=1;
    private int mEditMode=CHECK_MODE; //初始为未编辑
    private boolean editable = false;     //当前界面是否可编辑
    private Map<Integer,Boolean> map_check=new HashMap<>(); //利用map存储checkbox的状态
    private TextView bt_select_all;
    private int checkedNumber=0; //选中数量
    private TextView edit_mode_title;

    private TextView bt_edit;

    FrameLayout frameLayout_edit;
    Toolbar toolbar_no_edit;
    private SwipeRecyclerView recyclerView;
    private List<DirResponse.OnlineFile> fileList = new ArrayList<>();
    private List<DirResponse.OnlineFile> files=new ArrayList<>();
    private ResourceAdapter resourceAdapter;
   
    private TextView bt_edit_cancel;
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my_resource);
      
        bt_select_all=findViewById(R.id.button_select_all);
        //全选
        bt_select_all.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getSelectAll();

            }
        });
        edit_mode_title=findViewById(R.id.edit_mode_title);
        frameLayout_edit=findViewById(R.id.toolbar_edit);
        toolbar_no_edit=findViewById(R.id.toolbar_rm);
         //编辑模式中取消按钮
        bt_edit_cancel=findViewById(R.id.button_edit_cancel);
        bt_edit_cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                hideEdit();
                //将目前checkbox全部为false
              //  Set<Map.Entry<Integer,Boolean>> set=map_check.entrySet();
             //   for(Map.Entry<Integer,Boolean> entry:set){
             //       entry.setValue(false);
            //    }

            }
        });


     

        swipeRefreshLayout =findViewById(R.id.ll_refresh);
        bt_edit=findViewById(R.id.bt_title);
       

        recyclerView =findViewById(R.id.rv_resourcemanage);
        //设置分割线
        DividerItemDecoration decoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL);
        recyclerView.addItemDecoration(decoration);
      
       

        initR();
        //加载控件
        initView();

        getResourceData3();
  
        //点击编辑
        bt_edit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                updateEditMode();

            }
        });

      
  
    //得到资源列表
    private void getResourceData3(){
       //这一部分可以写自己加载recyclerView数据
    }

   

    //全选方法
    private void getSelectAll() {
        resourceAdapter.selectAll();
        checkedNumber=resourceAdapter.getCheckedNumber();
        if(checkedNumber!=0){
            edit_mode_title.setText("已选择"+checkedNumber+"项");
        }else{
            edit_mode_title.setText("请选择文件");
        }
    }

    //隐藏编辑模式
    private void hideEdit(){
        mEditMode=EDIT_MODE;
        updateEditMode();
        resourceAdapter.cancel();    //将map中的值均变成false
        getCheckNumber();
    }

    private void getCheckNumber(){
        checkedNumber=resourceAdapter.getCheckedNumber();
        System.out.println("checknumber1"+checkedNumber);

        if(checkedNumber!=0){
            edit_mode_title.setText("已选择"+checkedNumber+"项");
        }else{
            edit_mode_title.setText("请选择文件");
        }
    }

    //更新编辑模式
    private void updateEditMode() {
        mEditMode= mEditMode==CHECK_MODE ? EDIT_MODE :CHECK_MODE;
        if(mEditMode==EDIT_MODE){
            //当前页面可以编辑
            frameLayout_edit.setVisibility(View.VISIBLE);
            toolbar_no_edit.setVisibility(View.GONE);
            bottomBar.setVisibility(View.GONE);
            bottomBar_edit.setVisibility(View.VISIBLE);
            editable=true;


        }
        else{
            //当前页面不可编辑
            toolbar_no_edit.setVisibility(View.VISIBLE);
            bottomBar.setVisibility(View.VISIBLE);
            bottomBar_edit.setVisibility(View.GONE);
            editable=false;
        }
        resourceAdapter.setEditMode(mEditMode);
    }

    

    private void initR(){
        //可以直接调用swipeRecyclerView框架里面的点击子项、点击长按事件
        recyclerView.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {
                //不可编辑模式下点开文件夹或下载
                if(editable==false){
                   //不可编辑模式下自己做的操作
                }
                if(editable==true){
                    //可编辑模式下
                    map_check.put(position,!map_check.get(position));
                    resourceAdapter.notifyDataSetChanged();
                    //获得选中数量
                    checkedNumber=resourceAdapter.getCheckedNumber();
                    System.out.println("check1"+checkedNumber);
                    if(checkedNumber!=0){
                        edit_mode_title.setText("已选择"+checkedNumber+"项");
                        //得到选择id数组
                        chooseId=new int[checkedNumber];
                        chooseId=resourceAdapter.getChooseID();
                        choosePosition=resourceAdapter.getChoosePosition();
                        for (int i = 0; i < chooseId.length; i++) {
                            Log.d("choose数量", String.valueOf(chooseId.length));
                            Log.d("choose", String.valueOf(chooseId[i]));
                        }

                    }else{
                        edit_mode_title.setText("请选择文件");
                    }

                }
            }
        });
        //长按
        recyclerView.setOnItemLongClickListener(new OnItemLongClickListener() {
            @Override
            public void onItemLongClick(View view, int position) {
                if(mEditMode==CHECK_MODE){
                    //进入编辑
                    updateEditMode();
                  //  map_check.put(position,true);
                    resourceAdapter.selectOne(position);
                    checkedNumber=resourceAdapter.getCheckedNumber();
                    if(checkedNumber!=0){
                        edit_mode_title.setText("已选择"+checkedNumber+"项");
                    }else{
                        edit_mode_title.setText("请选择文件");
                    }
                }else{
                    hideEdit();
                }

        });
    }

    //recyclerview
    private void initView() {
        //找到控件
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(MyResourceActivity.this, LinearLayoutManager.VERTICAL, false);
        recyclerView.setLayoutManager(linearLayoutManager);
        resourceAdapter = new ResourceAdapter(fileList, MyResourceActivity.this,map_check);
        recyclerView.setAdapter(resourceAdapter);
       

    }

   
    }
}

Adapter实现:

同样主要是实现编辑的操作,在数据加载部分没有做多余的展示。

package com.dcampus.weblib.resource;

import android.content.Context;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import org.apache.commons.lang3.StringUtils;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.dcampus.weblib.R;
import com.dcampus.weblib.WebLibApplication;
import com.dcampus.weblib.api.ResourceApiService;
import com.dcampus.weblib.bean.entityRoom.DBResourceThumbnail;
import com.dcampus.weblib.bean.response.resource.GetResourcesResponse;
import com.dcampus.weblib.bean.response.resource.GetThumbnailResponse;
import com.dcampus.weblib.data.constant.FileType;
import com.dcampus.weblib.data.repository.ResourceThumbnailRepository;
import com.dcampus.weblib.data.resource.NewNode;
import com.dcampus.weblib.data.resource.Resource;
import com.dcampus.weblib.data.resource.download.DownloadInfo;
import com.dcampus.weblib.network.RetrofitUtils;
import com.dcampus.weblib.utils.FileUtil;
import com.dcampus.weblib.utils.StringUtil;
import com.facebook.drawee.view.SimpleDraweeView;

import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.SingleObserver;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.schedulers.Schedulers;
import retrofit2.http.Url;

public class ResourceAdapter extends RecyclerView.Adapter<ResourceAdapter.MyViewHolder> {
    private final static int CHECK_MODE=0;
    private int mEditMode=CHECK_MODE;
    private List<DirResponse.OnlineFile> fileList=new ArrayList<>();
    private List<Integer> resourceWithThumbnail=new ArrayList<>();
    private Context context;
    private Map<Integer,Boolean> map_check=new HashMap<>(); //利用map存储checkbox的状态

    private int number;
   
    public ResourceAdapter(List<DirResponse.OnlineFile> fileList, Context context, Map<Integer, Boolean> map_check) {
        this.fileList = fileList;
        this.context = context;
        this.map_check = map_check;
    }

    public ResourceAdapter(List<DirResponse.OnlineFile> fileList, Context context) {
        this.fileList = fileList;
        this.context = context;
    }

   

    //找到view
    @NonNull
    @NotNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) {
        View view= LayoutInflater.from(context).inflate(R.layout.list_item_resource_manage,null);
        return new MyViewHolder(view);
    }


    

    //给每个item赋值
    @Override
    public void onBindViewHolder(@NonNull @NotNull ResourceAdapter.MyViewHolder holder, int position) {

       


        //判断是否为可编辑状态
        if(mEditMode==CHECK_MODE){
            holder.checkBox.setVisibility(View.GONE);
        }else{
            holder.checkBox.setVisibility(View.VISIBLE);
            holder.checkBox.setChecked(map_check.get(position));
        }
    }

   



//返回item的数量
    @Override
    public int getItemCount() {
        return fileList.size();
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {
        private SimpleDraweeView type;//文件类型
        private TextView name;//文件名
        private TextView tvDesc;               //资源大小(文件)
        private ImageView iv_next;//下一步
        private CheckBox checkBox;
        private TextView tvFolder;             //资源名(文件夹、柜子、分类)
        private TextView tvFolderProcess;      //资源下载进度(文件夹)
        private LinearLayout llDetail;         //文件资源名与资源大小显示的外层 layout,用于隐藏和显示
        private ProgressBar pbBackground;      //item 下载进度背景

        public MyViewHolder(@NonNull @NotNull View itemView) {
            super(itemView);
            type = itemView.findViewById(R.id.iv_node_img);
            name = itemView.findViewById(R.id.weblib_item_name);
            iv_next=itemView.findViewById(R.id.iv_arrow);
            checkBox=itemView.findViewById(R.id.list_cb);
            tvFolder = itemView.findViewById(R.id.tv_folder);
            tvFolderProcess = itemView.findViewById(R.id.tv_folder_process);
            llDetail = itemView.findViewById(R.id.ll_detail);
            pbBackground = itemView.findViewById(R.id.pb_background);
            tvDesc = itemView.findViewById(R.id.descTextView);
            /*
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(onItemClickListener!=null){

                            onItemClickListener.click(itemView,getAdapterPosition());
                            if(mEditMode!=CHECK_MODE){
                              //  checkBox.setChecked(true);
                                map_check.put(getAdapterPosition(),!map_check.get(getAdapterPosition()));
                             //   System.out.println(map_check);
                                notifyDataSetChanged();

                            }
                    }
                }
            });
             */
            //点击事件
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //更新map的boolean值
                    map_check.put(getAdapterPosition(),!map_check.get(getAdapterPosition()));
                    notifyDataSetChanged();
                    onItemClickListener.click(v,getAdapterPosition());
                }
            });
            itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    if(onItemLongClickListener!=null){
                        onItemLongClickListener.longClick(itemView,getAdapterPosition());
                    }
                    return true;
                }
            });

        }

    }


 
    //得到选择数量
    public int getCheckedNumber(){
        number=0;
        if(mEditMode!=CHECK_MODE){
            Set<Map.Entry<Integer,Boolean>> set=map_check.entrySet();
            for(Map.Entry<Integer,Boolean>entry:set){
                //entry.getvalue为true表示选中
                if(entry.getValue()&& number< fileList.size()){
                    number=number+1;
                }
            }
        }
        System.out.println(number+"number");
        return number;
    }
    //得到选择的position
    public int[] getChoosePosition() {
        List<Integer> choosePosition_list = new ArrayList<>();
        if (mEditMode != CHECK_MODE) {
            if (number != 0) {
                choosePosition = new int[number];
                //遍历map集合
                Set<Map.Entry<Integer, Boolean>> set = map_check.entrySet();
                for (Map.Entry<Integer, Boolean> entry : set) {
                    if (entry.getValue()) {
                        //先将id添加到list集合中
                        choosePosition_list.add(entry.getKey());
                    }
                }
                //将list集合转成数组形式
                for (int i = 0; i < choosePosition_list.size(); i++) {
                    choosePosition[i] = choosePosition_list.get(i);
                }
            }
        }
        return choosePosition;
    }

  

    //取消方法
    public void cancel(){
        Set<Map.Entry<Integer,Boolean>> set=map_check.entrySet();
        for(Map.Entry<Integer,Boolean> entry:set){
            entry.setValue(false);
        }
        getCheckedNumber();
        notifyDataSetChanged();
    }

    //全选
    public void selectAll(){
        boolean isChecked=false;
        //遍历map
        Set<Map.Entry<Integer,Boolean>> set=map_check.entrySet();
        for(Map.Entry<Integer,Boolean> entry:set){
            if(entry.getValue()==false){
                isChecked=true;
                break;
            }
        }
        for(Map.Entry<Integer,Boolean> entry:set){
            entry.setValue(isChecked);
        }
        getCheckedNumber();
        notifyDataSetChanged();
    }
    //将长按的item选中
    public void selectOne(int position){
        map_check.put(position,true);
        getCheckedNumber();

        notifyDataSetChanged();
    }
   

    //更新编辑模式
    public void setEditMode(int editMode) {
        mEditMode = editMode;
        notifyDataSetChanged();
    }

   
}

View层:

activity中的view层可以直接由一个recyclerView展示,上面两个button按钮就行,由于项目的问题就不做这个的展示

主要可以看一下每个item的view,这里涉及到checkbox的展示:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:fresco="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="@dimen/item_height_48dp">

    <RelativeLayout
        android:id="@+id/rv_flag"
        android:tag="slide_flag"
        android:layout_width="match_parent"
        android:background="@drawable/bg_white_item_clickable"
        android:layout_height="@dimen/item_height_48dp">


        <CheckBox
            android:id="@+id/list_cb"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginStart="10dp"
            android:layout_marginEnd="4dp"
            android:visibility="gone"
            android:button="@drawable/selector_cb_blue" />

        <ProgressBar
            android:id="@+id/pb_background"
            style="?android:attr/progressBarStyleHorizontal"
            android:layout_width="match_parent"
            android:layout_height="@dimen/item_height_48dp"
            android:layout_alignParentTop="true"
            android:layout_toEndOf="@+id/list_cb"
            android:progressDrawable="@drawable/my_progressbar"
            android:visibility="invisible" />


        <com.facebook.drawee.view.SimpleDraweeView
            android:id="@+id/iv_node_img"
            android:layout_width="50dp"
            android:layout_height="@dimen/item_height_48dp"
            android:layout_toEndOf="@+id/list_cb"
            android:contentDescription="@string/desc"
            android:padding="6dp"
             />

        <TextView
            android:id="@+id/tv_folder"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginEnd="48dp"
            android:layout_toEndOf="@+id/iv_node_img"
            android:textColor="#000000"
            android:textSize="@dimen/list_item_text_size_15sp"
            android:maxLines="1"
            android:ellipsize="end" />

        <LinearLayout
            android:id="@+id/ll_detail"
            android:layout_width="wrap_content"
            android:layout_height="@dimen/item_height_48dp"
            android:layout_gravity="center_vertical"
            android:orientation="vertical"
            android:layout_toEndOf="@+id/tv_folder"
            android:layout_marginEnd="48dp">

            <TextView
                android:id="@+id/weblib_item_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="2"
                android:gravity="bottom"
                android:textSize="@dimen/list_item_text_size_15sp"
                android:maxLines="1"
                android:ellipsize="end" />

            <TextView
                android:id="@+id/descTextView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="2"
                android:textSize="13sp" />

        </LinearLayout>

        <TextView
            android:id="@+id/tv_folder_process"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toLeftOf="@id/iv_arrow"
            android:layout_centerVertical="true"
            android:layout_marginRight="10dp"
            android:textColor="@color/gray"
            android:visibility="invisible" />

        <ImageView
            android:id="@+id/iv_arrow"
            android:layout_width="wrap_content"
            android:layout_height="24dp"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="10dp"
            android:contentDescription="@string/desc"
            android:src="@drawable/arrow" />

        <ImageView
            android:id="@+id/ic_drag_handle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:layout_centerVertical="true"
            android:layout_marginEnd="10dp"
            android:src="@drawable/ic_drag_handle_grey"
            android:contentDescription="@null"
            android:visibility="gone" />

        <ImageView
            android:id="@+id/button_watch"
            android:layout_width="@dimen/item_height_48dp"
            android:layout_height="@dimen/item_height_48dp"
            android:layout_alignParentEnd="true"
            android:layout_centerVertical="true"
            android:padding="4dp"
            android:visibility="gone"
            android:src="@drawable/ic_watch_selectable"
            android:background="@drawable/bg_white_item_clickable"
            android:scaleType="centerInside"
            android:contentDescription="@null" />

    </RelativeLayout>

</RelativeLayout>

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值