Android 拖拽到指定區域刪除修改等操做

最近研究了一下某社交軟件的朋友圈圖片長按拖拽到指定區域刪除的功能,通過不斷的奮鬥終於實現了它。java

先看下效果吧!android

     

 

乾貨來了 git

MoveLayoutManager.java
/**

* RecycleView設置縱向滾動

*/
public class MoveLayoutManager extends LinearLayoutManager {
    private boolean isScrollEnabled = true;

    public MoveLayoutManager(Context context) {
        this(context, LinearLayoutManager.VERTICAL, false);
    }

    public MoveLayoutManager(Context context, int orientation, boolean reverseLayout) {
        super(context, orientation, reverseLayout);
    }

    @Override
    public boolean canScrollVertically() {
        return isScrollEnabled && super.canScrollVertically();
    }

    public void setScrollEnabled(boolean scrollEnabled) {
        isScrollEnabled = scrollEnabled;
    }
}
RecycleViewLongPressMove .java
import android.view.MotionEvent;
import android.view.View;

import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;

import java.util.Collections;
import java.util.List;

/**
 * 移動拖拽ItemView 到指定區域操做
 *
 * @author xulin
 * @email xllovey@163.com
 */
public class RecycleViewLongPressMove implements View.OnTouchListener {

    private MoveLayoutManager moveLayoutManager;
    private List<?> list;
    private View removeView;
    private int positionTag;
    private boolean isLongPress;

    /**
     * 移動拖拽ItemView 到指定區域操做
     *
     * @param recyclerView 當前集合RecyclerView
     * @param list         當前Adater的數據源 移動時排序使用
     * @param removeView   指定的操做View區域
     */
    public RecycleViewLongPressMove(RecyclerView recyclerView, List<?> list, View removeView) {
        this.list = list;
        this.removeView = removeView;

        moveLayoutManager = new MoveLayoutManager(recyclerView.getContext());
        recyclerView.setLayoutManager(moveLayoutManager);
        itemTouchHelper.attachToRecyclerView(recyclerView);
        recyclerView.setOnTouchListener(this);
    }


    //爲RecycleView綁定觸摸事件
    ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() {

        @Override
        public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
            //首先回調的方法 返回int表示是否監聽該方向
            int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.START | ItemTouchHelper.END;//拖拽
            return makeMovementFlags(dragFlags, 0);
        }

        @Override
        public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
            //滑動事件
            int fromPosition = viewHolder.getAdapterPosition();//獲得拖動ViewHolder的position
            int toPosition = target.getAdapterPosition();//獲得目標ViewHolder的position
            recyclerView.getAdapter().notifyItemMoved(fromPosition, toPosition);//位置變化
            positionTag = toPosition;
            //數據源位置更換
            if (fromPosition < toPosition) {
                for (int i = fromPosition; i < toPosition; i++) {
                    Collections.swap(list, i, i + 1);
                }
            } else {
                for (int i = fromPosition; i > toPosition; i--) {
                    Collections.swap(list, i, i - 1);
                }
            }
            return false;
        }

        @Override
        public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
        }

        @Override
        public boolean isLongPressDragEnabled() {
            moveLayoutManager.setScrollEnabled(false);//禁止滑動
            isLongPress = true;
            onLongPressMoveLisener.onMoveView(false);
            return true;
        }
    });

    @Override
    public boolean onTouch(View view, MotionEvent event) {
        if (onLongPressMoveLisener == null) {
            new IllegalArgumentException("請在 RecycleViewLongPressMove 調用 setOnLongPressMoveLisener !!!");
            return true;
        }
        float xDown = event.getX();
        float yDown = event.getY();
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
        } else if (event.getAction() == MotionEvent.ACTION_UP) {
            if (isLongPress) {
                if (isTouchPointInView(removeView, xDown, yDown)) {
                    onLongPressMoveLisener.onOperation(positionTag);
                }
            }
            onLongPressMoveLisener.onNomalView();
            isLongPress = false;
            moveLayoutManager.setScrollEnabled(true);
        } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
            if (isLongPress) {
                onLongPressMoveLisener.onMoveView(isTouchPointInView(removeView, xDown, yDown));
            }
        }
        return false;
    }

    private boolean isTouchPointInView(View view, float x, float y) {
        if (view == null) {
            return false;
        }
        int[] location = new int[2];
        view.getLocationOnScreen(location);
        int left = location[0];
        int top = location[1];
        int right = left + view.getMeasuredWidth();
        int bottom = top + view.getMeasuredHeight();
        //view.isClickable() &&
        if (y >= top && y <= bottom && x >= left
                && x <= right) {
            return true;
        }
        return false;
    }

    private OnLongPressMoveLisener onLongPressMoveLisener;

    public void setOnLongPressMoveLisener(OnLongPressMoveLisener onLongPressMoveLisener) {
        this.onLongPressMoveLisener = onLongPressMoveLisener;
    }

    public interface OnLongPressMoveLisener {
        void onNomalView();//正常
        void onMoveView(boolean isTouchPointInView);//移動
        void onOperation(int position);//操做
    }

}
Activiy
/**
 * 拖動View 刪除
 */
