用于微调项目的OnItemClickListener,与setOnItemSelectedListener一起出现问题

时间:2017-11-15 12:10:29

标签: android android-arrayadapter android-spinner dialogfragment

我想创建一个时间和日期选择对话框,就像goolgle keep app中的对话框一样,显示在将来想要提醒某个事件时。

该对话框有两个用于日期和时间的微调器字段。 前几个字段是今天,明天等的口头描述。最后一个元素是手动选择日期。单击它将打开时间/日期选择器。

A date and time selection dialog

我目前的解决方案为每个Spinners使用两个自定义适配器。适配器是类似的,所以我将进一步描述时间选择部分。

我的TimeSelection示例实现了getViewgetDropDownView方法。 getDropDownView方法并不像在这种情况下那样设置要在微调器项中显示的值。

@Override
    public View getDropDownView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        ViewHolderDropDown holder;
        TimeSelectionModel model = getItem(position);
        if (convertView == null) {
            holder = new ViewHolderDropDown();
            convertView = inflater.inflate(R.layout.time_spinner_drop_down_item, parent, false);
            holder.verbalTimeTextView = (TextView) convertView.findViewById(R.id.verbal_time_text_view);
            holder.timeTextView = (TextView) convertView.findViewById(R.id.time_text_view);
            convertView.setTag(R.layout.time_spinner_drop_down_item, holder);
        } else {
            holder = (ViewHolderDropDown) convertView.getTag(R.layout.time_spinner_drop_down_item);
        }

        holder.timeTextView.setText(model.time);
        holder.verbalTimeTextView.setText(model.verbalTime);

        return convertView;
    }

唯一不标准的是,它填充了两个TextViews,用于口头描述早晨,晚上等,而一个精确的8:00。

getView方法不同,而不是通过使用常规数据数组填充其成员来获取字段selectedTime中的值。稍后我会回到这个领域的设定方式。

@NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        ViewHolder holder;

        if (convertView == null) {
            holder = new ViewHolder();
            convertView = inflater.inflate(R.layout.time_spinner_item, parent, false);
            holder.timeTextView = (TextView) convertView.findViewById(R.id.time_text_view);
            convertView.setTag(R.layout.time_spinner_item, holder);
        } else {
            holder = (ViewHolder) convertView.getTag(R.layout.time_spinner_item);
        }

        holder.timeTextView.setText(selectedTime);

        return convertView;
    }

同时拥有这两个视图的DateTimeSelectionDialog为这两个微调器实现了setOnItemSelectedListener,这些旋转器也是类似的。

timeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        Log.d(TAG, "onItemSelected");
        if (position == POSITION_MORNING) {
            timeAdpater.setTime(8, 0);
        } else if (position == POSITION_AFTERNOON) {
            timeAdpater.setTime(13, 0);
        } else if (position == POSITION_EVENING) {
            timeAdpater.setTime(18, 0);
        } else if (position == POSITION_NIGHT) {
            timeAdpater.setTime(20, 0);
        } else {
            dateTimeDialogCallbacks.selectTimeManually();
        }
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {

    }
});

我在这里设置标签。唯一的例外是我通过底层活动实现的dateTimeDialogCallbacks.selectTimeManually();调用的最后一个字段。从TimePicker中选择时间之后,我调用DateTimeSelectionDialog实现的方法。

public void setTime(int hour, int minute) {
        this.hour = hour;
        this.minute = minute;
        timeAdpater.setTime(hour, minute);
    }

timeAdapter.setTime(hour, minute)将设置该字段并通​​知适配器有关数据更改的信息。

一切似乎都很有效。 问题是setOnItemSelectedListener与普通的点击监听器完全不同。因为只有在单击的字段与先前选择的字段不同时才会调用它。 因此,一旦用户手动选择时间,他就不能手动第二次选择它。这当然是一个错误。

所以我的问题是这是什么解决方法?谷歌的人显然找到了办法,所以可以做到。

1 个答案:

答案 0 :(得分:0)

那么,在您的代码的上下文中,您可以在onNothingSelected(AdapterView父级)中添加检查,这是不理想的但是一种解决方法!