最清晰的MVP架構(gòu)實現(xiàn)了最流暢的直播頁面交互滑動

本文為菜鳥窩作者蔣志碧的連載辑鲤。“從 0 開始開發(fā)一款直播 APP ”系列來聊聊時下最火的直播 APP灭美,如何完整的實現(xiàn)一個類"騰訊直播"的商業(yè)化項目
視頻地址:http://www.cniao5.com/course/10121

【從 0 開始開發(fā)一款直播 APP】5.1 MVP 完全解析 -- 實現(xiàn)直播登錄
【從 0 開始開發(fā)一款直播 APP】5.2 MVP 之 Fragment 交互實現(xiàn)滑動導(dǎo)航
【從 0 開始開發(fā)一款直播 APP】5.3 MVC 完全解析 -- 實現(xiàn)直播登錄
【從 0 開始開發(fā)一款直播 APP】5.4 MVC 之 Fragment 交互實現(xiàn)滑動導(dǎo)航


上一章講了 MVP 實現(xiàn)登錄功能屈张,這一章講 MVP 實現(xiàn)主頁面展示,前面已經(jīng)實現(xiàn)了這個功能诉植,現(xiàn)在結(jié)合 MVP 來講解祥国。

MVP 之 Fragment 交互實現(xiàn)滑動導(dǎo)航

Presenter

一、MainPresenter 對應(yīng)于 MainActivity

1晾腔、定義 BasePresenter 接口舌稀,主要方法是 start() — presenter 開始處理數(shù)據(jù),綁定 Presenter 灼擂。 finish() — 處理銷毀工作壁查,界面結(jié)束時調(diào)用,取消綁定 Presenter 的方法剔应。

2睡腿、定義 IMainPresenter 抽象類實現(xiàn) BasePresenter 接口,定義登錄所需邏輯處理方法峻贮,與 IMainView 關(guān)聯(lián)嫉到。

3、定義 MainPresenter 繼承 IMainPresenter 抽象類月洛,實現(xiàn)抽象方法以及處理邏輯何恶。

二、LiveMainPresenter 對應(yīng)于 LiveMainFragment

LiveMainPresenter 與 LiveMainFragment 關(guān)聯(lián)

View

一嚼黔、MainActivity

1细层、定義 BaseView 接口,將通用方法封裝到里面唬涧。

2疫赎、定義 IMainView 接口,繼承BaseView

3碎节、MainActivity 實現(xiàn) IMainView 及其抽象方法

二捧搞、LiveMainFragment

LiveMainFragment 與 MainActivity 關(guān)聯(lián),LiveMainFragment 主要在 MainActivity 中顯示 FragmentTabHost 數(shù)據(jù)狮荔。

Model

看到上面運行效果圖中胎撇,數(shù)據(jù)就是圖片以及標題,還有 Fragment 等殖氏,直接在 Presenter 定義晚树。

看完類圖,下面開始創(chuàng)建 MVP 基本架構(gòu)雅采,下面是根據(jù)上面類圖創(chuàng)建的相關(guān)包以及接口和類爵憎,紅色矩形框中的是LiveMainFragment 以及 MainActivity 展示數(shù)據(jù)要用到的類慨亲,下面一一進行講解。

注意:本章講解是基于前面的一篇文章進行講解宝鼓,不做過多的介紹刑棵。
具體細節(jié)查看:【從 0 開始開發(fā)一款直播 APP】2.2 高層封裝之 Fragment -- 滑動導(dǎo)航

MainActivity 的數(shù)據(jù)展示

Presenter 所有類實現(xiàn)

1、MainPresenter

public abstract class IMainPresenter implements BasePresenter{

    protected BaseView mBaseView;
    protected BaseActivity mContext;

    public IMainPresenter(BaseView baseView,BaseActivity context) {
        this.mBaseView = baseView;
        this.mContext = context;
    }

    //初始化 FragmentTabHost
    protected abstract void initFragment();
    //展示 Tab 選項卡
    protected abstract View getTabItemView(int i);
}

2愚铡、IMainPresenter

BasePresenter 和登錄中的功能一樣铐望,請查看前面一節(jié)內(nèi)容,MainPresenter 與 Model 關(guān)聯(lián)茂附,這里的 Model 是 FragmentTabHost 實現(xiàn)的底部導(dǎo)航正蛙。

