1

複合コンポーネント(LinearLayoutを拡張)に2つのTextViewとImageViewがあります。

含まれている個々のビューではなく、コンポーネント全体をクリック可能にしたいと考えています。

この複合コンポーネントに設定した 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 レイアウトを定義する方法が原因でした。ルートは LinearLayout です。

HomeButton コンストラクターでレイアウトをインフレートすると、ビュー階層は XML で定義された LinearLayout から開始されず、追加のルート ノード (HomeButton クラス自体からだと思います) があり、XML で定義された LinearLayout は最初の子です。このルート ノード。

HomeButton に onClick リスナーを設定することは問題ありませんが、onClick イベントは最初の子ノードによって消費されるため、この場合は必要ありません...

そこから考えられる解決策:

  1. ルート LinearLayout を削除し、マージ タグを使用します
  2. setOnClickListener をオーバーライドして、最初の子に転送します
  3. 最初の子で setClickable(false) を呼び出します。

マージタグを使用するとスタイルを希望どおりに設定できないため、3番目のソリューションを選択しました(ただし、すべてが機能することをテストしました)。

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をチートして最初の子に割り当てることができます...

4

3 に答える 3

1

自分で見つけた解決策

この問題は、複合コンポーネントの XML レイアウトを定義する方法が原因でした。ルートは LinearLayout です。

HomeButton コンストラクターでレイアウトをインフレートすると、ビュー階層は XML で定義された LinearLayout から開始されず、追加のルート ノード (HomeButton クラス自体からだと思います) があり、XML で定義された LinearLayout は最初の子です。このルート ノード。

HomeButton に onClick リスナーを設定することは問題ありませんが、onClick イベントは最初の子ノードによって消費されるため、この場合は必要ありません...

そこから考えられる解決策:

  1. ルート LinearLayout を削除し、マージ タグを使用します
  2. setOnClickListener をオーバーライドして、最初の子に転送します
  3. 最初の子で setClickable(false) を呼び出します。

マージタグを使用するとスタイルを希望どおりに設定できないため、3番目のソリューションを選択しました(ただし、すべてが機能することをテストしました)。

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をチートして最初の子に割り当てることができます...

于 2013-08-09T06:20:21.547 に答える
1

属性を使用してレイアウトをクリック可能に設定します

android:clickable=true

あなたのxmlで、または

setClickable(true)

プログラムで設定します。

また、その子のクリックがどのように機能するかを判断するために、 descendantFocusabilityを確認することもできます。

例えば:

android:descendantFocusability="blocksDescendants"

「 ViewGroupは、その子孫がフォーカスを受け取るのをブロックします。」

于 2013-08-08T10:32:06.577 に答える