刷新片段内的视图

我已经搜索了许多看起来像这样的问题,但没有在任何一个问题中找到我的答案。

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

在数据库更改时,我尝试通过调用invalate()/postinvalidate()来刷新选项卡中的视图,但这不起作用。调用片段的 onCreateView 也是如此,就像我考虑过的许多其他选项一样。

但是,当我转到另一个选项卡并返回时,更改已经完成,并且我的视图已按预期进行更新。

如何模拟更改为另一个选项卡时发生的相同情况?发生了什么。我试图查看Fragment生命周期(试图调用createView())来弄清楚它,但它只是不想像它应该的那样刷新/重绘。

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

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

问题是,如果我想重新绘制这些片段中的视图,我现在该怎么办。如果我应用 fragmentObject.getView().invalidate(), 它不起作用。我遇到了与以前相同的问题,但现在我的观察者通知数据库中的更改是使用加载程序正确实现的。

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) {
}
}

答案 1
  1. 不要试图给自己打电话...它是一个生命周期方法,应该只由框架调用。onCreateView()

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

    也就是说,我认为最好的解决方案是让你的每个实现接口。每个都将初始化一个(即,如果您使用的是 SQLite 数据库支持的数据库),它将负责 (1) 在后台线程上加载数据,以及 (2) 侦听对数据源所做的内容更改,并在发生内容更改时提供新数据。FragmentLoaderManager.LoaderCallbacks<D>FragmentLoaderCursorLoaderContentProviderLoaderonLoadFinished()

    此解决方案比当前解决方案更好,因为它完全由事件驱动。您只需要在将数据传递到时刷新视图(而不必在每次单击新选项卡时手动检查数据源是否已更改)。onLoadFinished()

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


答案 2

我有一个类似的(虽然不相同)问题,我可以通过以下方式解决:

在我添加的片段中

public void invalidate() {
    myView.post(new Runnable() {
        @Override
        public void run() {
            myView.invalidate();
        }
    });
}

当我想刷新片段的视图 myView 时,我从活动中调用了此方法。使用 post() 可确保视图仅在准备好绘制时才无效。


推荐