【发布时间】:2017-11-15 12:10:29
【问题描述】:
我想创建一个时间和日期选择对话框,就像 goolgle keep 应用中的那个,当人们想要在未来收到事件提醒时显示。
该对话框有两个用于日期和时间的微调框字段。 前几个字段是口头描述,例如今天、明天等。最后一个元素是手动选择日期。单击它会打开一个时间/日期选择器。
我当前的解决方案为每个 Spinner 使用两个自定义适配器。适配器是类似的,所以我将只进一步描述时间选择部分。
我的 TimeSelection 示例实现了 getView 和 getDropDownView 方法。 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 与普通的点击监听器不一样。因为仅当单击的字段与先前选择的字段不同时才会调用它。
因此,一旦用户手动选择时间,他就无法再次手动选择时间。这当然是一个错误。
所以我的问题是解决方法是什么?谷歌的人显然找到了办法,所以可以做到。
【问题讨论】:
-
试试this 链接。希望对您有所帮助。
-
@CagriYalcin 好东西。只需更改它以覆盖 AppComapatSpiner。
标签: android android-arrayadapter android-spinner dialogfragment