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

绝对什么都不做。

编辑2:

为我的 ListView 设置 onItemClickListener 也不起作用,即使对于滚动出和回到可见区域的项目也是如此。

编辑3:

我还注意到,当 ListView 中有 16 个项目(不是特殊数字)时,最后 5 个项目在我膨胀的布局中没有达到我指定的高度(例如 100 像素),它们的行为类似于 wrap_content。总而言之,我开始相信 ListView 不应该在 Dialog 中使用。

4

1 回答 1

0

我发现的一种可能的解决方案是停止尝试使用 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。此解决方法按预期工作。尽管如此,当它们非常适合这项工作时,我不得不使用 ScrollViews 而不是 ListViews,我感到非常愚蠢。

于 2012-08-09T13:33:21.973 回答