Android: 子视图超出父视图范围后无法响应点击事件

12

为了产生效果,我将子视图放大,导致子视图超出其父视图。我在子视图中有一个按钮,在缩放前它可以工作,但在缩放后就无法工作了。出了什么问题?请参见下面的图片:

button outside doesn't work

我使用以下代码缩放子元素:

            childView.bringToFront();
            Animation a = new Animation() {
                @Override
                protected void applyTransformation(float t, Transformation trans) {
                    float scale = 1f * ( 1 - t ) + SCALE_UP_FACTOR * t;
                    childView.setScaleX(scale);
                    childView.setScaleY(scale);
                }

                @Override
                public boolean willChangeBounds() {
                    return true;
                }
            };
            a.setDuration(ANIM_DURATION);
            a.setInterpolator(new Interpolator() {
                @Override
                public float getInterpolation(float t) {
                    t -= 1f;
                    return (t * t * t * t * t) + 1f; // (t-1)^5 + 1
                }
            });
            childView.startAnimation(a); 

父级是一个ViewPager

     <ViewPager
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/invoice_list_view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#f5f5f5"
        android:layout_gravity="center"
        android:clipChildren="false"
        android:clipToPadding="false"
        />

当视图被缩放时,如果您在按钮的原始(未缩放)位置轻敲,按钮会响应吗? - Barend
@Barend,正如我在问题中提到的:“在缩放之前它可以工作,但在缩放之后就无法工作了”。 - Mneckoee
@Barend。我更改了图片。 - Mneckoee
@Ya Hoo,你找到解决方案了吗?我遇到了同样的问题。 - Kotsu
不,我使用另一种方式来实现所需的效果。 - Mneckoee
显示剩余2条评论
1个回答

3
这应该能行:
final View grandParent = (View) childView.getParent().getParent();
grandParent.post(new Runnable() {
    public void run() {
        Rect offsetViewBounds = new Rect();
        childView.getHitRect(offsetViewBounds);

        // After scaling you probably want to append your view to the new size.
        // in your particular case it probably could be only offsetViewBounds.right:
        // (animDistance - int value, which you could calculate from your scale logic)
        offsetViewBounds.right = offsetViewBounds.right + animDistance;

        // calculates the relative coordinates to the parent
        ((ViewGroup)parent).offsetDescendantRectToMyCoords(childView, offsetViewBounds);
        grandParent.setTouchDelegate(new TouchDelegate(offsetViewBounds, childView));
    }
});

虽然我不确定它是否适用于Animation,但对于缩放,您可以使用类似以下的东西:
float scale = ...; // your scale logic

ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(childView, 
        PropertyValuesHolder.ofFloat("scaleX", scale),
        PropertyValuesHolder.ofFloat("scaleY", scale));
animator.setDuration(ANIM_DURATION);
animator.start();

请注意在XML文件中父视图的android:clipChildren="false"属性。

这样做不起作用,因为即使您使用触摸委托,也不能超出父视图的边界以具有可触摸区域。这意味着如果在其视图范围之外进行点击,则父级不会注册点击事件,因此无法将其转发到按钮。 - Csharpest
2
@Csharpest 在这种情况下,您总是可以调用祖父而不是父母:final View parent = (View) childView.getParent().getParent();我测试过了。它有效。在我的答案中进行了更改。 - Sergey
该死,我不知道那个,我错过了它。你甚至可以把你的父变量称为“grandParent”:P。谢谢你提供的信息。 - Csharpest
@Csharpest 说得好,我改了我的答案,现在是 grandParent :) 如果我的答案有用,你可以标记它为有用 :) - Sergey
如果您想把它标记为有用的:D,怎么做呢? 如果您指的是“接受”,那我很抱歉,因为我不是这个问题的作者。 - Csharpest

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接