【从 0 开始开发一款直播 APP】5.4 MVC 之 Fragment 交互实现滑动导航

阅读 498
收藏 33
2017-04-25
原文链接:www.cniao5.com
本文为菜鸟窝作者蒋志碧的连载。“从 0 开始开发一款直播 APP ”系列来聊聊时下最火的直播 APP,如何完整的实现一个类”腾讯直播”的商业化项目
视频地址:www.cniao5.com/course/1012…

【从 0 开始开发一款直播 APP】5.1 MVP 完全解析 — 实现直播登录
【从 0 开始开发一款直播 APP】5.2 MVP 之 Fragment 交互实现滑动导航
【从 0 开始开发一款直播 APP】5.3 MVC 完全解析 — 实现直播登录
【从 0 开始开发一款直播 APP】5.4 MVC 之 Fragment 交互实现滑动导航


上一章讲了 MVC 实现登录功能,这一章讲 MVC 实现主页面展示,前面已经实现了这个功能,现在结合 MVC 来讲解。

MVC 之 Fragment 交互实现滑动导航

Controller

1、MVCMainController 对应于 MVCMainActivity

1、定义 MVCIMainController 抽象类,主要方法是 initFragment() — 初始化 FragmentTabHost。

2、定义 MVCMainController 类继承 MVCIMainController 抽象类,实现 initFragment() 方法(FragmentTabHost 数据绑定)的逻辑。

2、MVCLiveMainController 对应于 MVCLivaMainFragment

MVCLiveMainController 与 MVCLiveMainView 关联,并添加初始化 ViewPager 实现导航的数据的方法 initViewPager(View rootView)。

View

1、MVCMainActivity

1、定义 MVCBaseView 接口,将通用方法封装到里面。

2、定义 MVCIMainView 抽象类,实现 MVCBaseView 接口。MVCIMainView 关联 MVCMainController,并绑定 FragmentTabHost 完成数据显示。

3、MVCMainActivity 继承 MVCIMainView 抽象类及其抽象方法,完成 MVCMainController 的实例化以及调用 initFragment() 完成显示 FragmentTabHost 的功能。

2、MVCLivaMainFragment

1、定义 MVCLiveMainView 抽象类继承 BaseFragment 抽象类,关联 MVCLiveMainController,绑定 ViewPager 完成 Tab 的切换。

2、MVCLivaMainFragment 继承 MVCLiveMainView,调用 MVCLiveMainView 中的方法最终完成导航显示。

Model

看到上面运行效果图中,数据就是图片以及标题,还有 Fragment 等,直接在 View 定义。

类图结合上面的文字说明帮助理解,下面开始创建 MVC 基本架构,下面是根据上面类图创建的相关包以及接口和类,红色矩形框中的是 MVCLiveMainFragment 以及 MVCMainActivity 展示数据要用到的类,下面一一进行讲解。

注意:本章讲解是基于前面的一篇文章进行讲解,不做过多的介绍。
具体细节查看:【从 0 开始开发一款直播 APP】2.2 高层封装之 Fragment — 滑动导航

MVCMainActivity 数据展示

Controller 所有类实现

1、MVCIMainController

Controller 基类,用于绑定 View 和 Model 的逻辑方法封装,initFragment() 用于初始化 FragmentTabHost,完成 底部导航封装方法初步定义。

public abstract class MVCIMainController {
    protected MVCBaseView mBaseView;
    protected BaseActivity mContext;

    public MVCIMainController(MVCBaseView baseView,BaseActivity context) {
        this.mBaseView = baseView;
        this.mContext = context;
    }

    //初始化 FragmentTabHost
    protected abstract void initFragment();
}

2、MVCMainController

MVCMainController 继承 MVCIMainController,实现其抽象方法,mIMainView.setModel() 方法在 MVCIMainView 类中有实现。结合 MVC 架构,C 层完成 V 层的绑定,以及 M 层数据传递的逻辑实现。

public class MVCMainController extends MVCIMainController{

    private MVCIMainView mIMainView;
    public MVCMainController(MVCIMainView mainView, BaseActivity context) {
        super(mainView,context);
        mIMainView = mainView;
    }

    @Override
    public void initFragment() {
        mIMainView.setModel();
    }
}

View 所有类实现

1、MVCBaseView

View 基类定义,封装可能用到的通用方法。

public interface MVCBaseView {

    /**
     * 数据加载或耗时加载时界面显示
     */
    void showLoading();

    /**
     * 数据加载或耗时加载完成时界面显示
     */
    void dismissLoading();

