Create a project framework with MVP

Source: Internet
Author: User

Objective
在目前的项目框架中大多是用Viewpager+Fragment实现,而通常情况下一个Fragment中包含以下功能,但是如果将这些功能全部集成在一个fragment中会造成,逻辑不清楚,而且我们编写的时候本身也不容易理清顺序,比如在刷新界面的时候要分多种情况,如果是加载第一页且没有缓存数据的时候显示进度动画,否则显示listview自带的下拉刷新动画,当发生错误的时候也要根据有无显示的内容做相应的判断,如果有内容则显示Toast提示用户,否则切换到重试页面。如果将这些逻辑处理与fragment捆绑的话,如果需要更换banner控件,或则下拉刷新控件,则这些逻辑不能复用。所以我尝试使用MVP的方式实现项目框架。

Function
先看一下我目前实现的功能有哪些。
1. Drop-down refresh, pull-up load more

2. Lazy loading, loading animations, data caching

3. Error message (There is data here, unable to display the retry interface, but if there is no data, there is a retry interface)

4. Next retry, (because there is already a page of data, so the retry interface cannot be displayed, otherwise the user's data will be overwritten, a footerview is added here to retry)

Implementation 1. Why Choose MVP

MVP (Mode view presenter) and traditional MVC (Mode view controller) pay more attention to the independence of the view, in MVC more attention to model independence, that is, the model is constant and there are multiple view corresponding to the same mode, This is the view dependent mode, and the inevitable meaning of view in the logical processing of the part, this will be based on the view of the reuse of the decline in the system's coupling, and in the MVP mode and view are independent. While the main logic is in the presenter, and in the presenter is also the model and view interface, so that the mode and view of the re-usability, the flexibility of the system increased.

My project structure is as follows

2. Interface Extraction

The most critical here is the view interface of the extraction, have seen a lot of people mvpdemo but wait until their own writing but do not know how to do, I summed up the view interface extraction is mainly three points

    1. Data that needs to be fetched from view
    2. The status that needs to be displayed for the view
    3. What you need to do with view

Ilistview excuses

 PackageCom.zgh.mvpdemo.view.news;ImportAndroid.content.DialogInterface;ImportCom.zgh.mvpdemo.bean.BannerItem;ImportCom.zgh.mvpdemo.bean.NewsItem;ImportJava.util.List;/** * Created by Zhuguohui on 2016/6/29. * * Public  interface ilistview {    /******* Loading Home related *******/    //Display loading effect of load page    voidShowloadingfirstpage ();//Hide load Home animation    voidHideloadingfirstpage ();//home page failed to load when the call    voidShowretryfirstpage ();//The home is empty when called    voidShowempty ();//Get to the home page when the data is called    voidShowfirstpagedata (list<newsitem> listData);/*********** loading next page related *************/    //Show load next page    voidShowloadingnextpage ();//Hide load Next page    voidHideloadingnextpage ();//Gets to the next page of data is called    voidShownextpagedata (list<newsitem> listData);//Display and next page    voidShowhavenextpage ();//Show retry loading next page    voidShowretrynextpage ();//No more.    voidShownomore ();/**************banner related *********************/    //Hide banner when no banner data is being called    voidHidebanner ();//Display banner Data    voidShowbanner (list<banneritem> bannerdata);/***************** Get Data ***************************/    //Determine if there is another page    BooleanHavenextpage (intDataSize);//Whether there is already a display of content, used to determine whether to display the retry interface when there is no network, if there is content to display content, otherwise display retry.     BooleanHavecontent ();//Get the URL address of the homepageString Getfirstpageurl ();//Next page URL addressString Getnextpageurl ();/************** Click event ****************************/Interface Onbannerclicklistener {voidOnbannnerclick (Banneritem item); } interface Onnewsitemclicklistener {voidOnnewsitemclick (NewsItem item); }voidSetonbanneritemclicklistener (Onbannerclicklistener listener);voidSetonlistitemclicklistener (Onnewsitemclicklistener listener);voidToitemdetail (NewsItem item);voidTobannerdetail (Banneritem item);/**************** Notice *******************************/    voidShowtoast (String info);}

Ilistmode interface

package com.zgh.mvpdemo.model.news;/** * Created by zhuguohui on 2016/6/29. */publicinterface IListMode {    /**     *      * @param useCache 是否使用缓存     * @param url 数据url     * @param listener 回调接口     */    void LoadData(boolean useCache,String url,DataResultListener listener);}

There's no extraction interface for presenter.

 PackageCom.zgh.mvpdemo.presenter.news;ImportCom.zgh.mvpdemo.bean.BannerItem;ImportCom.zgh.mvpdemo.bean.NewsItem;ImportCom.zgh.mvpdemo.model.news.DataResultListener;ImportCom.zgh.mvpdemo.model.news.IListMode;ImportCom.zgh.mvpdemo.model.news.ListMode;ImportCom.zgh.mvpdemo.view.news.IListView;ImportJava.util.List;/** * Created by Zhuguohui on 2016/6/29. * * Public  class listpresenter implements Ilistview. Onbannerclicklistener, ilistview. Onnewsitemclicklistener {Ilistview ListView; Ilistmode Listmode; Public Listpresenter(Ilistview ListView) { This. ListView = ListView; Listmode =NewListmode ();//Set Click eventsListview.setonbanneritemclicklistener ( This); Listview.setonlistitemclicklistener ( This); } Public void Loadfirstpage(BooleanUseCache) {The progress bar is displayed when there is no content and does not need to be refreshed at the drop-down        if(!listview.havecontent ())        {listview.showloadingfirstpage (); } listmode.loaddata (Usecache,listview.getfirstpageurl (),NewDataresultlistener () {@Override             Public void onsuccess(list<newsitem> newsdata, list<banneritem> bannerdata) {listview.hideloadingfirstpage ();//If the banner data is not empty to show banner, otherwise hidden                if(Bannerdata! =NULL&& bannerdata.size () >0) {Listview.showbanner (bannerdata); }Else{Listview.hidebanner (); }The display style is set according to whether the list has data or not                if(Newsdata! =NULL&& newsdata.size () >0) {Listview.showfirstpagedata (newsdata);//Determine if there is a next page based on the number of item                    if(Listview.havenextpage (Newsdata.size ()))                    {listview.showhavenextpage (); }Else{Listview.shownomore (); }                }Else{Listview.showempty (); }            }@Override             Public void OnError(String error) {listview.hideloadingfirstpage ();//Show retry when no content is present, or only prompt, or show original cached content                if(!listview.havecontent ())                {listview.showretryfirstpage ();            } listview.showtoast (Error);    }        }); } Public void Loadnextpage() {//Show load next pageListview.showloadingnextpage (); Listmode.loaddata (false, Listview.getnextpageurl (),NewDataresultlistener () {@Override             Public void onsuccess(list<newsitem> newsdata, list<banneritem> bannerdata) {//Do not need to judge Banner's data when loading the next page                if(Newsdata! =NULL&& newsdata.size () >0) {Listview.shownextpagedata (newsdata);//If there is no next page, show no more                    if(!listview.havenextpage (Newsdata.size ()))                    {Listview.shownomore (); }Else{listview.showhavenextpage (); }                }Else{Listview.showtoast ("no more.");                Listview.shownomore ();            } listview.hideloadingfirstpage (); }@Override             Public void OnError(String error) {listview.hideloadingnextpage ();//Show retry when no content is present, or only prompt, or show original cached content                if(!listview.havecontent ())                {listview.showretryfirstpage (); }Else{listview.showretrynextpage ();            } listview.showtoast (Error);    }        }); }@Override     Public void Onbannnerclick(Banneritem Item)    {Listview.tobannerdetail (item); }@Override     Public void Onnewsitemclick(NewsItem Item)    {Listview.toitemdetail (item); }}
3. State switching

State switching I'm using Zhang Hongyang's loadingandretrymanager. Let's go and see for yourself. It is necessary to note that Loadingandretrymanager is used in fragment in Viewpager to return loadingandretrylayout as a fragment view. And the first Mbaseview is the view you created yourself.

 Mloadingandretrymanager = new  Loadingandretrymanager ( Mbaseview, new  Onloadingandretrylistener () {@O Verride  public  void  setretryevent  (View retryview) {Retryview.findviewbyid (r.id.id_btn_retry). Setonclicklistene R (new  View.onclicklistener () { @Overrid E  public  void  onclick  (View v) {mpresenter.loadfirstpage (true  ); } }); } }); Mbaseview = mloadingandretrymanager.mloadingandretrylayout; 
4.Fragment and Viewpager precautions for use 1. Lazy Loading

Since Viewpager will cache several pages of fragment in advance, the life cycle of fragment does not really make much sense in Viewpager, so in order for the user to swipe to this interface to display the data of this interface, We have to load the data in the Setuservisiblehint, just like this.

    @Override    publicvoidsetUserVisibleHint(boolean isVisibleToUser) {        super.setUserVisibleHint(isVisibleToUser);        if (isVisibleToUser && !haveInint) {            true;            mPresenter.LoadFirstPage(true);        }    }
View's cache

During the sliding of Viewpager, a Fragment Oncreateview () method and the Ondestroyview () method are called multiple times, that is, the view is destroyed first and the member variables in the fragment are preserved. When the memory is low, the fragment is destroyed again. Because view creation is also a time-consuming operation, I choose to cache the view, and to prevent the view from being empty every time the data request is returned, I put the view's creation in the OnCreate () method and create the view to request the data first.

   @Override     Public void onCreate(@Nullable Bundle savedinstancestate) {Super. OnCreate (Savedinstancestate);        CreateView ();        Binddata ();        Setlistener (); Mpresenter =NewListpresenter ( This);    Mloadingandretrymanager.showloading (); }@Nullable    @Override     PublicViewOncreateview(Layoutinflater inflater, ViewGroup container, Bundle savedinstancestate) {Viewparent parent = mbaseview.getparent ();if(Parent! =NULL&& ParentinstanceofViewGroup) {ViewGroup group = (viewgroup) parent;        Group.removeview (Mbaseview); }returnMbaseview; }
5.ListView Footerview and Heardview display and hide

I think this technique is quite useful, so I wrote it specifically. Most of the time we add the view to the ListView as Footview or Heardview and call View.setvisibility (View.gone) when we want to hide it, but the result is that view does not show, But it occupies a space that is similar to the call View.setvisibility (view.invisible) effect, Later I found that it was possible to hide the Footerview effect by wrapping it with a layer of layout before adding Footview or Headview, and the code was as follows:

Add Footerview Tv_bottom_info = (TextView) View. Inflate(Getactivity (), R. Layout. View_bottom_retry, NULL);Tv_bottom_info. Setlayoutparams(New ViewGroup. Layoutparams(ViewGroup. Layoutparams. MATCH_parent, Densityutil. Dip2PX (Getactivity (), $)));To Footerview a hidden effect, you must wrap it outside the layer Layout,heardview the same linearlayout footerviewparent = new LinearLayout (getactivity ());Footerviewparent. AddView(Tv_bottom_info);Tv_bottom_info. Setvisibility(View. GONE);Mlistview. Addfooterview(footerviewparent);
Demo

For more details please see my demo, Welcome to star Ha.

Mvpdemo

Create a project framework with MVP

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.