public class OnLongPressMoveNewActivity extends AppCompatActivity implements RecycleViewLongPressMove.OnLongPressMoveLisener {

    private static final String TAG = "OnLongPressMoveNewActivity";
    private MoveDropAdapter moveDropAdapter;
    private RecyclerView recyclerView;
    private List<String> list;
    private TextView tvButton;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_move_drop);

        list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add("我是第" + i + "個被拖拽的");
        }

        moveDropAdapter = new MoveDropAdapter(this, list);
        recyclerView = findViewById(R.id.recycler_view);
        recyclerView.setAdapter(moveDropAdapter);
        moveDropAdapter.notifyDataSetChanged();
        tvButton = findViewById(R.id.tv_button);

        RecycleViewLongPressMove recycleViewLongPressMove = new RecycleViewLongPressMove(recyclerView, list, tvButton);
        recycleViewLongPressMove.setOnLongPressMoveLisener(this);
    }


    @Override
    public void onNomalView() {
        Log.d(TAG, "onNomalView");
        tvButton.setBackgroundColor(Color.WHITE);
        tvButton.setTextColor(Color.GREEN);
    }

    @Override
    public void onMoveView(boolean isTouchPointInView) {
        Log.d(TAG, "onMoveView");
        if(isTouchPointInView){
            tvButton.setBackgroundColor(Color.RED);
            tvButton.setTextColor(Color.GRAY);
        }else{
            tvButton.setBackgroundColor(Color.RED);
            tvButton.setTextColor(Color.WHITE);
        }
    }

    @Override
    public void onOperation(int position) {
        tvButton.setBackgroundColor(Color.WHITE);
        tvButton.setTextColor(Color.BLUE);

        Log.d(TAG, "onOperation" + ">" + position);
        list.remove(position);
        recyclerView.getAdapter().notifyDataSetChanged();
    }
}

activity_move_drop.xmlgithub

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

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/tv_button" />

    <TextView
        android:id="@+id/tv_button"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_alignParentBottom="true"
        android:background="#08a1ef"
        android:gravity="center"
        android:text="移動到這裏刪除"
        android:textColor="#ffffff"
        android:textSize="18dp" />
</RelativeLayout>

adapter_movedrop.xmlide

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

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#e5e5e5"
        android:text="長按拖動拖動我"
        android:textSize="18dp" />
</RelativeLayout>

MoveDropAdapter.javathis

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

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

import com.ol.xow.R;

import java.util.List;

public class MoveDropAdapter extends RecyclerView.Adapter implements View.OnLongClickListener {

    private static final int mLayout = R.layout.adapter_movedrop;

    private Context context;
    private List<String> list;


    public MoveDropAdapter(Context context, List<String> list) {
        this.list = list;
        this.context = context;
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(mLayout, null);
        return new MoveDropViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
        if (viewHolder instanceof MoveDropViewHolder) {
            MoveDropViewHolder holder = (MoveDropViewHolder) viewHolder;
            String title = list.get(position);
            holder.tvTitle.setText(title);

            holder.itemView.setTag(mLayout, position);
            holder.itemView.setOnLongClickListener(this);
        }
    }

    @Override
    public int getItemCount() {
        return list != null ? list.size() : 0;
    }

    @Override
    public boolean onLongClick(View view) {
        int position = (int) view.getTag(mLayout);
        if (onAdapterListener != null) {
            onAdapterListener.onItemLongClick(view, position);
        }
        return false;
    }


    public class MoveDropViewHolder extends RecyclerView.ViewHolder {

        TextView tvTitle;

        public MoveDropViewHolder(@NonNull View itemView) {
            super(itemView);
            tvTitle = itemView.findViewById(R.id.tv_title);
        }
    }

    private OnAdapterListener onAdapterListener;

    public void setOnAdapterListener(OnAdapterListener onAdapterListener) {
        this.onAdapterListener = onAdapterListener;
    }

    public interface OnAdapterListener {
        void onItemLongClick(View view, int position);
    }
}

下載地址code

相關文章
相關標籤/搜索