Freely Draggable TextView - 精细控制

时间:2015-10-22 23:17:22

标签: java android textview

我有一个带有id" tx"的TextView。我设置了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相同),所以如果我决定从左侧拖动,则不会重新居中。我认为这是大多数用户对这种互动的期望。他们不希望将TextView重新定位在他们第一次点击的位置。

非常感谢所有人的帮助!

2 个答案:

答案 0 :(得分:1)

MotionEvent.ACTION_DOWN

前面总会有一个MotionEvent.ACTION_MOVE

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

答案 1 :(得分:0)

我终于弄明白了,所以我在这里完整地发布了答案,因为在看起来像这么简单的问题时找到帮助真是令人沮丧。您基本上需要在向下按下时设置初始x和y坐标,然后将TextView的边距偏移一个等于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>