当前位置 主页 > 网站技术 > 代码类 >

    Android 仿微信发动态九宫格拖拽、删除功能

    栏目:代码类 时间:2019-11-18 15:10

    1、完美1比1 仿照微信仿微信发动态 九宫格拖拽、删除

    暴力拖拽ui有点问题,不影响使用,资源文件自己找个+号

    2、微信发动态拖拽bug

    当选择完图片,长按图片拖拽过程中按下屏幕home键盘,再次进入这时候就不能点击输入文字,点击输入文字的时候会触发选择相册事件

    3、拖拽事件用的basequickadapter

     implementation 'com.android.support:recyclerview-v7:28.0.0'
     implementation "com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.50"
     implementation "com.github.bumptech.glide:glide:4.9.0"

    4、演示

    在这里插入图片描述

    5、快速入手

    activity
     NineGridChooseImage nineGridChooseImage = findViewById(R.id.nineGridChooseImage);
     FrameLayout frameLayout= findViewById(R.id.frameLayout);
     nineGridChooseImage.init(frameLayout);
    
     int statusBarHeight = 0;
     int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
     if (resourceId > 0) {
      statusBarHeight = getResources().getDimensionPixelSize(resourceId);
     }
     nineGridChooseImage.setFixH(statusBarHeight);//自己对一下高度
     nineGridChooseImage.setAddClick(new NineGridChooseImage.AddClick() {
      @Override
      public void onAdd() {
      /* List<String> list = new LinkedList<>();
      for(int i = 0;i<5;i++){
       list.add("https://xx.jpg");
      }*/
      nineGridChooseImage.addData("https://xxx.jpg");
      }
     });

    xml

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:andro
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     tools:context=".Main11Activity">
     <com.example.hotfix_01.view.NineGridChooseImage
     android:background="#A8A1A1"
     android:layout_marginTop="100dp"
     android:
     android:layout_width="match_parent"
     android:layout_height="wrap_content" />
    </FrameLayout>

    5、实现过程

    如果帮助到你请关注点赞一下

    NineGridChooseImage.java
    package com.example.hotfix_01.view;
    import android.animation.Animator;
    import android.animation.AnimatorListenerAdapter;
    import android.animation.ObjectAnimator;
    import android.app.Activity;
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Point;
    import android.graphics.Rect;
    import android.support.annotation.NonNull;
    import android.support.annotation.Nullable;
    import android.support.v7.widget.GridLayoutManager;
    import android.support.v7.widget.RecyclerView;
    import android.support.v7.widget.helper.ItemTouchHelper;
    import android.text.TextUtils;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.Display;
    import android.view.Gravity;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.FrameLayout;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    import android.widget.TextView;
    import com.bumptech.glide.Glide;
    import com.chad.library.adapter.base.BaseItemDraggableAdapter;
    import com.chad.library.adapter.base.BaseViewHolder;
    import com.chad.library.adapter.base.callback.ItemDragAndSwipeCallback;
    import com.chad.library.adapter.base.listener.OnItemDragListener;
    import java.util.LinkedList;
    import java.util.List;
    import top.antaikeji.base.R;
    import top.antaikeji.foundation.utils.DisplayUtil;
    import static android.support.v7.widget.helper.ItemTouchHelper.ACTION_STATE_IDLE;
    /**
     * Author: flyzhang
     */
    public class NineGridChooseImage extends RecyclerView {
     private Rect lastRect = new Rect();
     private Rect rect = new Rect();
     private boolean isDel = false, tempImageDel = false;
     private int mSelectPosition = 0;
     private int SCREEN_W, SCREEN_H;
     private int mImageWH;
     private int mImageCount = 4;
     private DraggableAdapter mDraggableAdapter;
     private LinearLayout mBottomView;
     private FrameLayout mFrameLayout;
     private AddClick mAddClick;
     private DragCallBack mDragCallBack;
     private ImageView mTempImage;
     ;
     private int mFixH = 0;
     private int bottomViewH = 55;
     private ImageView trash;
     private int margin = 2;
     public NineGridChooseImage(@NonNull Context context) {
     super(context);
     }
     public NineGridChooseImage(@NonNull Context context, @Nullable AttributeSet attrs) {
     super(context, attrs);
     }
     public void init(FrameLayout f) {
     this.mFrameLayout = f;
     Display defaultDisplay = ((Activity) getContext()).getWindowManager().getDefaultDisplay();
     Point point = new Point();
     defaultDisplay.getSize(point);
     SCREEN_H = point.y;
     SCREEN_W = point.x;
     mImageWH = SCREEN_W / 3 - 2 * DisplayUtil.dpToPx(5) - 4 * DisplayUtil.pxToDp(20) - DisplayUtil.pxToDp(50);
     bottomViewH = DisplayUtil.dpToPx(bottomViewH);
     margin = DisplayUtil.dpToPx(margin);
     mTempImage = new ImageView(getContext());
     mTempImage.setScaleType(ImageView.ScaleType.FIT_XY);
     //初始化底部view
     mBottomView = new LinearLayout(getContext());
     mBottomView.setGravity(Gravity.CENTER);
     mBottomView.setBackgroundColor(Color.RED);
     FrameLayout.LayoutParams bottomLayoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, bottomViewH);
     bottomLayoutParams.gravity = Gravity.BOTTOM;
     trash = new ImageView(getContext());
     int wh = DisplayUtil.dpToPx(25);
     FrameLayout.LayoutParams trashParams = new FrameLayout.LayoutParams(wh, wh);
     trash.setLayoutParams(trashParams);
     mBottomView.addView(trash);
     TextView tipTextView = new TextView(getContext());
     tipTextView.setTextColor(Color.WHITE);
     tipTextView.setText("拖拽此处删除");
     mBottomView.addView(tipTextView);
     mBottomView.setOrientation(LinearLayout.VERTICAL);
     mBottomView.setLayoutParams(bottomLayoutParams);
     mBottomView.setVisibility(GONE);
     out();
     mFrameLayout.addView(mBottomView);
     GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), 3);
     setLayoutManager(gridLayoutManager);
     List<String> data = new LinkedList<>();
     data.add("");
     mDraggableAdapter = new DraggableAdapter(data);
     DragAndSwipeCallback mItemDragAndSwipeCallback = new DragAndSwipeCallback(mDraggableAdapter);
     ItemTouchHelper itemTouchHelper = new ItemTouchHelper(mItemDragAndSwipeCallback);
     itemTouchHelper.attachToRecyclerView(this);
     mDraggableAdapter.enableDragItem(itemTouchHelper, R.id.image, true);
     mItemDragAndSwipeCallback.setSwipeMoveFlags(ItemTouchHelper.START | ItemTouchHelper.END);
     mDraggableAdapter.setOnItemDragListener(new OnItemDragListener() {
      @Override
      public void onItemDragStart(RecyclerView.ViewHolder viewHolder, int pos) {
      if(null!=mDragCallBack){
       mDragCallBack.onStart();
      }
      mSelectPosition = pos;
      mFrameLayout.removeView(mTempImage);
      tempImageDel = false;
      isDel = false;
      in();
      ImageView imageView = viewHolder.itemView.findViewById(R.id.image);
      mTempImage.setImageDrawable(imageView.getDrawable());
      ViewGroup.LayoutParams l = new ViewGroup.LayoutParams(imageView.getWidth(), imageView.getHeight());
      mTempImage.setLayoutParams(l);
      imageView.getGlobalVisibleRect(lastRect);
      mTempImage.setX(lastRect.left);
      mTempImage.setY(lastRect.top - mFixH);
      mTempImage.setScaleX(1.2f);
      mTempImage.setScaleY(1.2f);
      mFrameLayout.addView(mTempImage);
      imageView.setAlpha(0f);
      }
      @Override
      public void onItemDragMoving(RecyclerView.ViewHolder source, int from, RecyclerView.ViewHolder target, int to) {
      target.itemView.findViewById(R.id.image).getGlobalVisibleRect(lastRect);
      mSelectPosition = to;
      }
      @Override
      public void onItemDragEnd(RecyclerView.ViewHolder viewHolder, int pos) {
      if(null!=mDragCallBack){
       mDragCallBack.onEnd();
      }
      ImageView imageView = viewHolder.itemView.findViewById(R.id.image);
      imageView.setScaleX(1f);
      imageView.setScaleY(1f);
      if (tempImageDel) {
       mDraggableAdapter.remove(mSelectPosition);
      } else {
       imageView.setAlpha(1f);
       mFrameLayout.removeView(mTempImage);
      }
      out();
      }
     });
     setAdapter(mDraggableAdapter);
     }
     public void setFixH(int mFixH) {
     this.mFixH = mFixH;
     }
     /**
     * 拖住adapter
     */
     private class DraggableAdapter extends BaseItemDraggableAdapter<String, BaseViewHolder> {
     private DraggableAdapter(List<String> data) {
      super(R.layout.base_iamge_item, data);
     }
     @Override
     protected void convert(@NonNull BaseViewHolder helper, String item) {
      ImageView imageView = helper.getView(R.id.image);//图片
      LinearLayout.LayoutParams l = (LinearLayout.LayoutParams) imageView.getLayoutParams();
      l.height = mImageWH;
      l.width = mImageWH;
      l.rightMargin = margin;
      l.bottomMargin = margin;
      l.topMargin = margin;
      imageView.setLayoutParams(l);
      ImageView imageView2 = helper.getView(R.id.image2);//加号
      LinearLayout.LayoutParams l2 = (LinearLayout.LayoutParams) imageView.getLayoutParams();
      l2.height = mImageWH;
      l2.width = mImageWH;
      l2.rightMargin = margin;
      l2.bottomMargin = margin;
      l2.topMargin = margin;
      imageView2.setLayoutParams(l2);
      /**
      * 如果list的长度等于mImageCount 最后一张最后一张显示正常图片
      *
      */
      if(TextUtils.isEmpty(item)){
      if(mImageCount <= helper.getAdapterPosition()){
       imageView.setVisibility(View.GONE);
       imageView2.setVisibility(View.GONE);
      }else{
       imageView.setVisibility(View.GONE);
       imageView2.setVisibility(View.VISIBLE);
       imageView2.setOnClickListener(new OnClickListener() {
       @Override
       public void onClick(View v) {
        if (null != mAddClick) {
        mAddClick.onAdd();
        }
       }
       });
      }
      }else{
      imageView.setVisibility(View.VISIBLE);
      imageView2.setVisibility(View.GONE);
      Glide.with(mContext).load(item).into(imageView);
      }
      imageView.setAlpha(1f);
     }
     }
     /**
     * 拖拽监听
     */
     private class DragAndSwipeCallback extends ItemDragAndSwipeCallback {
     private DragAndSwipeCallback(BaseItemDraggableAdapter adapter) {
      super(adapter);
     }
     @Override
     public boolean canDropOver(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder current, @NonNull RecyclerView.ViewHolder target) {
      if (target.getAdapterPosition() == mDraggableAdapter.getData().size() - 1 || current.getAdapterPosition() == mDraggableAdapter.getData().size() - 1) {
      return false;
      }
      return super.canDropOver(recyclerView, current, target);
     }
     @Override
     public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
      super.onSelectedChanged(viewHolder, actionState);
      if (actionState == ACTION_STATE_IDLE) {
      //空闲状态
      if (isDel) {
       isDel = false;
       tempImageDel = true;
       mFrameLayout.removeView(mTempImage);
      }
      }
     }
     @Override
     public void onChildDrawOver(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
      super.onChildDrawOver(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
      if (tempImageDel) {
      return;
      }
      ImageView tempImageView = viewHolder.itemView.findViewById(R.id.image);
      boolean b = tempImageView.getGlobalVisibleRect(rect);
      Log.e("TAG", "dX:" + dX);
      Log.e("TAG", "dY:" + dY);
      if (b && dX > 0 && dY > 0) {
      mTempImage.setX(rect.left);
      mTempImage.setY(rect.top - mFixH);
      } else {
      mTempImage.setX(lastRect.left + dX);
      mTempImage.setY(lastRect.top - mFixH + dY);
      }
      mTempImage.getGlobalVisibleRect(rect);
      if (SCREEN_H - bottomViewH < rect.bottom) {
      isDel = true;
      trash.setBackgroundResource(R.drawable.base_trash_open);
      } else {
      isDel = false;
      trash.setBackgroundResource(R.drawable.base_trash_close);
      }
     }
     }
     public void addData(String path) {
     mDraggableAdapter.addData(0, path);
     mDraggableAdapter.notifyItemChanged(mDraggableAdapter.getData().size()-1);
     }
     public void addData(List<String> path){
     int size = mDraggableAdapter.getData().size();
     int offset = mImageCount - size + 1;
     if(offset > path.size()){
      offset = path.size();
     }
     mDraggableAdapter.addData(0, path.subList(0,offset));
     mDraggableAdapter.notifyItemChanged(mDraggableAdapter.getData().size() -1);
     }
     public void setImageCount(int mImageCount) {
     this.mImageCount = mImageCount;
     }
     public void setAddClick(AddClick mAddClick) {
     this.mAddClick = mAddClick;
     }
     public void setDragCallBack(DragCallBack mDragCallBack) {
     this.mDragCallBack = mDragCallBack;
     }
     /**
     * 获取列表
     *
     * @return
     */
     public List<String> getData() {
     List<String> res = new LinkedList<>();
     for (int i = 0; i < mDraggableAdapter.getData().size() - 1; i++) {
      res.add(mDraggableAdapter.getData().get(i));
     }
     return res;
     }
     /**
     * 底部进入
     */
     private void in() {
     mBottomView.setVisibility(View.VISIBLE);
     ObjectAnimator animator = ObjectAnimator.ofFloat(mBottomView, "translationY", 0)
      .setDuration(200);
     animator.start();
     }
     /**
     * 底部移除屏幕外部
     */
     private void out() {
     final int moveX = DisplayUtil.dpToPx(55);
     ObjectAnimator animator = ObjectAnimator.ofFloat(mBottomView, "translationY", moveX)
      .setDuration(200);
     animator.addListener(new AnimatorListenerAdapter() {
      @Override
      public void onAnimationEnd(Animator animation) {
      super.onAnimationEnd(animation);
      mBottomView.setVisibility(View.GONE);
      trash.setBackgroundResource(R.drawable.base_trash_close);
      }
     });
     animator.start();
     }
     public interface AddClick {
     void onAdd();
     }
     public interface DragCallBack{
     void onStart();
     void onEnd();
     }
    }