簡體   English   中英

刷新片段內的視圖

[英]Refreshing a view inside a fragment

我搜索了很多看起來像這個問題的問題,但是沒有找到我的答案。

我有一個活動,通過操作欄可以訪問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) {
}
}
  1. 不要試圖自己調用onCreateView() ......這是一個生命周期方法,只能由框架調用。

  2. Fragment是可重用的UI組件。 他們有自己的生命周期,顯示自己的視圖,並定義自己的行為。 你通常不需要讓你的Activity亂用Fragment的內部工作,因為Fragment的行為應該是自包含的並且獨立於任何特定的Activity

    也就是說,我認為最好的解決方案是讓每個Fragment實現LoaderManager.LoaderCallbacks<D>接口。 每個Fragment將初始化一個Loader (即如果你使用的是由SQLite數據庫支持的ContentProvider則為CursorLoader ),並且Loader將負責(1)在后台線程上加載數據,以及(2)監聽內容更改對數據源進行的操作,並在發生內容更改時將新數據傳遞給onLoadFinished()

    此解決方案優於您當前的解決方案,因為它完全由事件驅動。 您只需要在將數據傳遞到onLoadFinished()時刷新視圖(而不是每次單擊新選項卡時都必須手動檢查數據源是否已更改)。

  3. 如果你很懶,只想要快速解決方案,你也可以在FragmentonResume()方法中刷新視圖。

我有一個類似的(雖然不完全相同)問題,我可以通過以下方式解決:

在我添加的片段中

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

當我想要刷新片段的myView時,我從活動中調用了這個方法。 使用post()可確保視圖僅在准備好繪制時失效。

我找到了一個解決方法來刷新片段中的視圖。 每次更新數據庫時,我都會重新創建(新的CustomView)視圖。 之后我調用setContentView(CustomView視圖)。 它看起來更像是一個黑客,但它有效,沒有其他我嘗試過的。

雖然我的問題實際上沒有解決,但我還是給Alex Lockwood獎勵了。 他對裝載機的建議使我的應用程序更好,這讓我一直在尋找我最終找到的解決方案。

我遇到過同樣的問題。 我的解決方案是分離片段並再次附加它。

        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        Fragment f = getFragment(action);
        if(forceUpdate)
        {
            fragmentTransaction.detach(f);
            fragmentTransaction.attach(f);
        }
        fragmentTransaction.replace(R.id.mainFragment, f);
        fragmentTransaction.commit();
        currentAction = action;

最快的解決方案適合我:

 @Override
    public void onPause() {
        super.onPause();
        if (isRemoving() && fragmentView != null) {
            ((ViewGroup) fragmentView).removeAllViews();
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM