仅为TextView复合drawable实现onClick

时间:2012-05-19 14:47:21

标签: android android-layout onclick textview

我需要在左边有一些带有drawable的文本,我想在用户点击/触摸图像时执行一些代码(只有图像,而不是文本),所以我使用了 LinearLayout 使用 TextView ImageView 可点击并启动onClick事件。 XML解析器建议我用 TextView 替换它,并使用复合drawable ,这将用更少的 XML 行来绘制相同的东西。我的问题是“我可以指定我只想在 TextView 的drawable上处理onClick事件而不是在 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 个答案:

答案 0 :(得分:35)

非常简单。假设你在TextView&#39; txtview&#39;的左侧有一个drawable。以下将做到这一点。

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;
    }
});

如果您想要右侧绘制,请将if语句更改为:

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

同样,你可以为所有复合绘图做到这一点。

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

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

点击here以获取Android开发者网站的参考。

答案 1 :(得分:7)

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

如果我是你,我会考虑退后一步,看看文字和图像是否拦截触摸做任何动作都可能是一件好事。通常,具有更大的触摸区域使得更容易按压。有些用户实际上可能倾向于触摸文本而不是图像。

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

How to Create Borderless Buttons in Android

答案 2 :(得分:4)

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

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;
    }
});

答案 3 :(得分: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; } }