一个RecyclerView展示不同列表可动态滑动删减的相册

简单说明主要处理有滑动事件的监听,不同布局的加载条目间距,及条目动态删减和不同条目间的间距处理,添加了简单的新控件快捷菜单,整体代码挺乱,如果谁有更好的条目删减及滑动事件处理麻烦给份相关链接

效果图
demo展示.gif

开始定义

1.获取图片信息

private void initData() {
        mHandler = new Main2Activity.MyHandler(this);
        new Thread() {
            @Override
            public void run() {
                List<PhotoBean> list = new ArrayList<PhotoBean>();
                List<String> list1 = new ArrayList<String>();
                super.run();
                Cursor cursor = resolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null, MediaStore.Images.Media.DATE_TAKEN + " desc");
                if (cursor != null && cursor.moveToFirst()) {
                    do {
                        String path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA));
                        long date = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATE_TAKEN));
                        long id=cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID));
                        String name=cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME));
                        String dec=cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME));
                        Date date1 = new Date(date);
                        String Sdate = format.format(date1);
                        if (!list1.contains(Sdate)) {
                            list1.add(Sdate);
                            PhotoBean photoBean1 = new PhotoBean(true,Sdate);
                            list.add(photoBean1);
                            Log.d("szjjyh","11111111111=");
                        }
                        PhotoBean photoBean = new PhotoBean(path, Sdate,id,dec,name);
                        Log.d("szjjyh","22222222");
                        list.add(photoBean);
                    } while (cursor.moveToNext());
                    cursor.close();
                    Message msg = new Message();
                    msg.what = 1;
                    Bundle bundle = new Bundle();
                    ArrayList allList = new ArrayList();
                    allList.add(list);
                    allList.add(list1);
                    bundle.putParcelableArrayList("photos", allList);

                    msg.setData(bundle);
                    mHandler.sendMessage(msg);
                }

            }
        }.start();
    }


//RecyclerView基本信息
    private static class MyHandler extends Handler implements PhotoitemClickListener {
        WeakReference<Main2Activity> mWeakReference;
        MyHandler(Main2Activity activty) {
            mWeakReference = new WeakReference<Main2Activity>(activty);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 1:
                    Bundle bundle = msg.getData();
                    mPhotoFiles = (ArrayList<PhotoBean>) bundle.getParcelableArrayList("photos").get(0);

                    mAdapter = new PhotoRecViewAdapter(mWeakReference.get(), mPhotoFiles);
                    GridLayoutManager layoutManager = new GridLayoutManager(mWeakReference.get(), 4);
    //加载不同的布局后面
                    layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                        @Override
                        public int getSpanSize(int position) {
                            return mPhotoFiles.get(position).isTitle?4:1;
                        }
                    });
                    mWeakReference.get().mRv.addItemDecoration(new PhotoItemDecoration(layoutManager.getSpanCount(), mWeakReference.get()));
                    mWeakReference.get().mRv.setLayoutManager(layoutManager);
                    mWeakReference.get().mRv.setAdapter(mAdapter);
                    mAdapter.setOnItemClickListener(this);

            }
        }

        @Override
        public void onItemClick(View itemView, int position) {
            Toast.makeText(mWeakReference.get(),"路径="+mPhotoFiles.get(position).getPath(),Toast.LENGTH_SHORT).show();
        }

//图片长按点击事件
        @Override
        public void onLongItemClick(View itemView, int position) {
            mWeakReference.get().mRv.setDragSelectActive(true, position);
            mWeakReference.get().mLinview.setVisibility(View.VISIBLE);
        }
    }
//底部删除取消,及全选按钮点击事件
class onclickListener implements View.OnClickListener {

        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.list_space_photo_lin_cancel:
                    for (int i = 0; i< mPhotoFiles.size(); i++){
                        if (!mPhotoFiles.get(i).isTitle) {
                            mPhotoFiles.get(i).mSelected = false;
                        }
                    }
                    mAdapter.setSelected(-1,false);
                    mAdapter.notifyDataSetChanged();
                    mLinview.setVisibility(View.GONE);
                    break;
                case R.id.list_space_photo_lin_del:
                    Iterator<PhotoBean> it = mPhotoFiles.iterator();
                    while(it.hasNext()){
                        PhotoBean x = it.next();
                        if(x.mSelected){
                            it.remove();
                        }
                    }

                    for (int i = 0; i< mPhotoFiles.size(); i++){
                        if (i< mPhotoFiles.size()+1) {
                            if (mPhotoFiles.get(i).isTitle && mPhotoFiles.get(i + 1).isTitle) {
                                mPhotoFiles.remove(i);
                                i--;
                            }
                        }
                        if (mPhotoFiles.get(mPhotoFiles.size()-1).isTitle){
                            mPhotoFiles.remove(mPhotoFiles.size()-1);
                            i--;
                        }
                    }

