自定义视图不响应触摸

7
我已经创建了一个自定义视图,当用户按下、高亮或禁用时,应该改变其背景图片。应用程序运行,但按钮没有更改其背景。以下是我的代码:
public class CustomImageButton extends View {

public CustomImageButton(Context context) {
super(context);
setFocusable(true);
setClickable(true);
}

public CustomImageButton(Context context, AttributeSet attrs) {
super(context, attrs);
setFocusable(true);
setClickable(true);
}
public CustomImageButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setFocusable(true);
setClickable(true);
}

protected Drawable background = super.getBackground();


@Override
public void setBackgroundDrawable(Drawable d) {
// Replace the original background drawable (e.g. image) with a LayerDrawable that
// contains the original drawable slightly edited.

CustomImageButtonBackgroundDrawable layer = new CustomImageButtonBackgroundDrawable(d);
super.setBackgroundDrawable(layer);
}

public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 int drawableWidth = super.getBackground().getMinimumWidth();
 int drawableHeight = super.getBackground().getMinimumHeight();
 setMeasuredDimension(drawableWidth, drawableHeight);
}

protected class CustomImageButtonBackgroundDrawable extends LayerDrawable { 

    protected Drawable lowerlayer;
    protected Drawable _highlightedDrawable;

    protected int _disabledAlpha = 100;
    protected Drawable _pressedDrawable;


    public CustomImageButtonBackgroundDrawable(Drawable d) {
          super(new Drawable[] { d });
    }

    @Override
    protected boolean onStateChange(int[] states) {
      boolean enabled = false;
      boolean highlighted = false;
      boolean pressed = false;

      for (int state : states) {
        if (state == android.R.attr.state_enabled)
            enabled = true;
        else if (state == android.R.attr.state_selected)
            highlighted = true;
        else if (state == android.R.attr.state_pressed)
            pressed = true;
      }

      mutate();
      if (enabled && highlighted) {
        ColorFilter colourFilter = new LightingColorFilter(Color.YELLOW, 1);
        ScaleDrawable resizedImage = new ScaleDrawable(background, 0, 1.25f, 1.25f);

        lowerlayer = resizedImage.getDrawable();
        lowerlayer.setColorFilter(colourFilter);

        Drawable[] aD = new Drawable[2];
        aD[0] = lowerlayer;
        aD[1] = background;
        LayerDrawable _highlightedDrawable = new LayerDrawable(aD);

        setBackgroundDrawable(_highlightedDrawable); // buttons need transparent backgrounds

      } else if (!enabled) {
        setColorFilter(null);
        setAlpha(_disabledAlpha);

      } else if (enabled && pressed){
        ScaleDrawable smaller = new ScaleDrawable(background, 0, 0.75f, 0.75f);

        setBackgroundDrawable(smaller.getDrawable());

      } else if(enabled){
        setBackgroundDrawable(background);  
        setColorFilter(null);
      }

      invalidateSelf();

      return super.onStateChange(states);
    }

}

}

这是我的 XML:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffff">

<ImageButton
    android:id="@+id/title"
    android:layout_width="250dp"
    android:layout_height="58dp"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layout_margin ="25dp"
    android:background="@drawable/skintonetitle" />

<custombuttons.CustomImageButton
    android:id="@+id/skina1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/title"
    android:layout_below="@+id/title"
    android:layout_marginTop="35dp"
    android:background="@drawable/test_circle"
    android:clickable="true"
    android:focusable="true" />

</RelativeLayout>

有什么我漏掉的吗?
2个回答

6

它扩展自 View,而不是 button,因此默认情况下不可点击或获得焦点。可以通过

android:clickable="true"
android:focusable="true"

在您的XML中设置:

如果您想在Java中设置,也可以在View类的构造函数中进行:

setFocusable(true);
setClickable(true);

啊,那很有道理。下班后我会试一试。在我的自定义按钮类中,我可以使视图默认可点击和可聚焦吗? - Kyohei Kaneko
是的 - 我回答中的那两行是XML属性。您可以将它们放在您的<custombuttons.CustomImageButton XML元素中,就像android:background、android:id等一样。 - Alexander Lucas
哦,抱歉我的意思是我能否覆盖自定义按钮源代码中的方法,使其默认可点击。这样我就不需要在每个XML文件中添加这些行了。 - Kyohei Kaneko
抱歉。在该视图的构造函数中,您可以调用setFocusable(true)和setClickable(true)。 - Alexander Lucas
刚刚测试了一下,仍然没有反应...嗯(抱歉),已经将两者都添加到XML和Java中。编辑问题以显示更改。代码是否存在问题导致更改无法生效? - Kyohei Kaneko
不确定。添加一些日志语句以查看视图是否注意到它被按下。如果尚未添加,您可能需要添加OnClickListener和onFocusChangeListener。 - Alexander Lucas

6
在我的情况下,我使用了一个约束布局作为自定义视图的根视图,并且在我的自定义视图的setOnClickListener中没有获取到点击事件。事实证明,我需要在自定义视图xml的根视图中设置android:clickable="false"。显然,点击事件被分发到自定义视图xml的根视图而不是自定义视图本身(即自定义视图的setOnClickListener)。

这一定是个bug。把根元素的clickable='false',然后又让它可点击,这没有任何意义。但还是谢谢你帮我解决了问题。 - szaske
仍然适用。面临相同的情况。非常感谢。 - Kirguduck

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