使用的依赖和权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <!--<uses-permission android:name="android.permission.MOUNT_FORMAT_FILESYSTEMS"/>--> <uses-permission android:name="android.permission.INTERNET"/>
implementation rootProject.ext.dependencies["appcompat-v7"] implementation rootProject.ext.dependencies["constraint-layout"] implementation rootProject.ext.dependencies["retrofit2"] implementation rootProject.ext.dependencies["converter-gson"] implementation rootProject.ext.dependencies["rxjava2"] implementation rootProject.ext.dependencies["rxjava2:rxandroid"] implementation rootProject.ext.dependencies["dagger"] annotationProcessor rootProject.ext.dependencies["dagger-compiler"] implementation rootProject.ext.dependencies["adapter-rxjava"] implementation 'com.facebook.fresco:fresco:0.12.0' // 支持 GIF 动图,需要添加 implementation 'com.facebook.fresco:animated-gif:0.12.0' implementation 'com.sunfusheng:marqueeview:1.3.3' implementation 'com.android.support:support-v4:27.1.1' implementation 'com.jcodecraeer:xrecyclerview:1.3.2' implementation 'com.android.support:recyclerview-v7:27.1.1' implementation 'com.android.support:design:27.1.1'
build.gradle
apply from: "config.gradle" buildscript {}
config.gradle
ext { android = [ compileSdkVersion: 27, applicationId : "com.example.ruiyonghui.combwieruiyonghui0512", minSdkVersion : 15, targetSdkVersion : 27, versionCode : 1, versionName : "1.0" ] dependencies = [ "appcompat-v7" : "com.android.support:appcompat-v7:27.1.1", "constraint-layout": "com.android.support.constraint:constraint-layout:1.1.0", "retrofit2" : "com.squareup.retrofit2:retrofit:2.4.0", "converter-gson" : "com.squareup.retrofit2:converter-gson:2.4.0", "adapter-rxjava" : "com.squareup.retrofit2:adapter-rxjava2:2.4.0", "rxjava2" : "io.reactivex.rxjava2:rxjava:2.1.13", "rxjava2:rxandroid": "io.reactivex.rxjava2:rxandroid:2.0.2", "dagger" : "com.google.dagger:dagger:2.8", "dagger-compiler" : "com.google.dagger:dagger-compiler:2.7" ] }
activtiy_piece
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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=".PieceActivity"> <com.jcodecraeer.xrecyclerview.XRecyclerView android:id="@+id/recycler_duanzi" android:layout_width="match_parent" android:layout_height="match_parent"> </com.jcodecraeer.xrecyclerview.XRecyclerView> </RelativeLayout>
item_duanzi
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="15dp" xmlns:app="http://schemas.android.com/apk/res-auto"> <com.facebook.drawee.view.SimpleDraweeView android:id="@+id/sdv_yuan" android:layout_width="60dp" android:layout_height="60dp" android:layout_marginTop="15dp" app:actualImageScaleType="centerCrop" app:roundAsCircle="true"/> <TextView android:id="@+id/text_title" android:text="123" android:textColor="#ff0000" android:layout_marginTop="25dp" android:layout_toRightOf="@id/sdv_yuan" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/text_time" android:text="123" android:textColor="#3333" android:layout_toRightOf="@id/sdv_yuan" android:layout_below="@id/text_title" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/text_cont" android:layout_below="@id/sdv_yuan" android:layout_width="match_parent" android:maxLines="6" android:layout_marginTop="15dp" android:layout_marginBottom="15dp" android:layout_height="wrap_content" android:text="111"/> <TextView android:layout_below="@id/text_cont" android:layout_width="match_parent" android:layout_height="0.5dp" android:background="#3333"/> </RelativeLayout>
PieceActivity
import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.widget.Toast; import com.bwie.test.adapter.MyDuanZiAdapter; import com.bwie.test.base.BaseActivity; import com.bwie.test.bean.DuanZiBean; import com.bwie.test.component.DaggerHttpComponent; import com.bwie.test.module.HttpModule; import com.bwie.test.mypiece_demo.contract.DuanziContract; import com.bwie.test.mypiece_demo.presenter.DuanziPresenter; import com.jcodecraeer.xrecyclerview.ProgressStyle; import com.jcodecraeer.xrecyclerview.XRecyclerView; import java.util.ArrayList; import java.util.List; public class PieceActivity extends BaseActivity<DuanziPresenter> implements DuanziContract.View{ private int num = 1; private XRecyclerView mRecyclerDuanzi; boolean falg = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //隐藏原有标题 getSupportActionBar().hide(); initView(); mRecyclerDuanzi.setPullRefreshEnabled(true); mRecyclerDuanzi.setLoadingMoreEnabled(true); mRecyclerDuanzi.setRefreshProgressStyle(ProgressStyle.BallSpinFadeLoader); mRecyclerDuanzi.setLoadingMoreProgressStyle(ProgressStyle.Pacman); } @Override public void getJokesSuccess(DuanZiBean duanZiBean) { final List<DuanZiBean.DataBean> duanZiBeans = new ArrayList<>(); List<DuanZiBean.DataBean> data = duanZiBean.getData(); duanZiBeans.addAll(data); mRecyclerDuanzi.setLayoutManager(new LinearLayoutManager(PieceActivity.this, LinearLayoutManager.VERTICAL,false)); MyDuanZiAdapter adapter = new MyDuanZiAdapter(PieceActivity.this,duanZiBeans); mRecyclerDuanzi.setAdapter(adapter); mRecyclerDuanzi.setLoadingListener(new XRecyclerView.LoadingListener() { @Override public void onRefresh() { mPresenter.getJokes(num+""); mRecyclerDuanzi.refreshComplete(); duanZiBeans.clear(); Toast.makeText(PieceActivity.this, "刷新成功", Toast.LENGTH_SHORT).show(); } @Override public void onLoadMore() { num++; mPresenter.getJokes(num+""); mRecyclerDuanzi.refreshComplete(); Toast.makeText(PieceActivity.this, "加载成功", Toast.LENGTH_SHORT).show(); } }); } @Override public int getContentLayout() { return R.layout.activity_piece; } @Override public void inject() { DaggerHttpComponent.builder() .httpModule(new HttpModule()) .build() .inject(this); } private void initView() { mRecyclerDuanzi = (XRecyclerView) findViewById(R.id.recycler_duanzi); //请求数据 initData(); } private void initData() { mPresenter.getJokes(String.valueOf(101)); } }
app文件夹下MyApp
import android.app.Application; import com.facebook.drawee.backends.pipeline.Fresco; public class MyApp extends Application { @Override public void onCreate() { super.onCreate(); //初始化Fresco Fresco.initialize(this); } }
contract文件夹下DuanziContract
import com.bwie.test.base.BaseContract; import com.bwie.test.bean.DuanZiBean; public class DuanziContract { public interface View extends BaseContract.BaseView { void getJokesSuccess(DuanZiBean duanZiBean); } public interface Presenter extends BaseContract.BasePresenter<View> { void getJokes(String page); } }
presenter文件夹下DuanziPresenter
import com.bwie.test.base.BasePresenter; import com.bwie.test.bean.DuanZiBean; import com.bwie.test.mypiece_demo.contract.DuanziContract; import com.bwie.test.utils.JokesApi; import javax.inject.Inject; import io.reactivex.Observer; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.Disposable; import io.reactivex.schedulers.Schedulers; public class DuanziPresenter extends BasePresenter<DuanziContract.View> implements DuanziContract.Presenter{ JokesApi jokesApi; @Inject public DuanziPresenter(JokesApi jokesApi) { this.jokesApi = jokesApi; } @Override public void getJokes(String page) { jokesApi.getJokes(page) .observeOn(AndroidSchedulers.mainThread()) .subscribeOn(Schedulers.io()) .subscribe(new Observer<DuanZiBean>() { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(DuanZiBean duanZiBean) { mView.getJokesSuccess(duanZiBean); } @Override public void onError(Throwable e) { } @Override public void onComplete() { } }); } }
adapter文件夹下MyDuanZiAdapter
import android.content.Context; 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.bean.DuanZiBean; import com.bwie.test.mypiece_demo.R; import com.facebook.drawee.view.SimpleDraweeView; import java.util.List; public class MyDuanZiAdapter extends RecyclerView.Adapter<MyDuanZiAdapter.MyDuanZiHolder> { private final Context context; private final List<DuanZiBean.DataBean> duanZiBeans; public MyDuanZiAdapter(Context context, List<DuanZiBean.DataBean> duanZiBeans) { this.context = context; this.duanZiBeans = duanZiBeans; } @Override public MyDuanZiHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(context).inflate(R.layout.item_duanzi, parent, false); MyDuanZiHolder holder = new MyDuanZiHolder(view); return holder; } @Override public void onBindViewHolder(MyDuanZiHolder holder, int position) { DuanZiBean.DataBean bean = duanZiBeans.get(position); holder.sdv_yuan.setImageURI(bean.getUser().getIcon()); holder.text_title.setText(bean.getUser().getNickname()); holder.text_time.setText(bean.getCreateTime()); holder.text_cont.setText(bean.getContent()); } @Override public int getItemCount() { return duanZiBeans.size(); } class MyDuanZiHolder extends RecyclerView.ViewHolder { public SimpleDraweeView sdv_yuan; public TextView text_title; public TextView text_time; public TextView text_cont; public MyDuanZiHolder(View itemView) { super(itemView); sdv_yuan = itemView.findViewById(R.id.sdv_yuan); text_title = itemView.findViewById(R.id.text_title); text_time = itemView.findViewById(R.id.text_time); text_cont = itemView.findViewById(R.id.text_cont); } } }
base文件夹下BaseActivity
import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import com.bwie.test.inter.IBase; import com.bwie.test.mypiece_demo.R; import javax.inject.Inject; public abstract class BaseActivity<T extends BaseContract.BasePresenter> extends AppCompatActivity implements IBase, BaseContract.BaseView{ @Inject protected T mPresenter; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(getContentLayout()); inject(); //绑定 mPresenter.attchView(this); } @Override public void showLoading() { } @Override public void dismissLoading() { } @Override protected void onDestroy() { super.onDestroy(); //解绑 mPresenter.detachView(); } }
BaseContract
public interface BaseContract { //抽取所有Presenter共性,比如绑定,解绑 interface BasePresenter<T extends BaseView> { void attchView(T view); void detachView(); } //抽取所有View的共性,比如显示进度条和关闭进度 interface BaseView { void showLoading(); void dismissLoading(); } }
BasePresenter
public class BasePresenter<T extends BaseContract.BaseView> implements BaseContract.BasePresenter<T> { protected T mView; @Override public void attchView(T view) { this.mView = view; } @Override public void detachView() { if (mView != null) { mView = null; } } }
component文件夹下HttpComponent
import com.bwie.test.module.HttpModule; import com.bwie.test.mypiece_demo.PieceActivity; import dagger.Component; @Component(modules = HttpModule.class) public interface HttpComponent { void inject(PieceActivity pieceActivity); }
inter文件夹下IBase
public interface IBase { int getContentLayout(); void inject(); }
module文件夹下HttpModule
import com.bwie.test.utils.JokesApi; import com.bwie.test.utils.JokesService; 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 JokesApi provideJokesApi(OkHttpClient.Builder builder) { builder.addInterceptor(new MyInterceptor()); JokesService jokesService = new Retrofit.Builder() .baseUrl("https://www.zhaoapi.cn/") .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .client(builder.build()) .build() .create(JokesService.class); return JokesApi.getJokesApi(jokesService); } }
utils文件夹下Api
public interface Api { String DUANZI_URL = "https://www.zhaoapi.cn/"; }
JokesApi
import com.bwie.test.bean.DuanZiBean; import io.reactivex.Observable; import retrofit2.http.Field; import retrofit2.http.FormUrlEncoded; import retrofit2.http.POST; public class JokesApi { private static JokesApi jokesApi; private JokesService jokesService; private JokesApi(JokesService jokesService) { this.jokesService = jokesService; } public static JokesApi getJokesApi(JokesService jokesService) { if (jokesApi == null) { jokesApi = new JokesApi(jokesService); } return jokesApi; } public Observable<DuanZiBean> getJokes(String page) { return jokesService.DuanZi(page); } }
JokesService
import com.bwie.test.bean.DuanZiBean; import io.reactivex.Observable; import retrofit2.http.Field; import retrofit2.http.FormUrlEncoded; import retrofit2.http.POST; public interface JokesService { @FormUrlEncoded @POST("quarter/getJokes") Observable<DuanZiBean> DuanZi(@Field("page") String page); }
MyInterceptor
import java.io.IOException; import okhttp3.FormBody; import okhttp3.HttpUrl; import okhttp3.Interceptor; import okhttp3.Request; import okhttp3.Response; public class MyInterceptor implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { Response response; //区分是GET请求还是POST请求 Request originRequest = chain.request(); if ("GET".equals(originRequest.method())) { HttpUrl httpUrl = originRequest.url() .newBuilder() .addQueryParameter("source", "android") .addQueryParameter("appVersion","101") .build(); Request request = new Request.Builder().url(httpUrl).build(); //发送请求 response = chain.proceed(request); } else { FormBody.Builder builder = new FormBody.Builder(); FormBody body = (FormBody) originRequest.body(); int size = body.size(); for (int i = 0; i < size; i++) { builder.add(body.name(i), body.value(i)); } builder.add("source", "android"); builder.add("appVersion","101"); FormBody formBody = builder.build(); Request request = new Request.Builder() .url(originRequest.url()) .post(formBody) .build(); response = chain.proceed(request); } return response; } }
bean文件夹下DuanZiBean
import java.util.List; public class DuanZiBean { private String msg; private String code; private List<DataBean> 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<DataBean> getData() { return data; } public void setData(List<DataBean> data) { this.data = data; } public static class DataBean { private Object commentNum; private String content; private String createTime; private String 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 String getImgUrls() { return imgUrls; } public void setImgUrls(String 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 String icon; private String 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 String getIcon() { return icon; } public void setIcon(String icon) { this.icon = icon; } public String getNickname() { return nickname; } public void setNickname(String nickname) { this.nickname = nickname; } public String getPraiseNum() { return praiseNum; } public void setPraiseNum(String praiseNum) { this.praiseNum = praiseNum; } } } }