成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Fragment切換時,MVP中的P不能被重新創(chuàng)建

Reducto / 3539人閱讀

摘要:把項目的登陸注冊和修改密碼全部替換成順便通過簡單的模式來實現(xiàn)簡單記錄下遇到的一些問題誰是這里把做為而不是宿主具體原因有待深究然而能力有限的管理登陸注冊和修改密碼一個三個繼承自基類的并各自對應(yīng)自己的和這里使用到了使用來管理的生命周期并在中初始

把項目的登陸,注冊和修改密碼全部替換成Fragment,順便通過簡單的MVP模式來實現(xiàn),簡單記錄下遇到的一些問題.

誰是V

這里把Fragment做為V,而不是宿主Activity.(具體原因有待深究,然而能力有限)

Fragment的管理

登陸,注冊和修改密碼,一個三個Fragment,繼承自基類的IBaseFragment,并各自對應(yīng)自己的P和M.

public abstract class IBaseFragment extends Fragment implements IBaseView

這里使用到了DataBinding.

使用Loader來管理P的生命周期,并在IBaseFragment中初始化

PresenterLoader代碼如下:

    public class PresenterLoader

extends Loader { private P prensenter; private PresenterFactory

factory; /** * Stores away the application context associated with context. * Since Loaders can be used across multiple activities it"s dangerous to * store the context directly; always use {@link #getContext()} to retrieve * the Loader"s Context, don"t use the constructor argument directly. * The Context returned by {@link #getContext} is safe to use across * Activity instances. * * @param context used to retrieve the application context. */ public PresenterLoader(Context context, PresenterFactory

factory) { super(context); this.factory = factory; } @Override protected void onStartLoading() { super.onStartLoading(); if (prensenter!=null){ deliverResult(prensenter); return; } forceLoad(); } @Override protected void onForceLoad() { super.onForceLoad(); prensenter = factory.create(); deliverResult(prensenter); } @Override protected void onStopLoading() { super.onStopLoading(); } @Override protected void onReset() { super.onReset(); if (prensenter!=null) { prensenter.detach(); prensenter = null; } } }

 @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        LoaderManager loaderManager = activity.getSupportLoaderManager();
        loaderManager.initLoader(LOADER_ID, null, new LoaderManager.LoaderCallbacks

() { @Override public Loader

onCreateLoader(int id, Bundle args) { return new PresenterLoader

(activity, new PresenterFactory

() { @Override public P create() { return createPresenter(); } }); } @Override public void onLoadFinished(Loader

loader, P presenter) { IBaseFragment.this.presenter = presenter; } @Override public void onLoaderReset(Loader

loader) { } }); }

public class PresenterLoader

extends Loader

接口PresenterFactory用于生成對應(yīng)的P

抽象方法createPresenter();由子類負責具體實現(xiàn)

public interface PresenterFactory

{ P create(); }

fragment的切換流程:

登陸--->注冊---->登陸

登陸--->修改密碼---->登陸

從登陸界面跳轉(zhuǎn)到注冊/修改密碼使用如下方法:

getSupportFragmentManager().beginTransitation().add(containerId,fragment,tag).addBackToStack(tag).commit();

通過addBackToStack將當前添加的Fragment添加到回退棧

另外這里采用了add(containerId,fragment,tag)而不是replace是為了點擊實體返回鍵時,能回到登陸界面

這里有個坑

在fragment之間切換時,遇到一個坑.舉例:從登陸跳轉(zhuǎn)到注冊頁面,這個時候,注冊頁面的p的類型仍是登陸頁面的p類型.起初我以為是IBaseFragment在OnActivityCreated()初始化LoadManager只進行了一次.然而打斷點發(fā)現(xiàn),每次fragment切換這個方法都會執(zhí)行到.這時才明白是loaderManager.initLoader(LOADER_ID, null, new LoaderManager.LoaderCallbacks)這里的LOADER_ID參數(shù)的問題.在IBaseFragment中,這個參數(shù)只賦值一次,那么生成的Loader對象也只有一個,導致從登陸頁面切換到別的頁面時,P不再被重新創(chuàng)建,仍然是登陸界面那個P.

解決辦法: 在IBaseFragment中定義一個LOADER_ID如下:

 protected   int LOADER_ID = 210;

這里用protected修飾,保證可以被子類修改
然后在注冊和修改頁面重新賦值這個變量
如:

    RegisteFragment.java
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        LOADER_ID = 211;
    }

這樣就解決了P的問題.

Fragment的返回

監(jiān)聽屏幕返回按鈕事件

public boolean onKeyDown(int keyCode, KeyEvent event)

如何彈出回退棧中的Fragment(我們已經(jīng)在前面通過add和addBackToStack方法將fragment加入到回退棧)
FragmentManager有如下API:

1. popBackStackImmediate();//立即彈出
2. popBackStack(String tag,int flag);//這里的tag是add方法中最后一個參數(shù)tag,flag可以是0和                 FragmentManager.POP_BACK_STACK_INCLUSIVE,0表示不彈出自身,后者表示連同自身彈出.

通過FragmentManager.getBackStackEntryCount()得到回退棧中添加的個數(shù),然后不斷彈出,直到剩下一個為止.

   @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode==KeyEvent.KEYCODE_BACK&&event.getAction()==KeyEvent.ACTION_DOWN){
            FragmentManager fragmentManager = getSupportFragmentManager();
            if (fragmentManager.getBackStackEntryCount()>1) {
                while (fragmentManager.getBackStackEntryCount() > 1) {
                    fragmentManager.popBackStackImmediate();
                }
            }else
                finish();
        }
        return true;//這里要返回true,不然回退到最后一個可能會出現(xiàn)空白頁面
    }

大致就這樣,簡單總結(jié)下.

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/67440.html

相關(guān)文章

  • 改造 Android 官方架構(gòu)組件 ViewModel

    摘要:前言官方架構(gòu)組件在今年月份大會上被公布直到月份一直都是測試版由于工作比較繁忙期間我只是看過類似的文章但沒有在實際項目中使用過更沒有看過源碼所以對這幾個組件的使用很是生疏同時也覺得這幾個組件非常高大上非常神秘直到月份官方架構(gòu)組件正式版發(fā)布并且 前言 Android 官方架構(gòu)組件在今年 5 月份 Google I/O 大會上被公布, 直到 11 月份一直都是測試版, 由于工作比較繁忙, 期...

    DevTTL 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<