服务报价 | 域名主机 | 网络营销 | 软件工具| [加入收藏]
 热线电话: #

基于android MVP的Rss阅读器

时间:2016-09-20 11:41来源:未知 作者:最模板 点击:
最近在学习Android的MVP模式,就是MVP(Model-View-Presenter),网上大部分都是比较小的例子,所以想拿个小项目练手,于是采用了基于Rss feed的阅读器。 1.Rss feeds是什么? 是一种根据XML特性所

最近在学习Android的MVP模式,就是MVP(Model-View-Presenter),网上大部分都是比较小的例子,所以想拿个小项目练手,于是采用了基于Rss feed的阅读器。

  • 1.Rss feeds是什么?

    是一种根据XML特性所制定的格式,将网页内容抽取出来,读者订阅RSS Feed,即可直接取得有兴趣的资讯。简单来说就是一种xml。

  • 2.MVP是什么?

    解决的问题: 不让activity承接太多任务 ;使得Model和View层解耦,职责划分明显。结构清晰。(感觉说了跟白说一样)

    • 1.Model 提供数据
    • 2.View 负责显示
    • 3.Presenter 逻辑的处理,作为Model和view的中间者,从Model获得数据然后控制view显示.
  • 3.整个结构:

Paste_Image.png

具体效果:

