Search code examples
javaandroidandroid-fragmentsandroid-viewandroid-loadermanager

Refreshing a view inside a fragment


I have searched the numerous questions that look like this one, but haven't found my answer in any of them.

I have an activity that has 3 tabs accessible through the action bar. I achieved this by adding 3 fragments that inflate a custom view I made extending the view class.

At the moment the database changes, I try to refresh the view in my tab by calling invalidate()/postinvalidate(), but this does not work. The same is true for calling onCreateView of the fragment just as many other options I considered.

When I go to another tab and go back, however, the change has been made and my view is updated as it should be.

How can I simulate the same thing that happens when changing to another tab? What does happen. I tried to look at the Fragment lifecycle (tried to call onCreateView()) to figure it out but it just doesn't want to refresh/redraw as it should.

The data is loaded properly, as the data is changed when I change to another tab.

I deleted some of the code as it is no longer relevant. I implemented Cursorloaders instead of my own Observer pattern to notify a change. This is my main activity right now.

The question is what should I do now if I want to redraw the view inside these fragments. If I apply fragmentObject.getView().invalidate() it does not work. I'm having the same problem as before, but now my Observer to notify a change in the database is properly implemented with loaders.

public class ArchitectureActivity extends Activity implements LoaderManager.LoaderCallbacks<Cursor> {

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);     
    setContentView(R.layout.main);

    ActionBar actionbar = getActionBar();
    actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

    ActionBar.Tab EditTab = actionbar.newTab().setText("Edit");
    ActionBar.Tab VisualizeTab = actionbar.newTab().setText("Visualize");
    ActionBar.Tab AnalyseTab = actionbar.newTab().setText("Analyse");

    Fragment editFragment = new EditFragment();
    Fragment visualizeFragment = new VisualizeFragment();
    Fragment analyseFragment = new AnalyseFragment();

    EditTab.setTabListener(new MyTabsListener(editFragment));
    VisualizeTab.setTabListener(new MyTabsListener(visualizeFragment));
    AnalyseTab.setTabListener(new MyTabsListener(analyseFragment));

    actionbar.addTab(EditTab);
    actionbar.addTab(VisualizeTab);
    actionbar.addTab(AnalyseTab);

    ArchitectureApplication architectureApplication = (ArchitectureApplication)getApplicationContext();
    architectureApplication.initialize();

    getLoaderManager().initLoader(0, null, this);
    getLoaderManager().initLoader(1, null, this);
}

public Loader<Cursor> onCreateLoader(int id, Bundle args) {
    if (id == 0){
        return new CursorLoader(this, GraphProvider.NODE_URI , null, null, null, null);
    } else if (id == 1){
        return new CursorLoader(this, GraphProvider.ARC_URI , null, null, null, null);
    }
    return null;
}

public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
    // Reloading of data, actually happens because when switching to another tab the new data shows up fine
    Log.e("Data", "loaded");
}

public void onLoaderReset(Loader<Cursor> loader) {
}
}

Solution

  • I've found a workaround to refresh the view inside my fragment. I recreated (new CustomView) the view every time the database has been updated. After that I call setContentView(CustomView view). It looks more like a hack, but it works and nothing else that I tried does.

    Although my problem was not actually solved, I gave the reward to Alex Lockwood. His advice on Loaders made my application better and it caused me to keep looking for a solution that I eventually found.