Android 拖拽控件交换位置

  距离上次写博客已快有一月,中间也动过几次写博客的心思,但却因为懒,耽搁了下来。                         --萧洛

  在网上搜寻了许久,实在是没有找到可用的demo,无奈只好自己写一个,鉴于个人也是新手,这个

demo确实也是在下耗费了一些时间,若需要转载请标明出处。好啦,废话不多说了,直接上图。

功能说明:当退拽的距离超过当前控件的一半

                                                

1.XML文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="horizontal"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
    >
    <ImageView
        android:id="@+id/prettyBoy"
        android:clickable="true"
        android:src="@drawable/a"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:focusable="true"
        android:scaleType="fitXY"
        android:contentDescription="@string/todo"
        />
    <ImageView
        android:id="@+id/sunwukong"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:clickable="true"
        android:src="@drawable/b"
        android:scaleType="fitXY"
        android:focusable="true"
        android:contentDescription="@string/aprettyboy"/>

</LinearLayout>
   
   2.Java文件
 
package com.example.administrator.jiemiantest;

import android.app.Activity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;

public class MainActivity extends Activity implements View.OnTouchListener{

    int screenWidth;
    int screenHeight;
    int lastX;
    int lastY;
    ImageView sunwukong;
    ImageView prettyBoy;
    boolean sunwukong_resetLeftFlag = false;
    boolean sunwukong_resetRightFlag = false;
    boolean prettyBoy_resetLeftflag = false;
    boolean prettyBoy_resetRightflag = false;
    int rightMove_flag ;
    int leftMove_flag;
    int dx;
    int dy;
    @Override
    public void onCreate(Bundle savedInstanceState)  {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        DisplayMetrics dm = getResources().getDisplayMetrics();
        screenWidth = dm.widthPixels;
        screenHeight = dm.heightPixels - 50;
        sunwukong = findViewById(R.id.sunwukong);
        sunwukong.setOnTouchListener(this);
        prettyBoy=findViewById(R.id.prettyBoy);
        prettyBoy.setOnTouchListener(this);

    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        // TODO Auto-generated method stub
        int action=event.getAction();
        Log.i("@@@@@@", "Touch:"+action);
        //Toast.makeText(DraftTest.this, "λ�ã�"+x+","+y, Toast.LENGTH_SHORT).show();
        switch(action){
            case MotionEvent.ACTION_DOWN:
                lastX = (int) event.getRawX();
                lastY = (int) event.getRawY();

                break;
            /**
             * layout(l,t,r,b)
             * l  Left position, relative to parent
             t  Top position, relative to parent
             r  Right position, relative to parent
             b  Bottom position, relative to parent
             * */
            case MotionEvent.ACTION_MOVE:
                 dx =(int)event.getRawX() - lastX;
                 dy =(int)event.getRawY() - lastY;

                int left = v.getLeft() + dx;
                int top = v.getTop() + dy;
                int right = v.getRight() + dx;
                int bottom = v.getBottom() + dy;
                if(left < 0){
                    left = 0;
                    right = left + v.getWidth();
                }
                if(right > screenWidth){
                    right = screenWidth;
                    left = right - v.getWidth();
                }
                if(top < 0){
                    top = 0;
                    bottom = top + v.getHeight();
                }
                if(bottom > screenHeight){
                    bottom = screenHeight;
                    top = bottom - v.getHeight();
                }
                v.layout(left, top, right, bottom);
                lastX = (int) event.getRawX();
                lastY = (int) event.getRawY();
                switch (v.getId()){
                    case R.id.sunwukong:
                        if(dx > 0){
                            if(sunwukong.getLeft() >=150 ){
                                if(300 == prettyBoy.getLeft()) {
                                    prettyBoy.layout(0, 0, 300, 300);
                                    Animation translateAnimation = new TranslateAnimation(300, 0, 0, 0);
                                    translateAnimation.setFillAfter(true);
                                    translateAnimation.setDuration(600);
                                    prettyBoy.startAnimation(translateAnimation);
                                    rightMove_flag = 1;
                                }
                            }
                        }else{
                            if(sunwukong.getLeft()<=150){
                                if(0 == prettyBoy.getLeft()) {
                                    prettyBoy.layout(300, 0, 600, 300);
                                    Animation translateAnimation = new TranslateAnimation(-300, 0, 0, 0);
                                    translateAnimation.setFillAfter(true);
                                    translateAnimation.setDuration(600);
                                    prettyBoy.startAnimation(translateAnimation);
                                    leftMove_flag = 1;
                                }
                            }
                        }
                        break;
                    case R.id.prettyBoy:
                        if(dx > 0){
                            if(prettyBoy.getLeft() >= 150){
                                if(300 ==sunwukong.getLeft()) {
                                    sunwukong.layout(0, 0, 300, 300);
                                    Animation translateAnimation = new TranslateAnimation(300, 0, 0, 0);
                                    translateAnimation.setFillAfter(true);
                                    translateAnimation.setDuration(600);
                                    sunwukong.startAnimation(translateAnimation);
                                    rightMove_flag = 1;
                                }
                            }
                        }else{
                            if(prettyBoy.getLeft() <= 150){
                                if(0 == sunwukong.getLeft()) {
                                    sunwukong.layout(300, 0, 600, 300);
                                    Animation translateAnimation = new TranslateAnimation(-300, 0, 0, 0);
                                    translateAnimation.setFillAfter(true);
                                    translateAnimation.setDuration(600);
                                    sunwukong.startAnimation(translateAnimation);
                                    leftMove_flag = 1;
                                }
                            }
                        }
                }
                break;
            case MotionEvent.ACTION_UP:

                        switch (v.getId()){
                            case R.id.sunwukong:
                                if(dx > 0){
                                    if(sunwukong.getLeft() <=150 ){
                                        sunwukong_resetLeftFlag =true;
                                    }
                                    if(sunwukong.getLeft()>=300){
                                        sunwukong_resetRightFlag = true;
                                    }
                            }else{
                                if(sunwukong.getLeft()>=150){
                                    sunwukong_resetRightFlag = true;
                                }

                            }
                                 if(1 == rightMove_flag){
                                     rightMove_flag = 0;
                                     int x1 = sunwukong.getLeft();
                                     int x2 = sunwukong.getTop();
                                     sunwukong.layout(300,0,600,300);
                                     Animation translateAnimation = new TranslateAnimation(x1-300, 0, x2, 0);
                                     translateAnimation.setFillAfter(true);
                                     translateAnimation.setDuration(600);
                                     sunwukong.startAnimation(translateAnimation);
                                     break;
                                 }
                                 if(sunwukong_resetLeftFlag){
                                     sunwukong_resetLeftFlag=false;
                                     int x1 = sunwukong.getLeft();
                                     int high = sunwukong.getTop();
                                     sunwukong.layout(0,0,300,300);
                                     Animation translateAnimation = new TranslateAnimation(x1, 0, high, 0);
                                     translateAnimation.setFillAfter(true);
                                     translateAnimation.setDuration(600);
                                     sunwukong.startAnimation(translateAnimation);
                                     break;
                                 }
                                 if(1 ==leftMove_flag){
                                     leftMove_flag =0;
                                     int x1 = sunwukong.getLeft();
                                     int x2 = sunwukong.getTop();
                                     sunwukong.layout(0,0,300,300);
                                     Animation translateAnimation = new TranslateAnimation(x1, 0, x2, 0);
                                     translateAnimation.setFillAfter(true);
                                     translateAnimation.setDuration(600);
                                     sunwukong.startAnimation(translateAnimation);
                                     break;
                                 }
                                 if(sunwukong_resetRightFlag){
                                     sunwukong_resetRightFlag = false;
                                     int x1 = sunwukong.getLeft();
                                     int x2 = sunwukong.getTop();
                                     sunwukong.layout(300,0,600,300);
                                     Animation translateAnimation = new TranslateAnimation(x1-300, 0, x2, 0);
                                     translateAnimation.setFillAfter(true);
                                     translateAnimation.setDuration(600);
                                     sunwukong.startAnimation(translateAnimation);
                                     break;
                                 }

                                break;
                            case R.id.prettyBoy:
                                if(dx > 0){
                                    if(prettyBoy.getLeft() <= 150){
                                        prettyBoy_resetLeftflag =true;
                                    }
                                    if(prettyBoy.getLeft() >= 300){
                                        prettyBoy_resetRightflag = true;
                                    }
                                }else{
                                    if(prettyBoy.getLeft() >= 150){
                                        prettyBoy_resetRightflag = true;
                                    }
                                }
                                if(1 == rightMove_flag){
                                    rightMove_flag = 0;
                                    int x1 = prettyBoy.getLeft();
                                    int x2 = prettyBoy.getTop();
                                    prettyBoy.layout(300,0,600,300);
                                    Animation translateAnimation = new TranslateAnimation(x1-300, 0, x2, 0);
                                    translateAnimation.setFillAfter(true);
                                    translateAnimation.setDuration(600);
                                    prettyBoy.startAnimation(translateAnimation);
                                    break;
                                }
                                if(prettyBoy_resetLeftflag){
                                    prettyBoy_resetLeftflag=false;
                                    int x1 = prettyBoy.getLeft();
                                    int high = prettyBoy.getTop();
                                    prettyBoy.layout(0,0,300,300);
                                    Animation translateAnimation = new TranslateAnimation(x1, 0, high, 0);
                                    translateAnimation.setFillAfter(true);
                                    translateAnimation.setDuration(600);
                                    prettyBoy.startAnimation(translateAnimation);
                                    break;
                                }
                                if(1 ==leftMove_flag){
                                    leftMove_flag =0;
                                    int x1 = prettyBoy.getLeft();
                                    int x2 = prettyBoy.getTop();
                                    prettyBoy.layout(0,0,300,300);
                                    Animation translateAnimation = new TranslateAnimation(x1, 0, x2, 0);
                                    translateAnimation.setFillAfter(true);
                                    translateAnimation.setDuration(600);
                                    prettyBoy.startAnimation(translateAnimation);
                                    break;
                                }
                                if(prettyBoy_resetRightflag){
                                    prettyBoy_resetRightflag = false;
                                    int x1 = prettyBoy.getLeft();
                                    int x2 = prettyBoy.getTop();
                                    prettyBoy.layout(300,0,600,300);
                                    Animation translateAnimation = new TranslateAnimation(x1-300, 0, x2, 0);
                                    translateAnimation.setFillAfter(true);
                                    translateAnimation.setDuration(600);
                                    prettyBoy.startAnimation(translateAnimation);
                                    break;
                                }
                                break;
                        }
                break;
        }

        return false;
    }
}


