0

Dialogを拡張し、レイアウト内にListViewを持つカスタムダイアログがあります。ArrayAdapterを拡張するカスタムアダプタを介してListViewにデータを入力します。これが、特定のリストアイテムのonClickイベントを含むアダプターです。

public class PendingTimeslotArrayAdapter extends ArrayAdapter<PendingTimeslot> {
    private final Context context;
    private final PendingTimeslot[] values;
    private final View[] views;

    public PendingTimeslotArrayAdapter(Context context, PendingTimeslot[] values) {
        super(context, R.layout.mystuff_timeslot_picker_dialog_list_item, values);
        this.context = context;
        this.values = values;
        this.views = new View[values.length];
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if(views[position] == null){
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            View rowView = inflater.inflate(R.layout.mystuff_timeslot_picker_dialog_list_item, parent, false);
            rowView.setTag((Integer)position);

            ((TextView)rowView.findViewById(R.id.mystuff_timeslot_picker_list_item_date_time)).setText(values[position].getDateTime());
            ((TextView)rowView.findViewById(R.id.mystuff_timeslot_picker_list_item_stage_name)).setText(values[position].getStageName());

            rowView.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    System.out.println("getting touch event");
                    PendingTimeslot t = values[(Integer)(v.getTag())];
                    CheckBox checkBox = (CheckBox) v.findViewById(R.id.mystuff_timeslot_picker_list_item_checkbox);
                    checkBox.setChecked(!checkBox.isChecked());
                    t.toggle();
                }
            });

            views[position] = rowView;
            return rowView;
        }
        else
            return views[position];
    }
}

私の問題は、リストアイテムがクリックされたときに、タッチイベントを取得しないため、onClickが呼び出されないことです。面白いことに、ListViewは完全にスクロール可能であり、アイテムが表示領域から出て戻ってくると、タッチ可能になり、onClickイベントが発生します。

ListViewとそのonTouchEventメソッドをオーバーライドしてみました。アイテムがクリックされても、ListViewのonTouchEventは実際には発生しません。また、dispatchTouchEventメソッドをオーバーライドしようとしましたが、正しく機能し、すべてのタッチイベントを想定どおりに取得しました。

同様のカスタムArrayAdapterを他の場所(ダイアログ内ではない)で使用しましたが、問題なく動作します。私は今これをバグだと考えています。何かが足りないのですか、それとも別の方法でこれを行う必要がありますか(ダイアログ内のクリック可能なアイテムを含むListView)?

編集:

追加する

rowView.setClickable(true);
rowView.setFocusable(true);

絶対に何もしません。

Edit2:

ListViewにonItemClickListenerを設定しても、表示領域からスクロールアウトして表示領域に戻ったアイテムに対しても機能しません。

Edit3:

また、ListViewに16個のアイテム(特別な番号ではない)がある場合、最後の5個のアイテムは、膨らませたレイアウトで指定した高さ(100pxなど)を取得せず、代わりにwrap_contentのように動作することに気付きました。全体として、私はListViewをダイアログで使用すべきではないと信じ始めています。

4

1 に答える 1

0

私が見つけた1つの可能な解決策は、ListViewの使用をやめ、代わりに、内部に垂直のLinearLayoutを持つScrollViewを使用することです。このScrollViewのレイアウトは次のようになります。

<ScrollView
    android:layout_width="wrap_content"
    android:layout_height="0dp"
    android:layout_weight="1" >

    <LinearLayout
        android:id="@+id/mystuff_timeslot_picker_list"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical" >
    </LinearLayout>
</ScrollView>

リストデータを取得したら、それぞれの行を膨らませて、LinearLayoutに手動で追加します。

LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for(PendingTimeslot p : timeslots){
    View rowView = inflater.inflate(R.layout.mystuff_timeslot_picker_dialog_list_item, timeslotList, false);
    //((TextView)rowView.findViewById(R.id.mystuff_timeslot_picker_list_item_date_time)).setText(values[position].getDateTime());
    ((TextView)rowView.findViewById(R.id.mystuff_timeslot_picker_list_item_date_time)).setText("just testing");
    //((TextView)rowView.findViewById(R.id.mystuff_timeslot_picker_list_item_stage_name)).setText(values[position].getStageName());

    rowView.setClickable(true);
    rowView.setFocusable(true);

    rowView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            System.out.println("just testing");
            //PendingTimeslot t = values[(Integer)(v.getTag())];
            CheckBox checkBox = (CheckBox) v.findViewById(R.id.mystuff_timeslot_picker_list_item_checkbox);
            checkBox.setChecked(!checkBox.isChecked());
        }
    });

    timeslotList.addView(rowView);
}

timeslotListは、私が言及したLinearLayoutです。この回避策は期待どおりに機能します。それでも、仕事に最適なときにListViewsの代わりにScrollViewsを使用しなければならないのは非常に愚かです。

于 2012-08-09T13:33:21.973 に答える