Android MVP框架+RxJava+Retrofit+cecycleView,请求网络数据并加载

这些天经常用MVP框架来写工程,今天就给大家用MVP框架,RxJava+Retrofit请求网络数据,并recycleView加载,fresco图片加载。

首先加载所需要的权限:
// recycleView
compile 'com.android.support:mediarouter-v7:25.0.0'
compile 'com.android.support:appcompat-v7:25.0.0'
compile 'com.android.support:recyclerview-v7:25.0.0'
// reftorfit
compile 'com.android.support:design:23.4.0'
compile 'com.squareup.retrofit2:retrofit:2.0.1'
compile 'com.squareup.retrofit2:converter-gson:2.0.1'
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.1'
compile 'io.reactivex:rxandroid:1.1.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'
// fresco
compile 'com.facebook.fresco:fresco:0.11.0'

MVP框架,最主要的还是三个层,model层、view层、presenter层,

在View层里定义一个接口:Iview:里边就写一个方法,用来传递数据集合,主要在主函数中实现这个借口,重写里边的方法,用来给适配器中添加数据。

package view;

import java.util.List;

import bean.User;

/**
 * Created by 笔片 on 2017/11/7.
 */

public interface Iview {
    void GetUser(List<User.SongListBean> list);
}
同样,在model中定义一个接口Imodel:

package model;

import java.util.List;

import bean.User;

/**
 * Created by 笔片 on 2017/11/7.
 */

public interface Imodel {
    void GetJson(String url);
}


在请求网络数据之前,要先用RxJava来拼接接口的URL,新建一个Api.class,将请求的接口地址写到这个类里边,也比较省事,规范一点

Api.class:

package api;

/**
 * Created by 笔片 on 2017/11/7.
 */

public class Api {
    public static final String URL_HOME = "http://tingapi.ting.baidu.com/v1/restserver/";
}
,新建一个接口 ApiService :

package inter;

import bean.User;
import retrofit2.http.GET;
import rx.Observable;

/**
 * Created by 笔片 on 2017/11/7.
 */

public interface ApiService {
    @GET("ting?method=baidu.ting.billboard.billList&type=1&size=10&offset=0")
    Observable<User> getNoParams();
}
,在 定义一个类 ApiServices,来实现这个接口

package inter;

import bean.User;
import rx.Observable;

/**
 * Created by 笔片 on 2017/11/7.
 */

public class ApiServices implements ApiService {
    @Override
    public Observable<User> getNoParams() {
        return null;
    }
}


新建一个usermodel.class,并在这个类中实现Imodel方法。这个方法中主要用来请求网络数据,添加Retrofit的拦截器,这其中的 LoggingInterceptor 就是这个接口的拦截器,这个需要自己改一下,

package model;

import java.util.List;

import api.Api;
import bean.User;
import inter.ApiService;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import rx.Observable;
import rx.Observer;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

/**
 * 在usermodel 中请求网络数据,做耗时操作
 * Created by 笔片 on 2017/11/7.
 */

public class usermodel implements Imodel{

    public OnFinishLisenter lisenter;

    public void setLisenter(OnFinishLisenter lisenter) {
        this.lisenter = lisenter;
    }

    /**
     * 利用Retrofit请求网络数据,
     * 加载拦截器:得到一个OKHttpClick对象,利用建造者模式加载拦截器,并且在创建retrofit时,添加上OkHttpClick对象
     * @param list
     */


    LoggingInterceptor loggingInterceptor = new LoggingInterceptor();

    @Override
    public void GetJson(String url) {
        // 添加一个拦截器
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .addInterceptor(loggingInterceptor)
                .build();

        //  创建Retrofit
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(url)
                // 添加拦截器到Retrofit中
                .client(okHttpClient)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();
        // 通过动态代理得到网络接口对象
        ApiService apiservice = retrofit.create(ApiService.class);

        Observable<User> user = apiservice.getNoParams();
        user.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<User>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(User user) {
                        List<User.SongListBean> song_list = user.getSong_list();
                        lisenter.OnFinish(song_list);
                    }
                });
    }
}

通过usermodel请求下来的网络数据,由于M层和V层之间不能直接传递数据,所以,要将M层请求下来的数据 通过接口回调的方法传递到P层,所以接下来要定义一个接口

OnFinishLisenter:
package model;

import java.util.List;

import bean.User;

/**
 * Created by 笔片 on 2017/11/7.
 */

public interface OnFinishLisenter {
    void OnFinish(List<User.SongListBean> list);
}

接下来,就写中间层presenter,用来获取来自model层传过来的数据,并且发送给View层,

userPresenter.class:
package presenter;

import java.util.List;

import bean.User;
import model.OnFinishLisenter;
import model.usermodel;
import view.Iview;

