Search code examples
androidlistviewandroid-fragmentsnotifydatasetchanged

Android: How to change ListView item's value in Fragment?


I created a Fragment that has a ListView with several items. According to my plan, when I click one of the items on the ListView, I move to another Fragment, get data from them, replace the original data with the new one and update the ListView. In order to do that I wrote the code as follows.

  1. Code inside the onCreateView() method

    listAdapter = new AlarmOptionItemListAdapter();
    lvAlarmOptionList = (ListView) view.findViewById(R.id.lvAlarmOptionList);
    initializeListItems();
    lvAlarmOptionList.setAdapter(listAdapter);
    
  2. The initializeListItems() method that adds several items to lvAlarmOptionList, the ListView instance.

    private void initializeListItems() {
        itemRepeatAlarm = new TextOnlyItem();
        itemRepeatAlarm.setTitle(getString(R.string.repeat_weekly));
        itemRepeatAlarm.setSubtitle(getString(R.string.never));
        listAdapter.addItem(itemRepeatAlarm);
    
        itemAlarmLock = new TextOnlyItem();
        itemAlarmLock.setTitle(getString(R.string.alarm_lock));
        itemAlarmLock.setSubtitle(getString(R.string.choose_option));
        listAdapter.addItem(itemAlarmLock);
    }
    
  3. onActivityResult() method that gets the data from the other Fragment and modify the items on the ListView

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(resultCode == RESULT_OK && data != null) {
        switch(requestCode) {
            case CODE_PIN:
                String value = data.getStringExtra(Keys.VALUE);
                if(value != null) {
                    Log.i(ApplicationManager.LOG, "PIN set to " + value);
                }
                break;
    
            case CODE_PASSWORD:
                String password = data.getStringExtra(Keys.VALUE);
                if(password != null) {
                    Log.i(ApplicationManager.LOG, "Password set to " + password);
                }
                break;
    
            case CODE_REPEAT:
                repeatType = data.getIntExtra(Keys.REPEAT_TYPE, 0);
                switch(repeatType) {
                    case Keys.SINGLE:
                    case Keys.PLURAL:
                        Toast.makeText(activity, data.getStringExtra(Keys.REPEAT_MESSAGE), Toast.LENGTH_SHORT).show();
                        itemRepeatAlarm.setSubtitle(getString(R.string.on));
                        listAdapter.notifyDataSetChanged();
                        onResume();
                        break;
    
                    case Keys.NO_REPEAT:
                        Toast.makeText(context, getString(R.string.alarm_will_never_repeat), Toast.LENGTH_SHORT).show();
                        itemRepeatAlarm.setSubtitle(getString(R.string.never));
                        listAdapter.notifyDataSetChanged();
                        onResume();
                        break;
    
                    case Keys.EVERY_DAY:
                        Toast.makeText(context, getString(R.string.alarm_will_repeat_every_day), Toast.LENGTH_SHORT).show();
                        itemRepeatAlarm.setSubtitle(getString(R.string.every_day));
                        listAdapter.notifyDataSetChanged();
                        onResume();
                        break;
                }
                break;
    
            case CODE_PATTERN:
                pattern = data.getStringExtra(Keys.VALUE);
                if(pattern != null) {
                    Log.i(ApplicationManager.LOG, "Pattern set to " + pattern);
                }
                itemAlarmLock.setSubtitle(getString(R.string.pattern));
                listAdapter.notifyDataSetChanged();
                onResume();
                break;
        }
    }
    }
    
  4. And finally, the onResume() method

    @Override
    public void onResume() {
        super.onResume();
        if(listAdapter != null) {
            listAdapter.notifyDataSetChanged();
        }
    }
    

I managed to successfully bring data from the other Fragment using the onActivityResult() method, but I keep failing to refresh the data in the ListView.


Solution

  • In your onActivityResult you are modifying the itemRepeatAlarm object , but it is not updated automatically in the adapter. You need to get the object from the adapter and set it's value like this :

    ((TextOnlyItem) listAdapter.getItem(0)).setSubtitle(getString(R.string.on);
    listAdapter.notifyDataSetChanged();
    

    Hope this works.