15

I am learning Android and when trying to develop an application I came across the following situation:

I have an Activity that has two Fragments: ReminderListFragment and FilterListFragment. The first fragment has a list of Reminders and the second, a list of filters with the name and number of items registered in each filter. However, when I exclude some Reminder, the FilterListFragment values are not updated. The same thing happens when I delete one of the filters (in which case it deletes all records for the selected filter), it does not update the Reminders list.

enter image description here

FilterListFragment code:

    @Override
        public boolean onContextItemSelected(MenuItem item) {
            if (item.getGroupId() == R.id.context_menu_category) {
                // Used to verify it it is the right context_menu //Gets the item
                // position and gets the category in that position:
                AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
                Category category = ((CategoryFilter) lvFilters.getAdapter().getItem(info.position)).getCategory();

                // Switch between the options in the context menu(Edit and Delete)
                switch (item.getItemId()) {
                case R.id.edit:
                    // Passes the current reminder to be edited via Intent and
                    // Invokes edit method
                    DialogFragment newFragment = EditCategoryDialogFragment.newInstance(category);
                    newFragment.show(getFragmentManager(), "" + R.string.dialog_editcategory_title);
                    updateListView();
                    return true;
                case R.id.delete:
                    // Invokes delete method
                    try {
                        // Deletes from the bank;
                        Controller.instance(getActivity().getApplicationContext()).deleteReminderByCategory(category);
                        Controller.instance(getActivity().getApplicationContext()).deleteCategory(category);
                        updateListView();
                        return true;
                    } catch (DBException e) {
                        Log.e(TAG, e.getMessage());
                    }
                    updateListView();
                    return true;
                default:
                    return super.onContextItemSelected(item);
                }

            }
            return super.onContextItemSelected(item);
        }

ReminderListFragment code:

@Override
    public boolean onContextItemSelected(MenuItem item) {
        if (item.getGroupId() == R.id.context_menu_reminder) {
            AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
            Reminder reminder = (Reminder) contextMenuAdapter.getItem(info.position);
            switch (item.getItemId()) {
            case R.id.edit:
                Intent editIntent = editIntent(reminder);
                editIntent.putExtra("id", reminder.getId());
                editIntent.putExtra("text", reminder.getText());
                editIntent.putExtra("details", reminder.getDetails());
                startActivity(editIntent);
                updateListView(null);
                return true;
            case R.id.delete:
                try {
                    Controller.instance(getActivity().getApplicationContext()).deleteReminder(reminder);
                } catch (DBException e) {
                    Log.e(TAG, e.getMessage());
                }
                updateListView(null);
                return true;
            default:
                return super.onContextItemSelected(item);
            }
        }
        return super.onContextItemSelected(item);
    }
Leomar de Souza
  • 677
  • 10
  • 23

4 Answers4

7

You should communicate with second fragment through activity. When you do something in one fragment that should affect second one then you should call some method in your activity that will call update method in the second fragment. So for example activity:

public class MainActivity extends Activity(){
   private Fragment fragmentOne, fragmentTwo;

   public void updateFragmentTwo(){
       fragmentTwo.updateListView();
   }
}

fragment:

public class FirstFragment extends Fragment{


   public void updateFragmentTwo(){
       ((MyActivity)getActivity()).updateFragmentTwo();
   }
}
matip
  • 794
  • 3
  • 7
  • 27
  • Hello @matip, I've implemented this solution, but the application stops working when you run the option to delete Reminder, for example. Also, I had to change the updateListView () method to public as it was private. Is there any other way to solve it? – Leomar de Souza May 22 '18 at 01:09
  • This seems like a clean solution to me to notify each other via the common activity. The most professional solution would be, to share a ViewModel, so that all fragments are notified, when the data changes. In this case the ViewModel must be bound to the common activity. In both cases the activity is the connecting instance. – Blcknx May 24 '18 at 09:04
0

For fragment to fragment communication through a single activity would be possible through interfaces or I should say callbacks. I think by implementing the interface in your activity you could communicate to both the fragments and when the listener in the fragment is called you could perform action accordingly. As what I think when you have one activity containing two fragments you would easily know which fragment is currently visible and where you have to update data. There is a link below about implementing an interface for communication between activity and fragment.

https://google-developer-training.gitbooks.io/android-developer-advanced-course-practicals/unit-1-expand-the-user-experience/lesson-1-fragments/1-2-p-communicating-with-a-fragment/1-2-p-communicating-with-a-fragment.html

Hope it helps!

Harsh Jain
  • 1,372
  • 1
  • 9
  • 17
0

I was looking for something similar, this helped me then. update listview dynamically with adapter

In addition to this, you should be passing data using bundles, interface or intents

Saranya Vs
  • 3
  • 1
  • 6
-2

I was able to resolve it by adding the following methods:

On FilterListFragment class:

public void reloadReminderListFragment() {
        Fragment currentFragment = getActivity().getFragmentManager().findFragmentById(R.id.listReminders);
        if (currentFragment instanceof ReminderListFragment) {
            FragmentTransaction fragTransaction = (getActivity()).getFragmentManager().beginTransaction();
            fragTransaction.detach(currentFragment);
            fragTransaction.attach(currentFragment);
            fragTransaction.commit();
        }
    }

On ReminderListFragment class:

public void reloadFilterListFragment() {
        Fragment currentFragment = getActivity().getFragmentManager().findFragmentById(R.id.listCategories);
        if (currentFragment instanceof FilterListFragment) {
            FragmentTransaction fragTransaction = (getActivity()).getFragmentManager().beginTransaction();
            fragTransaction.detach(currentFragment);
            fragTransaction.attach(currentFragment);
            fragTransaction.commit();
        }
    }
Leomar de Souza
  • 677
  • 10
  • 23
  • 3
    Detaching and attaching the same fragment to update it, does not look like a serious solution to me. I produces a lot of overhead. It's somehow like restarting the car to turn the radio off. – Blcknx May 24 '18 at 08:56
  • try to use more complicated tools... ReplaySubject, RxBus something like that – Muhammadakbar Rafikov May 24 '18 at 13:22