                    PhotoNode.getInstance().setArrayList(mPhotoFiles);
                    mAdapter.setSelected(-1, false);
                    mAdapter.notifyDataSetChanged();
                    mLinview.setVisibility(View.GONE);
                    break;

                case R.id.list_space_photo_lin_all:
                    for (int i = 0; i< mPhotoFiles.size(); i++){
                        if (!mPhotoFiles.get(i).isTitle) {
                            mPhotoFiles.get(i).mSelected = true;
                        }
                    }
                    mAdapter.notifyDataSetChanged();
                    break;

                default:
                    break;
            }
        }
    }

2.对滑动事件处理自定义RecyclerView

package com.qiku.face.external.facelock360.spacephoto;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import com.qiku.face.external.facelock360.spacephoto.test2.PhotoRecViewAdapter;

public class PhotoSelectRecyclerView extends RecyclerView {

    private float mInitialDownX;
    private float mInitialDownY;

    public PhotoSelectRecyclerView(Context context) {
        super(context);
    }

    public PhotoSelectRecyclerView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public PhotoSelectRecyclerView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    private int mLastDraggedIndex = -1;
    private PhotoRecViewAdapter mAdapter;
    private int mInitialSelection;
    private boolean mDragSelectActive;
    boolean isBeingSlide;
    private int mMinReached;
    private int mMaxReached;

    public void setDragSelectActive(boolean active, int initialSelection) {
        if (initialSelection ==-1) {
            mAdapter.setSelected(initialSelection, active);
        }
        mLastDraggedIndex = -1;
        mDragSelectActive = active;
        isBeingSlide=active;
        mInitialSelection = initialSelection;
        mLastDraggedIndex = initialSelection;
        mMinReached = -1;
        mMaxReached = -1;
    }

    public void setAdapter(PhotoRecViewAdapter adapter) {
        super.setAdapter(adapter);
        mAdapter = adapter;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent e) {
        return super.onInterceptTouchEvent(e);
    }
    @Override
    public boolean dispatchTouchEvent(MotionEvent e) {
        if (mDragSelectActive) {
            if (e.getAction() == MotionEvent.ACTION_DOWN) {
                mInitialDownX = e.getX();
                mInitialDownY = e.getY();
            }else if (e.getAction() == MotionEvent.ACTION_UP) {
               // mDragSelectActive = false;
                isBeingSlide =false;
            } else if (e.getAction() == MotionEvent.ACTION_MOVE) {
                float xDiff = Math.abs(e.getX() - mInitialDownX);
                float yDiff = Math.abs(e.getY() - mInitialDownY);
                if (yDiff < xDiff && xDiff > 20.0) {
                    isBeingSlide = true;
                }
                View v = findChildViewUnder(e.getX(), e.getY());
                if (isBeingSlide) {
                    if (getPos(v) != -1) {
                        Log.d("adsds", " getId=" + v.getTag());
                        if (v != null && mLastDraggedIndex != getPos(v)) {
                            mLastDraggedIndex = getPos(v);
                            if (mMinReached == -1) mMinReached = mLastDraggedIndex;
                            if (mMaxReached == -1) mMaxReached = mLastDraggedIndex;
                            if (mLastDraggedIndex > mMaxReached)
                                mMaxReached = mLastDraggedIndex;
                            if (mLastDraggedIndex < mMinReached)
                                mMinReached = mLastDraggedIndex;
                            if (mAdapter != null)
                                mAdapter.selectRange(mInitialSelection, mLastDraggedIndex, mMinReached, mMaxReached);
                            if (mInitialSelection == mLastDraggedIndex) {
                                mMinReached = mLastDraggedIndex;
                                mMaxReached = mLastDraggedIndex;
                                Log.d("ddd", "onClick 3=" + getPos(v));
                            }
                            Log.d("ddd", "onClick 2=" + getPos(v));
                        }
                        return true;
                    }
                }else {
                    return super.dispatchTouchEvent(e);
                }
            }
        }
        return super.dispatchTouchEvent(e);
    }

    private int getPos(View parentView) {
        int pos = -1;
        Object tag = null;
        try {
            tag = parentView.getTag();
        }catch (Exception e){

        }

        if (tag != null)
            pos = (int) tag;
        return pos;
    }
}

3.对RecyclerView.Adapter的处理

package com.qiku.face.external.facelock360.spacephoto.test2;

