28

我需要在左侧有一些带有可绘制的文本,并且我想在用户单击/触摸图像时执行一些代码(只有图像,而不是文本),所以我使用了带有TextViewImageViewLinearLayout可点击并启动 onClick 事件。XML 解析器建议我用带有复合 drawable的TextView替换它,这将用更少的XML行绘制相同的东西。我的问题是“我可以指定我只想在 drawable 上处理 onClick 事件TextView而不是TextView本身?我见过一些解决方案,其中涉及编写自己的TextView扩展,但如果可能的话,我只对能够在布局资源中执行此操作感兴趣,否则我将保留以下XML代码:

<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="bottom"
            android:paddingTop="10dp"
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:text="@string/home_feedback_title"
            android:textColor="@android:color/primary_text_dark"
            android:textStyle="bold" 
            android:paddingBottom="4dp"/>


        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/action_feedback" 
            android:clickable="true"
            android:onClick="onClickFeedback"
            android:contentDescription="@string/action_feedback_description"/>
</LinearLayout>
4

5 回答 5

45

它非常简单。假设您在 TextView 'txtview' 的左侧有一个可绘制对象。以下将解决问题。

TextView txtview = (TextView) findViewById(R.id.txtview);
txtview.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if(event.getAction() == MotionEvent.ACTION_UP) {
            if(event.getRawX() <= txtview.getTotalPaddingLeft()) {
                // your action for drawable click event

             return true;
            }
        }
        return true;
    }
});

如果您想要正确的drawable,请将if语句更改为:

if(event.getRawX() >= txtview.getRight() - txtview.getTotalPaddingRight())

同样,您可以对所有复合可绘制对象执行此操作。

txtview.getTotalPaddingTop();
txtview.getTotalPaddingBottom();

此方法调用返回该侧的所有填充,包括任何可绘制对象。您甚至可以将它用于 TextView、Button 等。

单击此处以获取来自 android 开发者网站的参考。

于 2015-03-23T15:23:44.870 回答
8

你可以去任何一种方式。使用复合可绘制对象更快,因为它旨在进行优化。它使用更少的内存,因为您将 3 个视图减少为 1 个,并且布局更快,因为您失去了 1 个深度。

如果我是你,我会考虑退后一步,看看文本和图像是否都拦截了触摸以执行任何操作可能是一件好事。一般来说,触摸区域越大,越容易按压。一些用户实际上可能倾向于触摸文本而不是图像。

最后,如果您采用合并 2 的路线,您可能需要考虑使用 aButton而不是 a TextView。您可以设置按钮的样式,使其周围没有矩形。他们称之为无边框按钮。这很好,因为您会获得视觉反馈,即您单击了一个可操作的项目,而该项目通常是不可操作的ImageViewTextView

如何在 Android 中创建无边框按钮

于 2012-05-19T17:24:35.547 回答
6

@Vishnuvathsan 的答案几乎是完美的,但getRaw()返回了触摸点的绝对 x 位置。如果 textview 不在视图的左边缘,则应使用 . 与 textview 的绝对位置进行比较getLocationOnScreen。下面的代码是一个检查左侧可绘制点击和右侧可绘制点击的示例。

textView.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            int[] textLocation = new int[2];
            textView.getLocationOnScreen(textLocation);

            if (event.getRawX() <=  textLocation[0] + textView.getTotalPaddingLeft()) {

                // Left drawable was tapped

                return true;
            }


            if (event.getRawX() >= textLocation[0] + textView.getWidth() - textView.getTotalPaddingRight()){

                // Right drawable was tapped

                return true;
            }
        }
        return true;
    }
});
于 2017-11-27T03:32:14.960 回答
0
final int DRAWABLE_LEFT = 0;
final int DRAWABLE_TOP = 1;
final int DRAWABLE_RIGHT = 2;
final int DRAWABLE_DOWN = 3;

这个点击监听器正在进入触摸监听器

 if (event.getAction() == MotionEvent.ACTION_DOWN) 
if (event.getAction() == MotionEvent.ACTION_DOWN) {
            if (event.getX() >= (tvFollow.getTop() - tvFollow.getCompoundDrawables()[DRAWABLE_TOP].getBounds().width())) {
                   // your action here
                return true; } }
于 2019-07-04T12:57:00.203 回答
0

由于 getRaw() 和 getRight() 都返回整个屏幕坐标,因此如果您的视图不在屏幕的左边缘,这将不起作用。无论布局位置如何,以下解决方案都可以在任何地方使用。这是用于右侧可绘制触摸。

  textView.setOnTouchListener(OnTouchListener { _, event ->
                if (event.action == MotionEvent.ACTION_UP)
                {
                    if (event.x >= textView.width - textView.totalPaddingEnd)
                    {
                        <!---DO YOUR ACTIONS HERE--->
                        return@OnTouchListener true
                    }
                }
                true
            })

PS:科特林代码

于 2021-12-16T19:32:34.090 回答