简述:

1.中间有些东西为了方便,就直接写数字了。 在这个分辨率里面,100dp = 300px。

2.TranslateAnimation(),第一个参数的意思是动画开始的点离当前view的x坐标上的差值,第二参数的意思
是动画结束点离当前view x坐标的差值。

3.代码中的动画逻辑是,先设置位置,然后再将动画效果显示。这一点的话,需要自己理解实际位置和动画效果
之后的位置的关系,简 单来说的话就是,View动画不会改变控件的实际位置,该在哪里还是在哪里。

4.主逻辑是,点击的是哪张图片,接着判断是左移还是右移,然后再判断移动的距离是否达到交换控件位置的
距离,达到的 话就交换,反之则返回原位置。

5.写代码的时候最容易出现的就是在actionmove里面的逻辑错误。
    
最后呢,附上源码地址。
      

   


  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 拖拽交换位置可以通过自定义 RecyclerView.ItemTouchHelper.Callback 来实现。具体步骤如下: 1. 自定义 RecyclerView.ItemTouchHelper.Callback 类,并重写以下方法: - onMove():返回 true 表示可以移动 item,保存被移动的 item 和目标位置的 item,然后交换它们的位置。 - onSwiped():返回 true 表示可以滑动 item,不做任何操作即可。 - getMovementFlags():返回可以支持的移动和滑动方向。 2. 在 RecyclerView 中调用 ItemTouchHelper.attachToRecyclerView() 方法,将自定义的 ItemTouchHelper.Callback 作为参数传入。 3. 在 RecyclerView.Adapter 中实现自定义的 ItemTouchHelper.Adapter 接口,并重写以下方法: - onItemMove():交换被移动的 item 和目标位置的 item。 - onItemDismiss():不做任何操作即可。 示例代码如下: ``` public class ItemTouchHelperCallback extends ItemTouchHelper.Callback { private final ItemTouchHelperAdapter mAdapter; public ItemTouchHelperCallback(ItemTouchHelperAdapter adapter) { mAdapter = adapter; } @Override public boolean isLongPressDragEnabled() { return true; } @Override public boolean isItemViewSwipeEnabled() { return false; } @Override public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN; int swipeFlags = 0; return makeMovementFlags(dragFlags, swipeFlags); } @Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { mAdapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition()); return true; } @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { // do nothing } public interface ItemTouchHelperAdapter { boolean onItemMove(int fromPosition, int toPosition); void onItemDismiss(int position); } } ``` ``` public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> implements ItemTouchHelperCallback.ItemTouchHelperAdapter { private List<String> mData; public MyAdapter(List<String> data) { mData = data; } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.item_view, parent, false); return new ViewHolder(view); } @Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { holder.mTextView.setText(mData.get(position)); } @Override public int getItemCount() { return mData.size(); } @Override public boolean onItemMove(int fromPosition, int toPosition) { Collections.swap(mData, fromPosition, toPosition); notifyItemMoved(fromPosition, toPosition); return true; } @Override public void onItemDismiss(int position) { // do nothing } public static class ViewHolder extends RecyclerView.ViewHolder { public TextView mTextView; public ViewHolder(View view) { super(view); mTextView = view.findViewById(R.id.text_view); } } } ``` ``` public class MainActivity extends AppCompatActivity { private RecyclerView mRecyclerView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mRecyclerView = findViewById(R.id.recycler_view); mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); List<String> data = new ArrayList<>(); for (int i = 1; i <= 100; i++) { data.add("Item " + i); } MyAdapter adapter = new MyAdapter(data); ItemTouchHelperCallback callback = new ItemTouchHelperCallback(adapter); ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback); itemTouchHelper.attachToRecyclerView(mRecyclerView); mRecyclerView.setAdapter(adapter); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值