import android.content.Context;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.qiku.face.external.facelock360.spacephoto.PhotoBean;
import com.qiku.face.external.facelock360.spacephoto.R;
import com.qiku.face.external.facelock360.spacephoto.Util;

import java.io.File;
import java.util.List;

/**
 * Created by chenmingying on 2017/9/19.
 */

public class PhotoRecViewAdapter extends RecyclerView.Adapter<PhotoRecViewAdapter.MyViewHolder> {
    private final String TAG = "PhotoRecViewAdapter";
    private final LayoutInflater mLayoutInflater;
    private Context mContext;
    private List<PhotoBean> mList;
    private int fixedSize;
    private int mWidth;
    private boolean isBoxVisibility = false;
    private boolean isImageUpdate = true;
    protected PhotoitemClickListener mOnItemClickListener;
    private static final int VIEW_TYPE_TITLE = R.layout.list_space_photo_rv_title;
    private static final int VIEW_TYPE_ITEM = R.layout.list_space_photo_rv_item;
    
    public PhotoRecViewAdapter(Context context, List<PhotoBean> list) {
        this.mContext = context;
        this.mList = list;
        mLayoutInflater = LayoutInflater.from(context);
        PhotoNode.getInstance().setArrayList(list);
        DisplayMetrics metric = new DisplayMetrics();
        WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        manager.getDefaultDisplay().getMetrics(metric);
        
        // 屏幕宽度(像素)
        mWidth = metric.widthPixels;
        Log.d(TAG, "setLayoutParams=1 " + mWidth + " =" + Util.dip2px(context, 0.5f));
        fixedSize = (mWidth - 3 * Util.dip2px(mContext, 1.0f)) / 4;
    }
    
    public void setOnItemClickListener(PhotoitemClickListener listener) {
        this.mOnItemClickListener = listener;
    }
    
    public class MyViewHolder extends RecyclerView.ViewHolder {
        
        private ImageView imageView;
        protected CheckBox checkBox;
        protected TextView mTextView;
        int viewType;
        
        public MyViewHolder(View itemView, int viewType) {
            super(itemView);
            this.viewType =viewType;
            if (viewType==VIEW_TYPE_ITEM) {
                imageView = (ImageView) itemView.findViewById(R.id.list_space_photo_img);
                checkBox = (CheckBox) itemView.findViewById(R.id.list_space_photo_che);
                imageView.setLayoutParams(new RelativeLayout.LayoutParams(getImageSize(getItemCount()),
                        getImageSize(getItemCount())));
            }
            if (viewType==VIEW_TYPE_TITLE) {
                mTextView = (TextView) itemView.findViewById(R.id.list_photo_time);
            }
        }
        
        private int getImageSize(int position) {
            int tmpSize = 0;
            if ((position + 1) % 4 == 0) {
                tmpSize = mWidth - 3 * Util.dip2px(mContext, 1.0f) - 3 * fixedSize;
            } else {
                tmpSize = fixedSize;
            }
            return tmpSize + Util.dip2px(mContext, 1.0f);
        }
    }
    
