Search code examples
androidandroid-listviewandroid-datepicker

Android: ListView position and DatePicker


I have onItemClickListener for the ListView that opens DatePicker dialog when an item is clicked:

list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        showDatePickerDialog(view);
    }
});

public void showDatePickerDialog(View v) {
    DialogFragment newFragment = new DatePickerFragment();
    newFragment.show(getFragmentManager(), "datePicker");
}

After date in DatePicker gets set, I have onDateSet method which I want to use to update database and set date for item that was clicked in ListView:

public void onDateSet(DatePicker view, int year, int month, int day) {
    ...
    dataSource.updateDate(adapter.getItemId(position), month + "/" + day + "/" + year);
    ...
} 

How can I pass ListView position of the item that was clicked to onDateSet so that my database helper knows which record to update?


EDIT: Here's the DatePickerFragment class:

public static class DatePickerFragment extends DialogFragment
        implements DatePickerDialog.OnDateSetListener {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Use the current date as the default date in the picker
        final Calendar c = Calendar.getInstance();
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH);
        int day = c.get(Calendar.DAY_OF_MONTH);

        // Create a new instance of DatePickerDialog and return it
        return new DatePickerDialog(getActivity(), this, year, month, day);
    }

    public void onDateSet(DatePicker view, int year, int month, int day) {
        ...
        dataSource.updateDate(adapter.getItemId(position), month + "/" + day + "/" + year);
        ...
    }
}

Thanks!


Solution

  • Send the position to DatePickerFragment - I guess this is a class of your own. Send this parameter through arguments (as this is a best practice to protect your code in fragment recreations):

    public class DatePickerFragment extends Fragment {
    
        private DatePickerListener datePickerListener;
        private int listPosition = -1;
        private static final String POSITION_ARG_KEY = "POSITION_ARG_KEY";
    
        public static DatePickerFragment newInstance(int position) {
            DatePickerFragment fragment = new DatePickerFragment();
            Bundle args = new Bundle();
            args.putInt(POSITION_ARG_KEY, position);
            fragment.setArguments(args);
            return fragment;
        }
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            Bundle args = getArguments();
            if (args != null) {
                listPosition = args.getInt(POSITION_ARG_KEY);
            }
        }
    
        @Override
        public void onAttach(Activity activity) {
            super.onAttach(activity);
            if (activity instanceof DatePickerListener) {
                datePickerListener = (DatePickerListener) activity;
            }
        }
    
        @Override
        public void onDetach() {
            super.onDetach();
            datePickerListener = null;
        }
    
        public void methodThatCallsActivity() {
            if(datePickerListener) {
                datePickerListener.onDateSet(datePicker, year, month, day, this.listPosition);
            }
        }
    
        // / the rest of the code
    
        public static interface DatePickerListener {
            public void onDateSet(DatePicker view, int year, int month, int day, int listPosition);
        }
    }
    

    Then in the activity that displays the fragment, (it must implement DatePickerListener):

    A. send the list position:

    public void showDatePickerDialog(int listPosition) {
        DialogFragment newFragment = DatePickerFragment.newInstance(listPosition);
        newFragment.show(getFragmentManager(), "datePicker");
    }
    

    B. call this method from list item click:

    list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            showDatePickerDialog(position);
        }
    });
    

    C. You have the list position in onDateSet implementation:

    public void onDateSet(DatePicker view, int year, int month, int day, int listPosition) {
        // your relevant code
    }
    

    To brief: send the list position through arguments and parameters from listview to fragment and from there to parent activity.