/**
 * Created by 笔片 on 2017/11/7.
 */

public class userPresenter {
    Iview iview;
    usermodel usermodel;

    public userPresenter(final Iview iview) {
        this.iview = iview;
        this.usermodel = new usermodel();
        usermodel.setLisenter(new OnFinishLisenter() {
            @Override
            public void OnFinish(List<User.SongListBean> list) {
                iview.GetUser(list);
            }
        });
    }
    public void GetUrl(String url){
        usermodel.GetJson(url);
    }

}

由于要利用RecycleView来展示数据,来写适配器:
HomeAdapter.class:
package model;

import android.content.Context;
import android.net.Uri;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.bwie.test.mymvprxjavaretrofitrecycleview.R;
import com.facebook.drawee.view.SimpleDraweeView;

import java.util.List;

import bean.User;

/**
 * Created by 笔片 on 2017/11/7.
 */

public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.MyViewHolder>{
    List<User.SongListBean> mDatas;
    Context context;

    public HomeAdapter(List<User.SongListBean> mDatas, Context context) {
        this.mDatas = mDatas;
        this.context = context;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        MyViewHolder holder = new MyViewHolder(LayoutInflater.from(
                context).inflate(R.layout.list_item, parent, false));
        return holder;
    }


    @Override
    public int getItemCount() {
        return mDatas.size();
    }

    class MyViewHolder extends RecyclerView.ViewHolder {

        TextView tv;
        SimpleDraweeView img;

        public MyViewHolder(View view) {
            super(view);
            tv = (TextView) view.findViewById(R.id.tv);
            img = (SimpleDraweeView) view.findViewById(R.id.img);
        }
    }

    public interface OnItemClickLitener {
        void onItemClick(View view, int position);

        void onItemLongClick(View view, int position);
    }

    private OnItemClickLitener mOnItemClickLitener;

    public void setOnItemClickLitener(OnItemClickLitener mOnItemClickLitener) {
        this.mOnItemClickLitener = mOnItemClickLitener;
    }

    @Override
    public void onBindViewHolder(final MyViewHolder holder, final int position) {
        holder.tv.setText(mDatas.get(position).getTitle());
        String url = mDatas.get(position).getPic_small();
        Uri uri = Uri.parse(url);
        holder.img.setImageURI(uri);
//        if (url.equals("") || url == null) {
//            holder.img.setImageResource(R.mipmap.ic_launcher);
//        } else {
//            ImageLoader imgl = ImageLoader.getInstance();
//            imgl.displayImage(url, holder.img);
//        }

        // 如果设置了回调,则设置点击事件
        if (mOnItemClickLitener != null) {
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int pos = holder.getLayoutPosition();
                    mOnItemClickLitener.onItemClick(holder.itemView, pos);
                }
            });

            holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    int pos = holder.getLayoutPosition();
                    mOnItemClickLitener.onItemLongClick(holder.itemView, pos);
                    return false;
                }
            });
        }
    }
}

适配器中,加载图片的是用的fresco,要初始化,所以还是建了一个类,AppMy,用来初始化fresco
AppMy.class:

package app;

import android.app.Application;

import com.facebook.drawee.backends.pipeline.Fresco;

/**
 * Created by 笔片 on 2017/11/7.
 */

public class AppMy extends Application{
    @Override
    public void onCreate() {

        Fresco.initialize(this);
    }
}




MainActivity.class:
package com.bwie.test.mymvprxjavaretrofitrecycleview;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;

import java.util.List;

import api.Api;
import bean.User;
import model.HomeAdapter;
import presenter.userPresenter;
import view.Iview;

public class MainActivity extends AppCompatActivity implements Iview{

    userPresenter presenter;
    RecyclerView recyclerView;
    HomeAdapter adapter;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        presenter = new userPresenter(this);
        presenter.GetUrl(Api.URL_HOME);
        recyclerView = (RecyclerView) findViewById(R.id.revyvleview);


    }

    // 得到presenter传过来的数据,添加到输配器中
    @Override
    public void GetUser(List<User.SongListBean> list) {
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        adapter = new HomeAdapter(list,MainActivity.this);
        recyclerView.setAdapter(adapter);
    }
}

布局文件:
mainactivity.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.bwie.test.mymvprxjavaretrofitrecycleview.MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/revyvleview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></android.support.v7.widget.RecyclerView>
</RelativeLayout>

子布局:

list_item:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:fresco="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <com.facebook.drawee.view.SimpleDraweeView
        android:id="@+id/img"
        android:layout_width="130dp"
        android:layout_height="130dp"
        fresco:placeholderImage="@mipmap/ic_launcher" />

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="33333333333333333" />

</LinearLayout>

到这里就写完了,其中有不足的地方,还是要请多多指教。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值