如果视图在直接父视图的范围之外进行了动画处理,则onTouchListener()不响应

时间:2018-12-02 22:30:19

标签: android android-layout

我有一个ImageView,它是LinearLayout的子代。如果我在ImageView内的任何地方为LinearLayout设置动画,则onTouchListener()在动画之后会响应,但是如果动画将视图移到直接LinearLayout父级之外,则会变得无响应。

换句话说,ImageView onTouchListener()是否被触发,完全取决于我动画的x和y偏移量是否在LinearLayout父对象的范围内。

ObjectAnimator translateX =
        ObjectAnimator.ofFloat(view, "translationX",
                offSet_X);

ObjectAnimator translateY =
        ObjectAnimator.ofFloat(view, "translationY",
                offSet_Y);

translateX.setDuration(translationDurationMill);
translateX.start();
translateY.setDuration(translationDurationMill);
translateY.start();

是这种现象,还是我的代码中的错误?

修改

因此,例如,我已将问题简化为一个简单的应用程序,并验证了该行为不是错误,而是Android的工作方式,但我不确定如何解决该问题。

这是主要活动的简单布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" 
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:clipChildren="false"
    android:clipToPadding="false"
    >

    <LinearLayout
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:background="@color/colorPrimary"
        android:text="Hello World!"
        android:gravity="center"
        >

        <TextView
            android:id="@+id/tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@color/colorAccent"
            android:text="hello world" />

    </LinearLayout>
</LinearLayout>

这是主要的活动代码

public class MainActivity extends AppCompatActivity
        implements View.OnTouchListener{

    int mTranslationDurationMill = 500;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView tv = findViewById(R.id.tv);
        tv.setOnTouchListener(this);

        animateTextView(tv,10,10);
    }

    private void animateTextView(View view, int offSet_X,int offSet_Y)
    {
        ObjectAnimator translateX =
                ObjectAnimator.ofFloat(view, "translationX",
                        offSet_X);

        ObjectAnimator translateY =
                ObjectAnimator.ofFloat(view, "translationY",
                        offSet_Y);

        translateX.setDuration(mTranslationDurationMill);
        translateX.start();
        translateY.setDuration(mTranslationDurationMill);
        translateY.start();
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        Log.d("TAG","onTouch()");
        return false;
    }
}

上面有animateTextView(tv,10,10);可以为文本视图添加动画,动画之后,我可以确认日志表明触发了触摸事件,这是图片

enter image description here

但是如果执行animateTextView(tv,400,400);,则视图将移到直接父级LinearLayout之外,并且触摸事件不会注册。这是图片。

enter image description here

2 个答案:

答案 0 :(得分:0)

对我有用。 这是整个代码

在布局中,我有一个ImageView和一个TextView(一旦触发触摸事件,文本就会从未单击变为单击)

<FrameLayout
    android:id="@+id/child_view_container"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:id="@+id/child_view"
        android:layout_width="match_parent"
        android:layout_height="300px"
        app:srcCompat="@color/colorAccent"
        tools:layout_editor_absoluteX="216dp"
        tools:layout_editor_absoluteY="143dp" />

    <TextView
        android:id="@+id/textview"
        android:layout_width="wrap_content"
        android:layout_height="50dp"
        android:text="not clicked"
        android:textSize="30sp"
        tools:layout_editor_absoluteX="119dp"
        tools:layout_editor_absoluteY="230dp" />
</FrameLayout>
代码中的

: childView是ImageView textView是TextView 侦听器将侦听触摸事件,如果检测到触摸事件,它将把textView文本更改为“单击”

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    textView = findViewById(R.id.textview);

    childView = findViewById(R.id.child_view);
    childView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            textView.setText("clicked");
            return false;
        }
    });

}

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    if(hasFocus){
        View containerView = findViewById(R.id.child_view_container);
        childView.setTranslationX(containerView.getWidth());
        childView.animate()
                .translationXBy(-containerView.getWidth())
                .setDuration(10000)
                .setInterpolator(new AccelerateDecelerateInterpolator())
                .start();
    }
}

我希望这会有所帮助。

答案 1 :(得分:0)

我可能已经找到解决方法。看起来即使触摸甚至发生在动画视图上,触摸事件也不会传播到动画视图,但是会超出动画视图的直接父级的范围,因此我覆盖了活动派发事件处理程序,并传递了运动事件直接转到动画视图。

public class MainActivity extends AppCompatActivity
        implements View.OnTouchListener {

    int mTranslationDurationMill = 500;
    TextView tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv = findViewById(R.id.tv);
        tv.setOnTouchListener(this);

        animateTextView(tv, 400, 400);
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        Log.d("TAG", "onTouch()");
        Log.d("TAG", "event.getAction() "+event.getAction());
        return false;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent me) {

        Log.d("TAG", "dispatchTouchEvent");

        // Send the motion event directly to the view.

        this.onTouch(tv, me);

        // Don't propagate the motion event to the children.
        return true;
    }

    private void animateTextView(View view, int offSet_X, int offSet_Y) {
        ObjectAnimator translateX =
                ObjectAnimator.ofFloat(view, "translationX",
                        offSet_X);

        ObjectAnimator translateY =
                ObjectAnimator.ofFloat(view, "translationY",
                        offSet_Y);

        translateX.setDuration(mTranslationDurationMill);
        translateX.start();
        translateY.setDuration(mTranslationDurationMill);
        translateY.start();
    }
}

因此,这是当我触摸动画视图时,其视图超出其父级范围时的日志:

D/TAG: dispatchTouchEvent
D/TAG: onTouch()
D/TAG: event.getAction() 0
D/TAG: dispatchTouchEvent
D/TAG: onTouch()
D/TAG: event.getAction() 2
D/TAG: dispatchTouchEvent
D/TAG: onTouch()
D/TAG: event.getAction() 2
D/TAG: dispatchTouchEvent
D/TAG: onTouch()
D/TAG: event.getAction() 2
D/TAG: dispatchTouchEvent
D/TAG: onTouch()
D/TAG: event.getAction() 1