Search code examples
androidandroid-listviewimageviewandroid-arrayadaptercustom-arrayadapter

How can I change single ImageView background after clicking on it in ListView via ArrayAdapter in Android?


I have a ListView in my Fragment activity that gets the name of files stored in internal storage. The ListView also has an ImageView which when clicked, sets an alarm for showing notification. I want the particular ImageView's background to be changed when clicked. My problem is that after closing the app, the ImageView's background changes back to the normal. So, how should I change every ImageView's background that have been clicked?

Here is my Fragment class code:

ListView listView;
CustomArrayAdapter arrayAdapter;
ArrayList<String> FilesInFolder;

FilesInFolder = GetFiles(getActivity().getFilesDir());

arrayAdapter = new CustomArrayAdapter(FilesInFolder, getContext());

Collections.sort(FilesInFolder);

listView.setAdapter(arrayAdapter);

This is my 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);
        }
    }
}

Solution

  • This is the expected behaviour since you are not saving the state of your data. I would propose to create a model that reflects the real state. Maybe something like:

    class File {
        String filepath;
        boolean reminderSet;
    }
    

    Now that you have a model class, you can use Room to save the the data in a persistent way. When a click is performed, just go and update the corresponding object in DB (set reminderSet to true). In this way, when you will load the data after an app start, it will still retain its previous state.