    /**
     * 消息提示,如 Toast,Dialog等
     */
    void showMsg(String msg);
    void showMsg(int msgId);

    /**
     * 获取Context
     * @return
     */
    Context getContext();
}

2、MVCIMainView

MVCIMainView 继承 BaseActivity,实现 MVCBaseView 接口。绑定 MVCMainController 以及 Model 数据展示的具体实现。这里是 FragmentTabHost 实现底部滑动的数据展示。

public abstract class MVCIMainView extends BaseActivity implements MVCBaseView {
    //Controller
    protected MVCMainController mMainController;
      //Model
    public FragmentTabHost mTabHost;
    protected final Class mFragmentArray[] = {MVCLivaMainFragment.class, PublishFragment.class, UserInfoFragment.class};
    protected int mImageViewArray[] = {R.drawable.tab_live_selector, R.drawable.tab_pubish_selector, R.drawable.tab_my_selector};
    protected String mTextViewArray[] = {"live", "publish", "mine"};

      //在 MVCMainController 方法中调用
    public void setModel(){
        mTabHost = obtainView(android.R.id.tabhost);
        mTabHost.setup(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,mImageViewArray));
            mTabHost.addTab(tabSpec, mFragmentArray[i], null);
            mTabHost.getTabWidget().setDividerDrawable(null);
        }
    }

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

3、MVCMainActivity

MVCMainActivity 继承 MVCIMainView,最终完成底部导航在界面上的显示。看到这里代码很少,只有 MVCMainController 的初始化以及调用 initFragment() 方法完成最终显示。

public class MVCMainActivity extends MVCIMainView{
    @Override
    protected void setActionBar() {
    }

    @Override
    protected void setListener() {
    }

    @Override
    protected void initData() {
    }

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

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


    @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;
    }
}

运行效果依然不变


上面的导航依然是基于 MVCLiveMainFragment

MVCLiveMainFragment 的数据展示

Controller 所有类实现

MVCLiveMainController

Controller 基类定义,绑定 MVCLiveMainView,mMainView.initViewPager(rootView);mMainView.initViewPagerData() 方法在 MVCLiveMainView 类中有实现。结合 MVC 架构,C 层完成 V 层的绑定,以及 M 层数据传递的逻辑实现。

public class MVCLiveMainController {

    private MVCLiveMainView mMainView;
      //初始化 ViewPager,完成上面导航的显示
    public void initViewPager(View rootView){
        mMainView.initViewPager(rootView);
        mMainView.initViewPagerData();
    }

    public MVCLiveMainController(MVCLiveMainView mainView) {
        this.mMainView = mainView;
    }
}

View 所有类实现

1、MVCLiveMainView

MVCLiveMainView 继承 BaseFragment,绑定 MVCLiveMainController,完成 ViewPager 顶部导航数据显示的具体实现,实例化 MVCLiveMainController。

public abstract class MVCLiveMainView extends BaseFragment {
    //Controller
    protected MVCLiveMainController mMainController;
    //Model
    private ViewPager mViewPager;
    private PagerSlidingTabStrip mTabStrip;
    private ArrayList<String> mTitles;
    private ArrayList<Fragment> mFragments;

    public MVCLiveMainView() {
        mMainController = new MVCLiveMainController(this);
    }

    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("英雄联盟");
        mTitles.add("王者荣耀");
        for (String s:mTitles){
            Bundle bundle = new Bundle();
            bundle.putString("title",s);
            mFragments.add(LiveListFragment.newInstance(bundle));
        }
        mViewPager.setAdapter(getAdapter());
        mTabStrip.setViewPager(mViewPager);
    }

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

2、MVCLivaMainFragment

MVCLivaMainFragment 继承 MVCLiveMainView,最终完成顶部导航的展示。

public class MVCLivaMainFragment extends MVCLiveMainView {

    @Override
    protected void initData() {
    }

    @Override
    protected void setListener() {
    }

    @Override
    protected void initView(View rootView) {
        mMainController.initViewPager(rootView);
    }

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

运行效果


针对 MVC 框架,要做到结构清晰,尽量多画图, 结合 MVC 架构中三者的关系根据具体需求调节实现类和方法。写的有问题的地方还请大家踊跃留言帮助笔者改正。

更多内容,请关注菜鸟窝(微信公众号ID: cniao5),程序猿的在线学习平台。 如需转载,请注明出处(菜鸟窝 , 原文链接: http://www.cniao5.com/forum/thread/ec3f7b44250111e78c6c00163e0230fa

关注公众号免费领取" N套客户端实战项目教程"

评论