有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java可自由拖动的TextView精细控件

我有一个id为“tx”的文本视图。我已经设置了一个OnTouchListener,允许用户拖动视图

tx.setOnTouchListener(new View.OnTouchListener() {

    @Override
    public boolean onTouch(View view, MotionEvent event) {
        float x = event.getRawX();
        float y = event.getRawY();
        if (event.getAction() == MotionEvent.ACTION_MOVE) {
            // Offsets center the TextView to the center of the MotionEvent
            view.setX(x - view.getWidth() / 2);
            view.setY(y - view.getHeight() / 2);
        }

        return true;
    }

我如何创建一个拖动效果,即用户最初单击的位置就是拖动开始的位置?我需要精细控制(与Snapchat或Autodesk Sketch相同),因此如果我决定从左侧拖动,则不会重新居中。我认为这是大多数用户对这种交互的期望。他们不希望他们的文本视图被重新定位在他们第一次点击的中心位置

非常感谢大家的帮助


共 (2) 个答案

  1. # 1 楼答案

    始终会有一个MotionEvent.ACTION_DOWN前面加MotionEvent.ACTION_MOVE

    您应该首先处理MotionEvent.ACTION_DOWN事件,该事件将为您提供用户第一次触摸的位置。您可以存储这些坐标,然后在MotionEvent.ACTION_DOWN中使用它们来做任何您想做的事情

  2. # 2 楼答案

    我终于找到了答案,所以我在这里发布了完整的答案,因为在这个看似简单的问题上找到帮助真的很让人沮丧。基本上,您需要在按下时设置初始x和y坐标,然后将TextView的边距偏移等于TextView当前位置+/-初始输入坐标的a值。这给人一种沿拖动方向平滑移动textview的错觉。我希望这对别人有帮助

    TextView tx;        
    tx = (TextView) findViewById(R.id.textView1);
    
    tx.setOnTouchListener(new View.OnTouchListener() {
                int initialX = 0;
                int initialY = 0;
    
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    switch (event.getActionMasked()) {
                        case MotionEvent.ACTION_DOWN:
                            initialX = (int) event.getX();
                            initialY = (int) event.getY();
                            break;
                        case MotionEvent.ACTION_MOVE:
                            int currentX = (int) event.getX();
                            int currentY = (int) event.getY();
                            RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) tx.getLayoutParams();
    
                            int left = lp.leftMargin + (currentX - initialX);
                            int top = lp.topMargin + (currentY - initialY);
                            int right = lp.rightMargin - (currentX - initialX);
                            int bottom = lp.bottomMargin - (currentY - initialY);
    
                            lp.rightMargin = right;
                            lp.leftMargin = left;
                            lp.bottomMargin = bottom;
                            lp.topMargin = top;
    
                            tx.setLayoutParams(lp);
                            break;
                        default:
                            break;
                    }
                    return true;
                }
            });
    

    以及布局XML:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    
    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:typeface="sans"
        android:text=""
        android:fontFamily="sans-serif-bold"
        android:textSize="48sp"
        android:textColor="#33ffcc" />
    
    </RelativeLayout>