刷新片段内的视图

J. *_*aes 19 java android android-fragments android-view android-loadermanager

我搜索了很多看起来像这个问题的问题,但是没有找到我的答案.

我有一个活动,通过操作栏可以访问3个选项卡.我通过添加3个片段来实现这一点,这些片段扩展了我扩展视图类的自定义视图.

在数据库更改的那一刻,我尝试通过调用invalidate()/ postinvalidate()刷新我的选项卡中的视图,但这不起作用.调用片段的onCreateView就像我考虑的其他选项一样.

然而,当我转到另一个选项卡然后返回时,已经进行了更改,并且我的视图会按原样更新.

如何模拟更改为另一个选项卡时发生的相同事情?会发生什么 我试着看看Fragment生命周期(尝试调用onCreateView())来解决它,但它只是不想刷新/重绘它应该.

正确加载数据,因为当我更改为另一个选项卡时数据会更改.

我删除了一些代码,因为它不再相关.我实现了Cursorloaders而不是我自己的Observer模式来通知更改.这是我现在的主要活动.

问题是,如果我想重绘这些片段中的视图,我现在应该怎么做.如果我应用fragmentObject.getView().invalidate()它不起作用.我遇到了和以前一样的问题,但现在我的Observer通知加载器正确实现了数据库中的更改.

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) {
}
}
Run Code Online (Sandbox Code Playgroud)

Ale*_*ood 21

  1. 不要试图给onCreateView()自己打电话......它是一种生命周期方法,只能由框架调用.

  2. Fragments是可重用的UI组件.他们有自己的生命周期,显示自己的视图,并定义自己的行为.你通常不需要Activity乱用a的内部工作Fragment,因为它Fragment的行为应该是独立的并且独立于任何特定的行为Activity.

    也就是说,我认为最好的解决方案是让每个人都Fragment实现LoaderManager.LoaderCallbacks<D>接口.每次Fragment都会初始化Loader(即CursorLoader,如果您使用的是ContentProvider由一个SQLite数据库支持),并且Loader将负责(1)加载在后台线程的数据,和(2)倾听那些对变更的内容数据源,并onLoadFinished()在发生内容更改时提供新数据.

    此解决方案优于您当前的解决方案,因为它完全由事件驱动.您只需在传送数据时刷新视图onLoadFinished()(而不是每次单击新选项卡时都必须手动检查数据源是否已更改).

  3. 如果你很懒,只想要一个快速的解决方案,你也可以在你FragmentonResume()方法中刷新视图.


J. *_*aes 3

我找到了一种解决方法来刷新片段内的视图。每次更新数据库时,我都会重新创建(新的 CustomView)视图。之后我调用 setContentView(CustomView view)。它看起来更像是一种黑客攻击,但它确实有效,而我尝试过的其他方法都不起作用。

虽然我的问题并没有真正解决,但我把奖励给了Alex Lockwood。他对加载器的建议使我的应用程序变得更好,并促使我继续寻找最终找到的解决方案。