TextView上的OnClick事件会停止CardView上的RippleEffect。

5

我在CardView内部放置了一个TextView。当我添加OnClick事件并添加以下属性以启用Lollipop上CardView的水波纹效果时:

android:foreground="?android:attr/selectableItemBackground"

它可以正常工作。但是,在给TextView添加OnClick事件后,当我点击TextView区域时,水波纹效果不会显示,但是当我点击TextView外部时,水波纹效果仍然会出现。

是否有方法使得即使我点击TextView,水波纹效果也能够显示?

这是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"
                android:paddingLeft="@dimen/activity_horizontal_margin"
                android:paddingRight="@dimen/activity_horizontal_margin"
                android:paddingTop="@dimen/activity_vertical_margin"
                android:paddingBottom="@dimen/activity_vertical_margin"
                tools:context=".MainActivity">

    <android.support.v7.widget.CardView
        android:id="@+id/news_card"
        android:foreground="?android:attr/selectableItemBackground"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/text"
            android:text="Test String"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

    </android.support.v7.widget.CardView>

</RelativeLayout>

以下是代码:

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

    View v = findViewById (R.id.news_card);
    v.setOnClickListener (new View.OnClickListener () {
        @Override public void onClick (final View v) {

        }
    });

    View textView = findViewById (R.id.text);
    textView.setOnClickListener (new View.OnClickListener () {
        @Override public void onClick (final View v) {

        }
    });
}

水波纹应该只出现在处理点击的元素上。如果整个卡片不可点击,则整个卡片不应该显示水波纹。 - alanv
从用户的角度看,整个卡片都是可点击的。但是当用户点击TextView时,它必须先执行一些额外的逻辑,然后再将其传递给卡片的onclick事件。 - Comtaler
1个回答

6

一种选择是将按下状态和热点位置转发给父视图。

// Since the host view actually supports clicks, you can return false
// from your touch listener and continue to receive events.
myTextView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent e) {
        // Convert to card view coordinates. Assumes the host view is
        // a direct child and the card view is not scrollable.
        float x = e.getX() + v.getLeft();
        float y = e.getY() + v.getTop();

        // Simulate motion on the card view.
        myCardView.drawableHotspotChanged(x, y);

        // Simulate pressed state on the card view.
        switch (e.getActionMasked()) {
            case MotionEvent.ACTION_DOWN:
                myCardView.setPressed(true);
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                myCardView.setPressed(false);
                break;
        }

        // Pass all events through to the host view.
        return false;
    }
});

3
这个方法可行,但是动画不如默认效果流畅。我最终移除了TextView上的onClickListener,实现了onTouchListener来完成onClickListener的功能,并返回false以允许CardView显示涟漪效果。 - Comtaler

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