Paste_Image.png

  • 4.怎么获取Rss feeds数据?

    我在这里使用的是volley + 自定义的xmlRequest,在文章底部有附源码,主要写大概获取和使用方式:

    首先自定义一个接口:

    public interface RssLoadListener {   
      void onLoadSuccess(List<RssInfo> rssInfoList);//获取成功
      void onLoadFailed();//获取失败
      void onNetWorkFailed();//网络错误
      void onBeginLoad();//开始任务
    }

    让RssLoad下载任务时候实现这个接口并作为参数传进去, 有了这个接口,我们在哪里需要下载数据的时候就可以这么应用:

    new RssLoadModel(context,RSS_URL).excute(new RssLoadListener() {
    
              @Override
              public void onBeginLoad() {
                  view.showLoading();//刚开始下载的操作
              }
    
              @Override
              public void onLoadSuccess(List<RssInfo> rssInfoList) {
                  //下载成功后要做什么
                  Log.d(TAG, "onLoadSuccess: ");
                  view.hideLoading();
                  view.showResult(rssInfoList);
              }
    
              @Override
              public void onLoadFailed() {
                  //若失败后的操作
                  view.hideLoading();
                  view.showError("更新失败");
              }
    
              @Override
              public void onNetWorkFailed() {
                  view.showError("网络不可用");
                  view.hideLoading();
              }
          });

    RssLoadModel是一个负责下载的类,里面的excute方法负责下载,并在下载过程中调用loadListener的方法,比如下载成功就调用onLoadSuccess(),至于里面成功后应该怎么做,就由你来实现,这样就达到了将状态和结果传递出去的目的。

    public void excute(final RssLoadListener loadListener){
          if(!NetworkUtils.isNetworkAvailable(context)){
              loadListener.onNetWorkFailed();//网络失败
              return;
          }
          loadListener.onBeginLoad();
          XMLRequest xmlRequest = new XMLRequest(Constants.RSS_URL,
                  new Response.Listener<XmlPullParser>() {
                      @Override
                      public void onResponse(XmlPullParser response) {
                          parserXML(response);
                          loadListener.onLoadSuccess(rssInfos);
                          //调用下载成功,将结果传递出去
                      }
                  }, new Response.ErrorListener() {
              @Override
              public void onErrorResponse(VolleyError error) {
                  Log.e("TAG", error.getMessage(), error);
                  loadListener.onLoadFailed();//失败
              }
          });
          mQueue.add(xmlRequest);
      }

    XMLRequest 是继承volley.Request的自定义类,volley是一个方便Android应用网络操作框架,默认没有XML的request,(宝宝不开心):

    public class XMLRequest extends Request<XmlPullParser> {
    
      private final Response.Listener<XmlPullParser> mListener;
    
      public XMLRequest(int method, String url, Response.Listener<XmlPullParser> listener,
                        Response.ErrorListener errorListener) {
          super(method, url, errorListener);
          mListener = listener;
      }
    
      public XMLRequest(String url, Response.Listener<XmlPullParser> listener, Response.ErrorListener errorListener) {
          this(Method.GET, url, listener, errorListener);
      }
    
      @Override
      public Map<String, String> getHeaders() throws AuthFailureError {
          //需要加,否则获取不到数据
          HashMap<String, String> headers = new HashMap<String, String>();
          headers.put("Content-Type", "application/xml; charset=utf-8");
          return headers;
      }
      @Override
      protected Response<XmlPullParser> parseNetworkResponse(NetworkResponse response) {
          try {
              String xmlString = new String(response.data,
                      HttpHeaderParser.parseCharset(response.headers));
              Log.d("tag",xmlString);
              XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
              XmlPullParser xmlPullParser = factory.newPullParser();
              xmlPullParser.setInput(new StringReader(xmlString));
              return Response.success(xmlPullParser, HttpHeaderParser.parseCacheHeaders(response));
          } catch (UnsupportedEncodingException e) {
              return Response.error(new ParseError(e));
          } catch (XmlPullParserException e) {
              return Response.error(new ParseError(e));
          }
      }
    
      @Override
      protected void deliverResponse(XmlPullParser response) {
          mListener.onResponse(response);
      }
    }
  • 5.mvp

    VIew

    • MvpView类是个接口
      public interface MvpView {}
    • RssView 继承MvpView接口,具体的View类需要实现下面的方法,那么presenter想要控制具体的View类操作,就可以直接调用showLoading()等方法,这也是针对抽象编程。

      public interface RssView extends MvpView {
      /**
       * 显示loading下载视图
       */
      void showLoading();
      
      /**
       *隐藏loading下载视图
       */
      void hideLoading();
      
      /**
       * 显示错误信息
       * @param msg
       */
      void showError(String msg);
      
      /**
       * 显示结果
       * @param rssInfos
       */
      void showResult(List<RssInfo> rssInfos);
      
      /**
       * @param title
       */
      void showTitle(String title);
      }
    • 具体的view类,这里使用Activity作为view类,现在很多都将fragment作为view,将activity控制生命周期。

      public class MainActivity extends BaseActivty implements RssView

      需要实现下列方法,实现这么多方法给谁调用呢?当然是Presenter了。

      @Override
      public void showLoading() {//显示下载
          progressWheel.setVisibility(View.VISIBLE);
          swipeRefreshLayout.setVisibility(View.GONE);
          ValueAnimator progressFadeInAnim = ObjectAnimator.ofFloat(progressWheel, "alpha", 0, 1, 1);
          progressFadeInAnim.start();
      }
      
      @Override
      public void hideLoading() {//隐藏下载
          progressWheel.setVisibility(View.GONE);
          swipeRefreshLayout.setVisibility(View.VISIBLE);
          swipeRefreshLayout.setRefreshing(false); // close refresh animator
          ValueAnimator progressFadeInAnim = ObjectAnimator.ofFloat(progressWheel, "alpha", 1, 0, 0);
          progressFadeInAnim.start();
      }
      
      @Override
      public void showError(String msg) {//显示错误信息
          new SweetAlertDialog(this, SweetAlertDialog.ERROR_TYPE)
                  .setTitleText("Oops...")
                  .setContentText(msg)
                  .show();
      }
      
      @Override
      public void showResult(List<RssInfo> rssInfos) {//显示结果
          rssAdapter.setRssInfos(rssInfos);
      }
      
      @Override
      public void showTitle(String title) {//显示标题
          ((TextView)findViewById(R.id.toolbar_title)).setText(title);
      }

    Presenter

    MvpPresenter 接口,里面有两个方法attachView和detachView,负责将MvpView 绑定在MvpPresenter和解除绑定;例如在view类里面调用

    presenter.attachView(this);

    将自己传进去,这样 presenter就拥有了view,也就可以随心所欲地控制view了,Presenter通过接口进行对View的操作。

    public interface MvpPresenter<V extends MvpView> {
      /**
       * 将 MvpView 绑定在MvpPresenter
       * @param view
       */
      public void attachView(V view);
    
      /**
       * @param retainInstance
       * 解除绑定
       */
      public void detachView(boolean retainInstance);
    }

    RssPresenter类

    /**
    * Created by cheng on 16-7-24.
    */
    public class RssPresenter implements MvpPresenter<RssView> {
      private final static String TAG = "RssPresenter";
    
      private RssView view;
      private Context context;
    
      public RssPresenter(Context context) {
          this.context = context;
      }
    
      public void startLoadTask() {//开始下载
          if (view == null) {
              Log.w(TAG, "please attach view first.");
              return;
          }
    
          new RssLoadModel(context,RSS_URL).excute(new RssLoadListener() {
              @Override
              public void onBeginLoad() {
                  view.showLoading();
              }
    
              @Override
              public void onLoadSuccess(List<RssInfo> rssInfoList) {
                  Log.d(TAG, "onLoadSuccess: ");
                  view.hideLoading();
                  view.showResult(rssInfoList);
              }
    
              @Override
              public void onLoadFailed() {
                  view.hideLoading();
                  view.showError("更新失败");
              }
    
              @Override
              public void onNetWorkFailed() {
                  view.showError("网络不可用");
                  view.hideLoading();
              }
          });
      }
    
      @Override
      public void attachView(RssView view) {
          this.view = view;
      }
    
      @Override
      public void detachView(boolean retainInstance) {
          // TODO
    
      }
    }
  • 6.以上只是一部分源码,具体的源码:


(责任编辑:最模板)
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
栏目列表
热点内容