public class MainPresenter extends IMainPresenter {

    private IMainView mIMainView;
    private FragmentTabHost mTabHost;
    private final Class mFragmentArray[] = {LiveMainFragment.class, PublishFragment.class, UserInfoFragment.class};
    private int mImageViewArray[] = {R.drawable.tab_live_selector, R.drawable.tab_pubish_selector, R.drawable.tab_my_selector};
    private String mTextViewArray[] = {"live", "publish", "mine"};

    public MainPresenter(IMainView mainView, BaseActivity context) {
        super(mainView,context);
        mIMainView = mainView;
    }

    @Override
    public void start() {
    }

    @Override
    public void finish() {
        if (mIMainView!=null){
            mIMainView = null;
        }
    }


    @Override
    public void initFragment() {
        mTabHost = mContext.obtainView(android.R.id.tabhost);
        mTabHost.setup(mContext, mContext.getSupportFragmentManager(), R.id.contentPanel);
        int fragmentCount = mFragmentArray.length;
        for (int i = 0; i < fragmentCount; i++) {
            TabHost.TabSpec tabSpec = mTabHost.newTabSpec(mTextViewArray[i]).setIndicator(getTabItemView(i));
            mTabHost.addTab(tabSpec, mFragmentArray[i], null);
            mTabHost.getTabWidget().setDividerDrawable(null);
        }
    }

    @Override
    protected View getTabItemView(int i) {
        View view;
        view = LayoutInflater.from(mContext).inflate(R.layout.tab_live, null);
        ImageView imageView = (ImageView) view.findViewById(R.id.tab_icon);
        imageView.setImageResource(mImageViewArray[i]);
        return view;
    }

    @Override
    protected void checkCacheAndLogin() {
    }
}

View 的所有類實現(xiàn)

1、IMainView

目前還沒有其它新增方法营曼,后續(xù)慢慢添加

public interface IMainView extends BaseView {
}

2乒验、MainActivity

MainActivity 與 MainPresenter 關(guān)聯(lián),與原來的代碼相比蒂阱,避免了與 Model 直接交互锻全。

public class MainActivity extends BaseActivity implements IMainView {
    private MainPresenter mMainPresenter;

    @Override
    protected void setActionBar() {
    }

    @Override
    protected void setListener() {
    }

    @Override
    protected void initData() {
    }

    @Override
    protected void initView() {
        mMainPresenter = new MainPresenter(this,this);
        mMainPresenter.initFragment();
    }

    @Override
    protected int getLayoutId() {
        return R.layout.activity_main;
    }

    @Override
    public void showLoading() {
    }

    @Override
    public void dismissLoading() {
    }

    @Override
    public void showMsg(String msg) {
    }

    @Override
    public void showMsg(int msgId) {
    }

    @Override
    public Context getContext() {
        return this;
    }

}

運行效果大概是這樣。

上面的導(dǎo)航依然是基于 LiveMainFragment

LiveMainFragment 的數(shù)據(jù)展示

LiveMainPresenter

LiveMainPresenter 對應(yīng)的 View 是 LiveMainFragment录煤,LiveMainPresenter 與 Model 關(guān)聯(lián)鳄厌,避免 Model 直接與 View 交互

public class LiveMainPresenter {
    private BaseActivity mContext;
    //數(shù)據(jù)展示
    private ViewPager mViewPager;
    private PagerSlidingTabStrip mTabStrip;
    private ArrayList<String> mTitles;
    private ArrayList<Fragment> mFragments;

    public LiveMainPresenter(BaseActivity context) {
        this.mContext = context;
    }

    public FragmentStatePagerAdapter getAdapter() {
        return new PagerAdapter(mContext.getSupportFragmentManager(),mTitles,mFragments);
    }

    public void initViewPager(View rootView){
        mViewPager = (ViewPager) rootView.findViewById(R.id.viewpager);
        mTabStrip = (PagerSlidingTabStrip) rootView.findViewById(R.id.pager_sliding_tab_strip);
        mTabStrip.setTextColorResource(R.color.white);
        mTabStrip.setIndicatorColorResource(R.color.white);
        mTabStrip.setDividerColor(Color.TRANSPARENT);
        mTabStrip.setTextSize(rootView.getResources().getDimensionPixelSize(R.dimen.h6));
        mTabStrip.setUnderlineHeight(1);
        mViewPager.setCurrentItem(0);
    }

