在 Android 中通过 ArrayAdapter 在 ListView 中单击它后如何更改单个 ImageView 背景?
How can I change single ImageView background after clicking on it in ListView via ArrayAdapter in Android?
我的 Fragment activity 中有一个 ListView,它获取存储在内部存储器中的文件的名称。 ListView 还有一个 ImageView,当点击它时,它会设置一个显示通知的警报。我希望在单击时更改特定 ImageView 的背景。我的问题是关闭应用程序后,ImageView 的背景变回正常。那么,我应该如何改变每个被点击的ImageView的背景呢?
这是我的片段class代码:
ListView listView;
CustomArrayAdapter arrayAdapter;
ArrayList<String> FilesInFolder;
FilesInFolder = GetFiles(getActivity().getFilesDir());
arrayAdapter = new CustomArrayAdapter(FilesInFolder, getContext());
Collections.sort(FilesInFolder);
listView.setAdapter(arrayAdapter);
这是我的 CustomArrayAdapter class:
public class CustomArrayAdapter extends ArrayAdapter<String> {
private ArrayList<String> list;
Context mContext;
TimePickerDialog timePickerDialog;
DatePickerDialog datePickerDialog;
int currentHour, currentMinute, currentYear, currentMonth, currentDay, currentDate;
int setHour, setMinute, setYear, setMonth, setDay;
Calendar calendar;
AlarmManager alarmManager;
PendingIntent pendingIntent;
public static final String NOTIFICATION_CHANNEL_ID = "10001";
public static class ViewHolder {
TextView titleTextView;
ImageView imageView;
}
public CustomArrayAdapter(ArrayList<String> list, Context context) {
super(context, R.layout.custom_listview, list);
this.list = list;
this.mContext = context;
calendar = Calendar.getInstance();
currentHour = calendar.get(Calendar.HOUR_OF_DAY);
currentMinute = calendar.get(Calendar.MINUTE);
currentYear = calendar.get(Calendar.YEAR);
currentMonth = calendar.get(Calendar.MONTH);
currentDay = calendar.get(Calendar.DAY_OF_MONTH);
currentDate = calendar.get(Calendar.DATE);
}
public View getView(int position, View convertView, ViewGroup parent) {
String string = getItem(position);
ViewHolder viewHolder;
if (convertView == null) {
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.custom_listview, parent, false);
viewHolder.imageView = convertView.findViewById(R.id.bellIcon);
viewHolder.titleTextView = convertView.findViewById(R.id.textView);
convertView.setTag(viewHolder);
viewHolder = (ViewHolder) convertView.getTag();
}
else {
viewHolder = (ViewHolder) convertView.getTag();
}
ViewHolder finalViewHolder = viewHolder;
viewHolder.imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (finalViewHolder.imageView.getTag() == "done") {
Snackbar.make(v, setHour + " " + setMinute + ", on" + " " + setDay + " " + setMonth + " " + setYear, Snackbar.LENGTH_LONG).show();
} else {
timePickerDialog = new TimePickerDialog(getContext(), new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker timePicker, final int hourOfDay, int minute) {
setHour = hourOfDay;
setMinute = minute;
datePickerDialog = new DatePickerDialog(getContext(), new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
setYear = year;
setMonth = month;
setDay = dayOfMonth;
Calendar setTime = Calendar.getInstance();
setTime.set(setYear, setMonth, setDay, setHour, setMinute, 0);
Date date = setTime.getTime();
scheduleNotification(string, date.getTime());
finalViewHolder.imageView.setImageResource(R.drawable.ic_baseline_notifications_active_24);
finalViewHolder.imageView.setTag("done");
Snackbar.make(v, "Reminder set for: " + string + "!", Snackbar.LENGTH_LONG)
.setAnimationMode(BaseTransientBottomBar.ANIMATION_MODE_SLIDE)
.show();
}
}, currentYear, currentMonth, currentDay);
datePickerDialog.show();
}
}, currentHour, currentMinute, false);
timePickerDialog.show();
}
}
});
viewHolder.titleTextView.setText(string);
return convertView;
}
public void scheduleNotification (String fileName, long delay) {
Intent notificationIntent = new Intent(this.mContext, MyBroadCastReceiver.class);
notificationIntent.putExtra(MyBroadCastReceiver.NOTIFICATION_ID, (int)System.currentTimeMillis());
notificationIntent.putExtra("title", fileName);
pendingIntent = PendingIntent.getBroadcast(getContext(), (int)System.currentTimeMillis(), notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmManager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, delay, pendingIntent);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, delay, pendingIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, delay, pendingIntent);
}
}
}
这是预期的行为,因为您没有保存数据的状态。我建议创建一个反映真实状态的模型。也许是这样的:
class File {
String filepath;
boolean reminderSet;
}
现在您有了一个模型 class,您可以使用 Room 以持久的方式保存数据。当执行点击时,只需去更新数据库中的相应对象(将 reminderSet 设置为 true)。这样,当您在应用程序启动后加载数据时,它仍会保留其先前的状态。
我的 Fragment activity 中有一个 ListView,它获取存储在内部存储器中的文件的名称。 ListView 还有一个 ImageView,当点击它时,它会设置一个显示通知的警报。我希望在单击时更改特定 ImageView 的背景。我的问题是关闭应用程序后,ImageView 的背景变回正常。那么,我应该如何改变每个被点击的ImageView的背景呢?
这是我的片段class代码:
ListView listView;
CustomArrayAdapter arrayAdapter;
ArrayList<String> FilesInFolder;
FilesInFolder = GetFiles(getActivity().getFilesDir());
arrayAdapter = new CustomArrayAdapter(FilesInFolder, getContext());
Collections.sort(FilesInFolder);
listView.setAdapter(arrayAdapter);
这是我的 CustomArrayAdapter class:
public class CustomArrayAdapter extends ArrayAdapter<String> {
private ArrayList<String> list;
Context mContext;
TimePickerDialog timePickerDialog;
DatePickerDialog datePickerDialog;
int currentHour, currentMinute, currentYear, currentMonth, currentDay, currentDate;
int setHour, setMinute, setYear, setMonth, setDay;
Calendar calendar;
AlarmManager alarmManager;
PendingIntent pendingIntent;
public static final String NOTIFICATION_CHANNEL_ID = "10001";
public static class ViewHolder {
TextView titleTextView;
ImageView imageView;
}
public CustomArrayAdapter(ArrayList<String> list, Context context) {
super(context, R.layout.custom_listview, list);
this.list = list;
this.mContext = context;
calendar = Calendar.getInstance();
currentHour = calendar.get(Calendar.HOUR_OF_DAY);
currentMinute = calendar.get(Calendar.MINUTE);
currentYear = calendar.get(Calendar.YEAR);
currentMonth = calendar.get(Calendar.MONTH);
currentDay = calendar.get(Calendar.DAY_OF_MONTH);
currentDate = calendar.get(Calendar.DATE);
}
public View getView(int position, View convertView, ViewGroup parent) {
String string = getItem(position);
ViewHolder viewHolder;
if (convertView == null) {
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.custom_listview, parent, false);
viewHolder.imageView = convertView.findViewById(R.id.bellIcon);
viewHolder.titleTextView = convertView.findViewById(R.id.textView);
convertView.setTag(viewHolder);
viewHolder = (ViewHolder) convertView.getTag();
}
else {
viewHolder = (ViewHolder) convertView.getTag();
}
ViewHolder finalViewHolder = viewHolder;
viewHolder.imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (finalViewHolder.imageView.getTag() == "done") {
Snackbar.make(v, setHour + " " + setMinute + ", on" + " " + setDay + " " + setMonth + " " + setYear, Snackbar.LENGTH_LONG).show();
} else {
timePickerDialog = new TimePickerDialog(getContext(), new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker timePicker, final int hourOfDay, int minute) {
setHour = hourOfDay;
setMinute = minute;
datePickerDialog = new DatePickerDialog(getContext(), new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
setYear = year;
setMonth = month;
setDay = dayOfMonth;
Calendar setTime = Calendar.getInstance();
setTime.set(setYear, setMonth, setDay, setHour, setMinute, 0);
Date date = setTime.getTime();
scheduleNotification(string, date.getTime());
finalViewHolder.imageView.setImageResource(R.drawable.ic_baseline_notifications_active_24);
finalViewHolder.imageView.setTag("done");
Snackbar.make(v, "Reminder set for: " + string + "!", Snackbar.LENGTH_LONG)
.setAnimationMode(BaseTransientBottomBar.ANIMATION_MODE_SLIDE)
.show();
}
}, currentYear, currentMonth, currentDay);
datePickerDialog.show();
}
}, currentHour, currentMinute, false);
timePickerDialog.show();
}
}
});
viewHolder.titleTextView.setText(string);
return convertView;
}
public void scheduleNotification (String fileName, long delay) {
Intent notificationIntent = new Intent(this.mContext, MyBroadCastReceiver.class);
notificationIntent.putExtra(MyBroadCastReceiver.NOTIFICATION_ID, (int)System.currentTimeMillis());
notificationIntent.putExtra("title", fileName);
pendingIntent = PendingIntent.getBroadcast(getContext(), (int)System.currentTimeMillis(), notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmManager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, delay, pendingIntent);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, delay, pendingIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, delay, pendingIntent);
}
}
}
这是预期的行为,因为您没有保存数据的状态。我建议创建一个反映真实状态的模型。也许是这样的:
class File {
String filepath;
boolean reminderSet;
}
现在您有了一个模型 class,您可以使用 Room 以持久的方式保存数据。当执行点击时,只需去更新数据库中的相应对象(将 reminderSet 设置为 true)。这样,当您在应用程序启动后加载数据时,它仍会保留其先前的状态。