1、导入依赖
//RecycleView
implementation 'com.android.support:recyclerview-v7:28.0.0'
//XRecycleView:
configurations.all {
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
def requested = details.requested
if (requested.group == 'com.android.support') {
if (!requested.name.startsWith("multidex")) {
details.useVersion '28.0.0'
}
}
}
}
implementation 'com.jcodecraeer:xrecyclerview:1.5.9'
2、OKHttp封装的工具类
public class OkHttp {
private OkHttpClient okHttpClient;
public OkHttp() {
//日志拦截器
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
okHttpClient = new OkHttpClient.Builder()
.connectTimeout(20,TimeUnit.MINUTES)
.readTimeout(20,TimeUnit.MINUTES)
.callTimeout(20,TimeUnit.MINUTES)
.addInterceptor(interceptor) //添加日志拦截器
.build();
}
public static OkHttp getInstance(){
return OkHolder.OkHttp;
}
static class OkHolder{
private static final OkHttp OkHttp = new OkHttp();
}
//异步GET
public void getAsync(String url, Callback callback){
Request request = new Request.Builder().url(url).build();
okHttpClient.newCall(request).enqueue(callback);
}
//异步POST
public void postAsync(String url, Callback callback){
RequestBody body = new FormBody.Builder().add("key", "value").build();
Request request = new Request.Builder().url(url).post(body).build();
okHttpClient.newCall(request).enqueue(callback);
}
//上传图片 必须是POST
public void upLoadImage(String url, String uid, Callback callback) {
File file = new File(Environment.getExternalStorageDirectory() + "/Pictures/test.jpg");
//上传图片需要 MultipartBody
MultipartBody.Builder body = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("uid", uid)
.addFormDataPart("file", "test.jpg", RequestBody.create(MediaType.parse("image/jpg"), file));
RequestBody body1 = body.build();
Request request = new Request.Builder().url(url).post(body1).build();
okHttpClient.newCall(request).enqueue(callback);
}
}
3、封装MVP
CallBack:接口回调
public interface MyCallBack<T> {
void setSuccess(T successData);
void setError(T errorData);
}
Model层://获取数据
IModel:
public interface IModel {
void getData(String url, MyCallBack myCallBack);
}
MyModel:
public class MyModel<T> implements IModel {
@SuppressLint("HandlerLeak")
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
String s = (String) msg.obj;
Gson gson = new Gson();
News news = gson.fromJson(s, News.class);
myCallBack.setSuccess(news);
}
};
private MyCallBack myCallBack;
@Override
public void getData(String url, MyCallBack myCallBack) {
this.myCallBack = myCallBack;
OkHttp.getInstance().getAsync(url, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String s = response.body().string();
handler.sendMessage(handler.obtainMessage(0,s));
}
});
}
}
View层:刷新数据
IView:
public interface IView<T> {
void success(T success);
void error(T error);
}
Presenter层:请求数据,管理M和V之间的交互
IPresenter:
public interface IPresenter {
void startRequest(String url);
}
MyPresenter:
public class MyPresenter implements IPresenter {
private MyModel myModel;
private IView iView;
public MyPresenter(IView iView) {
this.iView = iView;
myModel = new MyModel();
}
@Override
public void startRequest(String url) {
myModel.getData(url, new MyCallBack() {
@Override
public void setSuccess(Object successData) {
iView.success(successData);
}
@Override
public void setError(Object errorData) {
iView.error(errorData);
}
});
}
}
4、适配器
多布局Recycleview继承RecyclerView.Adapter<RecyclerView.ViewHolder>
public class MyAdapter2 extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements View.OnClickListener {
private final int ITEM1=1;
private final int ITEM2=2;
private Context context;
private List<NewsBean.DataBean> list;
public MyAdapter2(Context context, List<NewsBean.DataBean> list) {
this.context = context;
this.list = list;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = null;
RecyclerView.ViewHolder holder = null;
switch (i){
case ITEM1:
view = LayoutInflater.from(context).inflate(R.layout.item_one,viewGroup,false);
holder = new Holder1(view);
break;
case ITEM2:
view = LayoutInflater.from(context).inflate(R.layout.item_two,viewGroup,false);
holder = new Holder2(view);
break;
}
view.setOnClickListener(this);
return holder;
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
NewsBean.DataBean dataBean = list.get(i);
if(viewHolder instanceof Holder1){
Glide.with(context).load(list.get(i).getPic_url()).into(((Holder1) viewHolder).iv);
//((Holder1) viewHolder).iv.setImageURI(Uri.parse(list.get(i).getPic_url()));
}else{
((Holder2) viewHolder).tv.setText(list.get(i).getNews_title());
}
}
@Override
public int getItemCount() {
return list.size();
}
@Override
public int getItemViewType(int position) {
if(position%2==0){
return ITEM1;
}else {
return ITEM2;
}
}
class Holder1 extends RecyclerView.ViewHolder{
private ImageView iv;
public Holder1(@NonNull View itemView) {
super(itemView);
iv = itemView.findViewById(R.id.iv);
}
}
class Holder2 extends RecyclerView.ViewHolder{
private TextView tv;
public Holder2(@NonNull View itemView) {
super(itemView);
tv = itemView.findViewById(R.id.tv);
}
}
}
单布局extends RecyclerView.Adapter<MyAdapter.ViewHolder>
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private List<News.DataBean> list;
private Context context;
public MyAdapter(List<News.DataBean> list, Context context) {
this.list = list;
this.context = context;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(context).inflate(R.layout.item,null,false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {
News.DataBean dataBean = list.get(i);
//瀑布流:在加载布局时把参数2改成viewGroup
ViewGroup.LayoutParams params = viewHolder.itemView.getLayoutParams();
Random random = new Random();
int height = random.nextInt(300)+300;
params.height = height;
viewHolder.itemView.setLayoutParams(params);
/**如果图片字符串有 s 或者 \\| 可以截取或替换
* String images = dataBean.getThumbnail_pic_s();
* String[] splits = images.split("\\|");
* for(int j=0;j<split.length;j++){
* Glide.with(context).load(replace).into(viewHolder.img);
* }
**/
Glide.with(context).load(dataBean.getThumbnail_pic_s()).into(viewHolder.img);
viewHolder.title.setText(dataBean.getTitle());
}
@Override
public int getItemCount() {
return list.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private ImageView img;
private TextView title;
public ViewHolder(@NonNull View itemView) {
super(itemView);
img = itemView.findViewById(R.id.img);
title = itemView.findViewById(R.id.title);
}
}
//条目点击事件 使用接口回调的方法
//1.定义一个接口
public interface CallBack{
void setOnItemClick(View view,int position);
}
//2.声明一个接口变量
private CallBack callBack;
//3.写一个设置监听
public void setOnClick(CallBack callBack){
this.callBack = callBack;
}
@Override
public void onClick(View v) {
if(callBack!=null){
callBack.setOnItemClick(v, (int) v.getTag());
}
}
}
5、MainActivity
public class MainActivity<T> extends AppCompatActivity implements IView<T> {
private String url = "http://www.xieast.com/api/news/news.php?page=";
private RecyclerView recy;
private List<News.DataBean> list = new ArrayList<>();
private MyAdapter adapter;
private MyPresenter myPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
adapter = new MyAdapter(list,MainActivity.this);
recy.setAdapter(adapter);
myPresenter = new MyPresenter(this);
myPresenter.startRequest(url);
}
private void initView() {
recy = findViewById(R.id.recy);
//LinearLayoutManager manager=new LinearLayoutManager(MainActivity.this);
//GridLayoutManager manager = new GridLayoutManager(this,3);
StaggeredGridLayoutManager manager = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);
recy.setLayoutManager(manager);
}
//IView
@Override
public void success(T success) {
News news = (News) success;
list.addAll(news.getData());
adapter.notifyDataSetChanged();
}
@Override
public void error(T error) {
}
}