RetrofitとRxjava/greendoを使ってリストを更新してロードすることを実現します.
91640 ワード
使用する依存と権限
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
implementation 'com.roughike:bottom-bar:1.3.3'
implementation 'com.jcodecraeer:xrecyclerview:1.3.2'
implementation 'com.android.support:design:27.1.1'
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation "io.reactivex.rxjava2:rxjava:2.1.13"// retrofit Rxjava
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0' // retrofit Gson
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
implementation 'com.google.dagger:dagger:2.8'
annotationProcessor 'com.google.dagger:dagger-compiler:2.7'
implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
implementation 'com.facebook.fresco:fresco:1.9.0'
implementation 'org.greenrobot:greendao:3.2.2' // add library
apply plugin: 'org.greenrobot.greendao' // apply plugin
android {}
build.gardleファイルにおける依存repositories {
google()
jcenter()
mavenCentral() // add repository
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.2'
classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // add plugin
activitymy_duan.zixml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MyDuanZiActivity">
<FrameLayout
android:id="@+id/fl"
android:layout_width="match_parent"
android:layout_height="match_parent" />
LinearLayout>
fragmentduanzixml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#FF1ABFD9">
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_centerVertical="true"
android:background="@drawable/user_icon"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_centerVertical="true"
android:textSize="18dp"
android:text=" "/>
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="@drawable/edit_icon"/>
RelativeLayout>
<com.jcodecraeer.xrecyclerview.XRecyclerView
android:id="@+id/xrl"
android:layout_width="match_parent"
android:layout_height="match_parent">
com.jcodecraeer.xrecyclerview.XRecyclerView>
LinearLayout>
xrv_ラyoutxml 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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/img"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_margin="3dp"
fresco:roundAsCircle="true" />
<LinearLayout
android:layout_width="100dp"
android:layout_height="match_parent"
android:layout_margin="3dp"
android:orientation="vertical">
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="123"
android:textColor="#f00"
android:textSize="16sp" />
<TextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="123"
android:textSize="16sp" />
LinearLayout>
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="150dp"
android:src="@drawable/add_icon" />
LinearLayout>
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/img_xia"
android:layout_width="match_parent"
android:layout_height="200dp" />
LinearLayout
MyDual ZiActivityimport android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.bwie.test.myduanzi.duanzi.DuanziFragment;
public class MyDuanZiActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_duan_zi);
//
getSupportActionBar().hide();
DuanziFragment duanziFragment = new DuanziFragment();
FragmentManager manager = getSupportFragmentManager();
manager.beginTransaction().replace(R.id.fl, duanziFragment).commit();
}
}
Dual zinFragmentimport android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.view.View;
import com.bwie.test.adapter.DuanziAdapter;
import com.bwie.test.app.MyApp;
import com.bwie.test.bean.MyDataBean;
import com.bwie.test.bean.MyDataBeanDao;
import com.bwie.test.component.DaggerHttpComponent;
import com.bwie.test.myduanzi.R;
import com.bwie.test.bean.DuanziBean;
import com.bwie.test.myduanzi.base.BaseFragment;
import com.bwie.test.myduanzi.duanzi.contract.DuanziContract;
import com.bwie.test.myduanzi.duanzi.presenter.DuanziPresenter;
import com.jcodecraeer.xrecyclerview.XRecyclerView;
import java.util.ArrayList;
import java.util.List;
public class DuanziFragment extends BaseFragment implements DuanziContract.View{
private XRecyclerView xlv;
private List list = new ArrayList<>();
private DuanziAdapter adapter;
private boolean isRefresh = true;
private int page = 1;
@Override
public int getContentLayout() {
return R.layout.fragment_duanzi;
}
@Override
public void initView(View view) {
xlv = view.findViewById(R.id.xrl);
xlv.setLayoutManager(new LinearLayoutManager(getContext()));
adapter = new DuanziAdapter(getContext(), list);
xlv.setAdapter(adapter);
//
MyDataBeanDao myDataBeanDao = MyApp.getDaoSession().getMyDataBeanDao();
List list = myDataBeanDao.queryBuilder().build().list();
if (list != null && list.size() > 0) {
//
} else {
mPresenter.getDuanzi(page + "");
}
//
xlv.setLoadingListener(new XRecyclerView.LoadingListener() {
@Override
public void onRefresh() {
//
page = 1;
isRefresh = true;
mPresenter.getDuanzi(page + "");
}
@Override
public void onLoadMore() {
//
page++;
isRefresh = false;
mPresenter.getDuanzi(page + "");
}
});
}
@Override
public void inject() {
DaggerHttpComponent.builder()
.build()
.inject(this);
}
@Override
public void onSuccess(List list) {
if (isRefresh) {
adapter.refresh(list);
xlv.refreshComplete();
} else {
adapter.loadMore(list);
int listNum = adapter.getListNum();
xlv.loadMoreComplete();
int size = list.size();
int count = listNum + size;
if (count >= 20) {
xlv.setLoadingMoreEnabled(false);
}
}
}
}
アプリフォルダ下のMyAppimport android.app.Application;
import com.bwie.test.bean.DaoMaster;
import com.bwie.test.bean.DaoSession;
import com.facebook.drawee.backends.pipeline.Fresco;
public class MyApp extends Application{
private static DaoSession daoSession;
@Override
public void onCreate() {
super.onCreate();
// fresco
Fresco.initialize(this);
DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(this, "baway.db");
DaoMaster daoMaster = new DaoMaster(devOpenHelper.getWritableDb());
daoSession = daoMaster.newSession();
}
public static DaoSession getDaoSession() {
return daoSession;
}
}
adapperフォルダ下のDual zinAdapterimport android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.bwie.test.bean.DuanziBean;
import com.bwie.test.myduanzi.R;
import com.facebook.drawee.view.SimpleDraweeView;
import java.util.List;
public class DuanziAdapter extends RecyclerView.Adapter {
private Context context;
private List list;
private LayoutInflater inflater;
public DuanziAdapter(Context context, List list) {
this.context = context;
this.list = list;
inflater = LayoutInflater.from(context);
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.xrv_layout, parent, false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
DuanziBean.DataBean dataBean = list.get(position);
MyViewHolder myViewHolder = (MyViewHolder) holder;
String imgUrls = (String) dataBean.getImgUrls();
String imgUrl = "";
if (!TextUtils.isEmpty(imgUrls)) {
imgUrl = imgUrls.split("\\|")[0];
}
myViewHolder.iv.setImageURI(imgUrl);
myViewHolder.tvName.setText(dataBean.getUser().getNickname() + "");
myViewHolder.tvTime.setText(dataBean.getCreateTime());
}
@Override
public int getItemCount() {
return list.size();
}
private class MyViewHolder extends RecyclerView.ViewHolder {
private final SimpleDraweeView iv;
private final TextView tvName;
private final TextView tvTime;
public MyViewHolder(View itemView) {
super(itemView);
iv = itemView.findViewById(R.id.img);
tvName = itemView.findViewById(R.id.tv_name);
tvTime = itemView.findViewById(R.id.tv_time);
}
}
public void refresh(List tempList) {
//
this.list.clear();
this.list.addAll(tempList);
notifyDataSetChanged();
}
public void loadMore(List tempList) {
this.list.addAll(tempList);
notifyDataSetChanged();
}
public int getListNum(){
return this.list.size();
}
}
インターフォルダ下でIBaseimport android.view.View;
public interface IBase {
int getContentLayout();
void initView(View view);
void inject();
}
componentフォルダ下のHttpComponentimport com.bwie.test.module.HttpModule;
import com.bwie.test.myduanzi.duanzi.DuanziFragment;
import dagger.Component;
@Component(modules = HttpModule.class)
public interface HttpComponent {
void inject(DuanziFragment duanziFragment);
}
moduleフォルダ下のHttpModuleimport com.bwie.test.utils.Api;
import com.bwie.test.utils.DuanziApi;
import com.bwie.test.utils.DuanziApiService;
import com.bwie.test.utils.MyInterceptor;
import java.util.concurrent.TimeUnit;
import dagger.Module;
import dagger.Provides;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
@Module
public class HttpModule {
@Provides
OkHttpClient.Builder provideOkHttpClientBuilder() {
return new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(20, TimeUnit.SECONDS)
.writeTimeout(20, TimeUnit.SECONDS);
}
@Provides
DuanziApi provideDuanApi(OkHttpClient.Builder builder) {
builder.addInterceptor(new MyInterceptor());
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Api.baseUrl)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.client(builder.build())
.build();
DuanziApiService duanziApiService = retrofit.create(DuanziApiService.class);
return DuanziApi.getDuanziApi(duanziApiService);
}
}
ベースフォルダ下でBaseContractpublic interface BaseContract {
interface BasePresenter<T extends BaseView> {
void attchView(T view);
void detachView();
}
interface BaseView {
void showLoading();
void dismissLoading();
}
}
BaseFragmentimport android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.bwie.test.inter.IBase;
import javax.inject.Inject;
public abstract class BaseFragment<T extends BaseContract.BasePresenter> extends Fragment
implements IBase, BaseContract.BaseView {
@Inject
protected T mPresenter;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
inject();
View view = inflater.inflate(getContentLayout(), null);
mPresenter.attchView(this);
initView(view);
return view;
}
@Override
public void onDestroy() {
super.onDestroy();
mPresenter.detachView();
}
@Override
public void showLoading() {
}
@Override
public void dismissLoading() {
}
}
BasePresenterpublic class BasePresenter<T extends BaseContract.BaseView> implements BaseContract.BasePresenter<T> {
protected T mView;
@Override
public void attchView(T view) {
if(view !=null){
this.mView = view;
}
}
@Override
public void detachView() {
if(mView !=null){
this.mView = null;
}
}
}
ファイル下のアウトラインimport com.bwie.test.bean.DuanziBean;
import com.bwie.test.myduanzi.base.BaseContract;
import java.util.List;
public interface DuanziContract {
interface View extends BaseContract.BaseView{
void onSuccess(List list);
}
interface Presenter extends BaseContract.BasePresenter {
void getDuanzi(String page);
}
}
presenterフォルダ下のDual zinPresenterimport android.annotation.SuppressLint;
import com.bwie.test.app.MyApp;
import com.bwie.test.bean.DaoSession;
import com.bwie.test.bean.DuanziBean;
import com.bwie.test.bean.MyDataBean;
import com.bwie.test.bean.MyDataBeanDao;
import com.bwie.test.myduanzi.base.BasePresenter;
import com.bwie.test.myduanzi.duanzi.contract.DuanziContract;
import com.bwie.test.utils.DuanziApi;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
public class DuanziPresenter extends BasePresenter implements
DuanziContract.Presenter {
private DuanziApi duanziApi;
@Inject
public DuanziPresenter(DuanziApi duanziApi) {
this.duanziApi = duanziApi;
}
@SuppressLint("CheckResult")
@Override
public void getDuanzi(String page) {
duanziApi.getDuanzi(page)
.subscribeOn(Schedulers.io())
.map(new Function>() {
@Override
public List apply(DuanziBean duanziBean) throws Exception {
return duanziBean.getData();
}
}).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer>() {
@Override
public void accept(List dataBeans) throws Exception {
DaoSession daoSession = MyApp.getDaoSession();
List list = new ArrayList<>();
MyDataBeanDao myDataBeanDao = daoSession.getMyDataBeanDao();
for (int i = 0; i < dataBeans.size(); i++) {
DuanziBean.DataBean dataBean = dataBeans.get(i);
MyDataBean myDataBean = new MyDataBean();
myDataBean.setAge(dataBean.getUser().getAge() + "");
myDataBean.setCommentNum(dataBean.getCommentNum() + "");
myDataBean.setContent(dataBean.getContent());
myDataBean.setCreateTime(dataBean.getCreateTime());
myDataBean.setFans(dataBean.getUser().getFans());
myDataBean.setFollow(dataBean.getUser().isFollow());
myDataBean.setIcon(dataBean.getUser().getIcon() + "");
myDataBean.setImgUrls((String)(dataBean.getImgUrls()));
list.add(myDataBean);
}
myDataBeanDao.insertInTx(list);
mView.onSuccess(dataBeans);
}
});
}
}
utilsフォルダ下のApppublic interface Api {
String baseUrl = "https://www.zhaoapi.cn/";
}
Dual nzippoimport com.bwie.test.bean.DuanziBean;
import io.reactivex.Observable;
public class DuanziApi {
private static DuanziApi duanziApi;
private DuanziApiService duanziApiService;
public DuanziApi(DuanziApiService duanziApiService) {
this.duanziApiService = duanziApiService;
}
public static DuanziApi getDuanziApi(DuanziApiService duanziApiService){
if (duanziApi == null){
duanziApi = new DuanziApi(duanziApiService);
}
return duanziApi;
}
public Observable getDuanzi(String page){
return duanziApiService.getDuanzi(page);
}
}
Dual nzippo Serviceimport com.bwie.test.bean.DuanziBean;
import io.reactivex.Observable;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.POST;
public interface DuanziApiService {
@FormUrlEncoded
@POST("quarter/getJokes")
Observable getDuanzi(@Field("page") String page);
}
MyInterceptorimport java.io.IOException;
import okhttp3.FormBody;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
public class MyInterceptor implements Interceptor{
@Override
public Response intercept(Chain chain) throws IOException {
FormBody.Builder builder = new FormBody.Builder();
Request originalRequest = chain.request();
FormBody formBody = (FormBody) originalRequest.body();
//
for (int i = 0; i"source","android");
builder.add("appVersion","100");
FormBody body = builder.build();
// Request
Request request = new Request.Builder()
.url(originalRequest.url())
.post(body)
.build();
Response response = chain.proceed(request);
return response;
}
}
beanフォルダの下でDual zaBenimport java.util.List;
public class DuanziBean {
private String msg;
private String code;
private List data;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public List getData() {
return data;
}
public void setData(List data) {
this.data = data;
}
public static class DataBean {
private Object commentNum;
private String content;
private String createTime;
private Object imgUrls;
private int jid;
private Object praiseNum;
private Object shareNum;
private int uid;
private UserBean user;
public Object getCommentNum() {
return commentNum;
}
public void setCommentNum(Object commentNum) {
this.commentNum = commentNum;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
public Object getImgUrls() {
return imgUrls;
}
public void setImgUrls(Object imgUrls) {
this.imgUrls = imgUrls;
}
public int getJid() {
return jid;
}
public void setJid(int jid) {
this.jid = jid;
}
public Object getPraiseNum() {
return praiseNum;
}
public void setPraiseNum(Object praiseNum) {
this.praiseNum = praiseNum;
}
public Object getShareNum() {
return shareNum;
}
public void setShareNum(Object shareNum) {
this.shareNum = shareNum;
}
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public UserBean getUser() {
return user;
}
public void setUser(UserBean user) {
this.user = user;
}
public static class UserBean {
private Object age;
private String fans;
private boolean follow;
private Object icon;
private Object nickname;
private String praiseNum;
public Object getAge() {
return age;
}
public void setAge(Object age) {
this.age = age;
}
public String getFans() {
return fans;
}
public void setFans(String fans) {
this.fans = fans;
}
public boolean isFollow() {
return follow;
}
public void setFollow(boolean follow) {
this.follow = follow;
}
public Object getIcon() {
return icon;
}
public void setIcon(Object icon) {
this.icon = icon;
}
public Object getNickname() {
return nickname;
}
public void setNickname(Object nickname) {
this.nickname = nickname;
}
public String getPraiseNum() {
return praiseNum;
}
public void setPraiseNum(String praiseNum) {
this.praiseNum = praiseNum;
}
}
}
}
MyDataBenimport org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Id;
import org.greenrobot.greendao.annotation.Property;
import org.greenrobot.greendao.annotation.Generated;
@Entity
public class MyDataBean {
@Id
private Long id;
@Property
private String commentNum;
@Property
private String content;
@Property
private String createTime;
@Property
private String imgUrls;
@Property
private int jid;
@Property
private String praiseNum;
@Property
private String shareNum;
@Property
private int uid;
@Property
private String age;
@Property
private String fans;
@Property
private boolean follow;
@Property
private String icon;
@Property
private String nickname;
@Generated(hash = 1891157934)
public MyDataBean(Long id, String commentNum, String content, String createTime,
String imgUrls, int jid, String praiseNum, String shareNum, int uid,
String age, String fans, boolean follow, String icon, String nickname) {
this.id = id;
this.commentNum = commentNum;
this.content = content;
this.createTime = createTime;
this.imgUrls = imgUrls;
this.jid = jid;
this.praiseNum = praiseNum;
this.shareNum = shareNum;
this.uid = uid;
this.age = age;
this.fans = fans;
this.follow = follow;
this.icon = icon;
this.nickname = nickname;
}
@Generated(hash = 650128772)
public MyDataBean() {
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getCommentNum() {
return this.commentNum;
}
public void setCommentNum(String commentNum) {
this.commentNum = commentNum;
}
public String getContent() {
return this.content;
}
public void setContent(String content) {
this.content = content;
}
public String getCreateTime() {
return this.createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
public String getImgUrls() {
return this.imgUrls;
}
public void setImgUrls(String imgUrls) {
this.imgUrls = imgUrls;
}
public int getJid() {
return this.jid;
}
public void setJid(int jid) {
this.jid = jid;
}
public String getPraiseNum() {
return this.praiseNum;
}
public void setPraiseNum(String praiseNum) {
this.praiseNum = praiseNum;
}
public String getShareNum() {
return this.shareNum;
}
public void setShareNum(String shareNum) {
this.shareNum = shareNum;
}
public int getUid() {
return this.uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public String getAge() {
return this.age;
}
public void setAge(String age) {
this.age = age;
}
public String getFans() {
return this.fans;
}
public void setFans(String fans) {
this.fans = fans;
}
public boolean getFollow() {
return this.follow;
}
public void setFollow(boolean follow) {
this.follow = follow;
}
public String getIcon() {
return this.icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
public String getNickname() {
return this.nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
}