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