我在复合组件中有 2 个 TextView 和一个 ImageView(扩展 LinearLayout)。
我希望整个组件都是可点击的,而不是单个包含的视图。
我在这个复合组件上设置的 onClick 监听器没有被调用,即使有视觉反馈表明该组件获得了触摸事件。
有任何想法吗 ?
更新:我的复合组件的代码:
public class HomeButton extends LinearLayout {
TextView title;
TextView subtitle;
ImageView icon;
public HomeButton(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.HomeButton, 0, 0);
String titleText = a.getString(R.styleable.HomeButton_title);
String subtitleText = a
.getString(R.styleable.HomeButton_subtitle);
int iconResId = a.getResourceId(R.styleable.HomeButton_icon, 0);
a.recycle();
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.home_button, this, true);
title = (TextView) findViewById(R.id.home_button_title);
title.setText(titleText);
subtitle = (TextView) findViewById(R.id.home_button_subtitle);
subtitle.setText(subtitleText);
icon = (ImageView) findViewById(R.id.home_button_icon);
icon.setImageResource(iconResId);
}
public void setTitle(String title) {
this.title.setText(title);
}
public void setSubtitle(String subtitle) {
this.subtitle
.setVisibility(subtitle == null ? View.GONE : View.VISIBLE);
this.subtitle.setText(subtitle);
}
}
请参阅下面我自己的答案(我现在也在这里发布,因为我没有足够的代表来立即回答我自己的问题;))
解决办法,自己找的
问题是由于我为复合组件定义 XML 布局的方式。根是一个线性布局。
在 HomeButton 构造函数中扩展布局时,视图层次结构不是从 XML 中定义的 LinearLayout 开始,它有一个额外的根节点(我猜来自 HomeButton 类本身),XML 中定义的 LinearLayout 是第一个子节点这个根节点。
在 HomeButton 上设置 onClick 侦听器很好,但在这种情况下不需要这样做,因为 onClick 事件会被第一个子节点消耗......
从那里开始可能的解决方案:
- 删除根 LinearLayout 并使用合并标签
- 覆盖 setOnClickListener 以转发到第一个孩子
- 在第一个孩子上调用 setClickable(false)。
我选择使用第三种解决方案(但我已经测试过所有的工作),因为使用合并标签不允许按照我想要的方式设置样式。
public HomeButton(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.HomeButton, 0, 0);
String titleText = a.getString(R.styleable.HomeButton_title);
String subtitleText = a
.getString(R.styleable.HomeButton_subtitle);
int iconResId = a.getResourceId(R.styleable.HomeButton_icon, 0);
a.recycle();
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.home_button, this, true);
title = (TextView) findViewById(R.id.home_button_title);
title.setText(titleText);
subtitle = (TextView) findViewById(R.id.home_button_subtitle);
subtitle.setText(subtitleText);
icon = (ImageView) findViewById(R.id.home_button_icon);
icon.setImageResource(iconResId);
// This made it work
getChildAt(0).setClickable(false);
}
解决方案 2 需要注意的一件事:如果您的 onClick 侦听器检查生成事件的视图的 id,您将不会获得您在 XML 中定义的 id(因为实际生成事件的视图是第一个子视图,而不是 HomeButton 视图),但您可以作弊并将 HomeButton 视图的 id 分配给第一个孩子...