    public void initViewPagerData(){
        mTitles = new ArrayList<>();
        mFragments = new ArrayList<>();
        mTitles.add("最新");
        mTitles.add("最熱");
        mTitles.add("達人");
        mTitles.add("活力");
        mTitles.add("英雄聯(lián)盟");
        mTitles.add("王者榮耀");
        for (String s:mTitles){
            Bundle bundle = new Bundle();
            bundle.putString("title",s);
            mFragments.add(LiveListFragment.newInstance(bundle));
        }
    }

    public void initAdapter(FragmentStatePagerAdapter adapter){
        mViewPager.setAdapter(adapter);
        mTabStrip.setViewPager(mViewPager);
    }
}

View — LiveMainFragment

LiveMainFragment 與 LiveMainPresenter 關(guān)聯(lián),調(diào)用其方法更新數(shù)據(jù)展示在界面上

public class LiveMainFragment extends BaseFragment implements View.OnClickListener {

    private LiveMainPresenter mLiveMainPresenter;

    @Override
    protected void initData() {
    }

    @Override
    protected void setListener() {
        obtainView(R.id.iv_search).setOnClickListener(this);
        obtainView(R.id.iv_message).setOnClickListener(this);
    }

    @Override
    protected void initView(View rootView) {
        mLiveMainPresenter = new LiveMainPresenter(mContext);
        mLiveMainPresenter.initViewPager(rootView);
        mLiveMainPresenter.initViewPagerData();
    }

    @Override
    protected int getLayoutId() {
        return R.layout.fragment_live_main;
    }

    @Override
    public void onClick(View v) {
    }
}

運行效果



使用 MVP 架構(gòu)對于大型項目的開發(fā)結(jié)構(gòu)清晰妈踊,只要搞懂三者的關(guān)系了嚎,畫出大致類圖,就可以很輕松寫出代碼了廊营。


(菜鳥窩歪泳,程序員的黃埔軍校,轉(zhuǎn)載請注明出處)

添加菜鳥窩運營微信:yrioyou露筒,備注【菜鳥直播】呐伞,入群交流

微信圖片_20170803172638.jpg

關(guān)注菜鳥窩官網(wǎng),免費領(lǐng)取140套開源項目

菜鳥窩官網(wǎng)公號二維碼.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末慎式,一起剝皮案震驚了整個濱河市伶氢,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瘪吏,老刑警劉巖癣防,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異肪虎,居然都是意外死亡劣砍,警方通過查閱死者的電腦和手機惧蛹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門扇救,熙熙樓的掌柜王于貴愁眉苦臉地迎上來刑枝,“玉大人,你說我怎么就攤上這事迅腔∽俺” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵沧烈,是天一觀的道長掠兄。 經(jīng)常有香客問我,道長锌雀,這世上最難降的妖魔是什么蚂夕? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮腋逆,結(jié)果婚禮上婿牍,老公的妹妹穿的比我還像新娘。我一直安慰自己惩歉,他們只是感情好等脂,可當我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著撑蚌,像睡著了一般上遥。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上争涌,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天粉楚,我揣著相機與錄音,去河邊找鬼亮垫。 笑死解幼,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的包警。 我是一名探鬼主播撵摆,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼害晦!你這毒婦竟也來了特铝?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤壹瘟,失蹤者是張志新(化名)和其女友劉穎鲫剿,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體稻轨,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡灵莲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了殴俱。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片政冻。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡枚抵,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出明场,到底是詐尸還是另有隱情汽摹,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布苦锨,位于F島的核電站逼泣,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏舟舒。R本人自食惡果不足惜拉庶,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望秃励。 院中可真熱鬧砍的,春花似錦、人聲如沸莺治。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谣旁。三九已至床佳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間榄审,已是汗流浹背砌们。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留搁进,地道東北人浪感。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像饼问,于是被迫代替她去往敵國和親影兽。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內(nèi)容