    @Override
    
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new MyViewHolder(mLayoutInflater.inflate(viewType, parent, false),viewType);
    }
    
    @Override
    public void onBindViewHolder(@NonNull final MyViewHolder holder, final int position) {
        Log.d(TAG, "onBindViewHolder: position=" + position);
        if (holder.viewType==VIEW_TYPE_TITLE) {
            holder.mTextView.setText(mList.get(position).getDate());
        }
        if (holder.viewType==VIEW_TYPE_ITEM) {
            Glide.with(mContext).load(mList.get(position).getPath()).into(holder.imageView);
            //holder.imageView.setImageBitmap(MediaStore.Images.Media.);
    
            if (isBoxVisibility) {
                holder.checkBox.setVisibility(View.VISIBLE);
            } else {
                holder.checkBox.setVisibility(View.GONE);
                mList.get(position).mSelected = false;
                Log.d(TAG, "onBindViewHolder: mList.set(" + position + ").mSelected");
            }
            holder.checkBox.setChecked(mList.get(position).mSelected);
            Log.d(TAG, "onBindViewHolder: mList.get(" + position + ")=" + mList.get(position).mSelected);
    
            if (holder.checkBox.isChecked()) {
                holder.imageView.setAlpha(0.8f);
            } else {
                holder.imageView.setAlpha(1.0f);
            }
            holder.itemView.setTag(position);
    
            holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                    Log.d(TAG, "onCheckedChanged: mList.set1(" + holder.getAdapterPosition() + ")" + b);
                    mList.get(holder.getAdapterPosition()).mSelected = b;
                    if (b) {
                        holder.imageView.setAlpha(0.8f);
                    } else {
                        holder.imageView.setAlpha(1.0f);
                    }
                }
            });
            holder.imageView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Log.d(TAG, "onClick: " + position);
                    mOnItemClickListener.onItemClick(view, position);
                    if (!isBoxVisibility) {
//                        mFileManager.openFile(mContext, mList.get(position).mPath);
                    } else {
                        if (holder.checkBox.isChecked()) {
                            mList.get(position/*holder.getAdapterPosition()*/).mSelected = false;
                        } else {
                            mList.get(position/*holder.getAdapterPosition()*/).mSelected = true;
                        }
                
                        notifyItemChanged(position);
                    }
                }
            });
            holder.imageView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View view) {
                    Log.d(TAG, "onLongClick: " + position);
                    if (mOnItemClickListener != null) {
                        mOnItemClickListener.onLongItemClick(view, position/*holder.getAdapterPosition()*/);
                    }
//
                    if (!isBoxVisibility) {
                        mList.get(position/*holder.getAdapterPosition()*/).mSelected = true;
//                Toast.makeText(mContext,"="+position+ " Tag="+position,Toast.LENGTH_SHORT).show();
//                    notifyItemChanged();
//                    holder.checkBox.setVisibility(View.VISIBLE);
//                    holder.checkBox.setChecked(true);
                        isBoxVisibility = true;
//                    isImageUpdate =false;
                        notifyDataSetChanged();
                    }
                    return false;
                }
            });
        }
    }
    
    
    @Override
    public int getItemCount() {
        return mList == null ? 0 : mList.size();
    }
    
    public void setSelected(int initialSelection, boolean b) {
        isBoxVisibility = b;
        //notifyDataSetChanged();
    }
    
    int aSelection = -1;
    
    public void selectRange(int initialSelection, int lastDraggedIndex, int minReached, int maxReached) {
        //if ()
        Log.d(TAG, "initialSelection=" + initialSelection + " lastDraggedIndex=" + lastDraggedIndex +
                " minReached=" + minReached + " maxReached=" + maxReached);
        if (aSelection != lastDraggedIndex) {
            mList.get(lastDraggedIndex).mSelected = !mList.get(lastDraggedIndex).mSelected;
            notifyItemChanged(lastDraggedIndex);
            aSelection = lastDraggedIndex;
        }
    }
    
    public void remove(int position) {
        new File(mList.get(position).getPath()).delete();
        mList.remove(position);
        notifyItemRemoved(position);
    }
    //获取不同布局的对象
    @Override
    public int getItemViewType(int position) {
        if (mList.get(position).isTitle)
            return VIEW_TYPE_TITLE;
        else return VIEW_TYPE_ITEM;
    }
}

4.对分割线的处理

package com.qiku.face.external.facelock360.spacephoto.test2;


import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.support.v7.widget.RecyclerView;
import android.view.View;


import com.qiku.face.external.facelock360.spacephoto.PhotoBean;
import com.qiku.face.external.facelock360.spacephoto.R;

import java.util.ArrayList;
import java.util.List;

public class PhotoItemDecoration extends RecyclerView.ItemDecoration {
    private int spanCount;
    private Context mContext;
    private List<PhotoBean> mDataArrayList;
    private List<Integer> mNum = new ArrayList<>();
    
    public PhotoItemDecoration(int spanCount, Context mContext) {
        this.spanCount =spanCount;
        this.mContext = mContext;
    }
    
    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        mDataArrayList = PhotoNode.getInstance().getArrayList();
        if (mDataArrayList != null) {
            mNum.clear();
            for (int i = 0; i < mDataArrayList.size(); i++) {
                if (mDataArrayList.get(i).isTitle) {
                    mNum.add(i);
                }
            }
        }
        int childLayoutPosition = parent.getChildLayoutPosition(view);
        int n = -2;
        if (mNum != null) {
            for (int i = 0; i < mNum.size()-1; i++) {
                if (mNum.get(i) < childLayoutPosition && childLayoutPosition < mNum.get(i + 1)) {
                    n = childLayoutPosition - mNum.get(i)-1;
                }
                if (childLayoutPosition>mNum.get(mNum.size()-1)){
                    n = childLayoutPosition - mNum.get(i + 1)-1;
                }
                if (childLayoutPosition == mNum.get(i)){
                    outRect.left = 0;
                }
            }
        
        }
        if ((n+1) %spanCount==0) {
            outRect.right = 0;
        }else {
            outRect.right = mContext.getResources().getDimensionPixelSize(R.dimen.image_interval);
        }
    }
    
    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDraw(c, parent, state);
    }
   
}

差不多了

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容