国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Fragment切換時,MVP中的P不能被重新創建

Reducto / 3530人閱讀

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

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

誰是V

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

Fragment的管理

登陸,注冊和修改密碼,一個三個Fragment,繼承自基類的IBaseFragment,并各自對應自己的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用于生成對應的P

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

public interface PresenterFactory

{ P create(); }

fragment的切換流程:

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

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

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

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

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

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

這里有個坑

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

監聽屏幕返回按鈕事件

public boolean onKeyDown(int keyCode, KeyEvent event)

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

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

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

   @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,不然回退到最后一個可能會出現空白頁面
    }

大致就這樣,簡單總結下.

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/67440.html

相關文章

  • 改造 Android 官方架構組件 ViewModel

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

    DevTTL 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<