我有一个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);
可以为文本视图添加动画,动画之后,我可以确认日志表明触发了触摸事件,这是图片
但是如果执行animateTextView(tv,400,400);
,则视图将移到直接父级LinearLayout
之外,并且触摸事件不会注册。这是图片。
答案 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