Android MVP,OkHttp,ImageLoader/Glide,接口回调,RecyclerView,属性动画,自定义View/ViewGroup,Sqlite

本文介绍了如何使用Android MVP架构、OkHttp、Glide等技术实现一个三色梯页面和新闻列表页面。内容涵盖自定义ViewGroup、接口回调、RecyclerView、属性动画以及SQLite缓存。详细阐述了各个功能点的实现,包括网络请求、数据存储、UI交互及动画效果。
摘要由CSDN通过智能技术生成
 

(一)    业务需求描述

1.     完成如下三色梯页面效果

1)自定义ViewGroup的方式完成如图一三色梯页面效果,第一条红色,第二条绿色,第三条蓝色,依次循环,台阶上显示第几条台阶数,每台阶梯子占控件宽度的1/3,垂直方向依次向下添加

2)为自定义三色梯提供添加和删除的方法,条目提供长按和点击事件

3)当点击标题栏右上方的添加按钮时,新的台阶添加到三色梯的下方,并显示添加的条数

4)长按三色梯的条目,可以删除选中条目

5)当点击添加的时候,使用属性动画,将内容平移到三色梯的条目上

6)点击条目时,将当前条目序号传到新闻列表页面

2.     完成图三所示新闻列表页面

1)使用OkHttp做网络请求,使用单例模式封装OkHttp,包括Get请求和Post请求,添加日志拦截器,自定义回调接口并回调到主线程

2)使用MVP框架搭建,分包明确,V层和M层解耦,通过接口完成V层和P层以及P层和M层通信,解决内存泄漏问题

3)使用xRecyClerView做列表展示页面,并实现下拉刷新,上拉加载更多的功能,使用ListView类的控件不得分

4)根据条目数据中的序号来实现多条目加载,每两条显示3张图片,第三条显示1张图片,依次排列,一张图片时显示在条目左侧,两条或三条时显示在条目下方,图片水平排列

5)自行选择图片加载框架完成图片加载

6)使用SQLite对新闻条目进行缓存,进入页面时,先从数据库进行读取数据展示,当有网时,从网络加载数据并更新列表数据,没有网络时,弹出吐司提示。

7)长按条目,弹出确认删除对话框,点击确认按钮时移除所选条目,添加默认的删除动画,并局部刷新

8)当确认删除后,将缓存到数据库的条目状态标记为已删除,下次从数据库读取数据时,被标记为已删除的条目不再进行展示,并且从网络请求数据时,如果加载的数据已经被删除过,则不展示该已经删除过的数据

(二)    效果图

    

(三)    技术选型

1.     MVP;

2.     OKHttp;

3.     ImageLoader/Glide等

4.     接口回调;

5.     RecyclerView

6.     属性动画

7.     自定义View/ViewGroup

8.     Sqlite

(四)    路分解

1.     通过文字或流程图等分析需求,形成完整解决问题思路;

2.     提供文档或流程图,一起拷贝到u盘;

(五)    接口

http://ttpc.dftoutiao.com/jsonpc/refresh?type=5010

其中,type5010+梯子序号,比如点击的第一个台阶,则type=5011,第二个台阶,则type=5012,依次类推,当下拉刷新时,type为刚开始的值,当上拉加载更多时,type值加1

(六)    第三方依赖

OkHttp

implementation 'com.squareup.okhttp3:okhttp:3.10.0'

OkHttp日志拦截器:

implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0'

xRecyclerView

compile 'com.jcodecraeer:xrecyclerview:1.5.9'

Glide

implementation'com.github.bumptech.glide:glide:4.7.1'

annotationProcessor'com.github.bumptech.glide:compiler:4.7.1'

ImageLoader

素材中提供Jar


NewsAdapter

 

package com.example.kson.monthdemo.adapter;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.provider.ContactsContract;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.example.kson.monthdemo.MainActivity;
import com.example.kson.monthdemo.R;
import com.example.kson.monthdemo.bean.News;
import com.example.kson.monthdemo.common.Constants;
import com.google.gson.Gson;
import com.jcodecraeer.xrecyclerview.XRecyclerView;

import java.util.List;

/**
 * Author:kson
 * E-mail:19655910@qq.com
 * Time:2018/05/29
 * Description:
 */
public class NewsAdapter extends XRecyclerView.Adapter<XRecyclerView.ViewHolder> {

    private List<News.Data> list;
    private Context context;
    //private  News news;

    public NewsAdapter(List<News.Data> list, Context context) {
        this.list = list;
        this.context = context;
        //this.news = news;
    }



    public void loadMore(List<News.Data> data) {
        if (list != null) {
            list.addAll(data);
            notifyDataSetChanged();
        }
    }


    @NonNull
    @Override
    public XRecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if (viewType == Constants.TYPE1) {
            View view = LayoutInflater.from(context).inflate(R.layout.news_item2_layout, parent, false);

            return new Type1ViewHolder(view);
        } else {
            View view2 = LayoutInflater.from(context).inflate(R.layout.news_item_layout, parent, false);

            return new Type2ViewHolder(view2);
        }


    }

    @Override
    public void onBindViewHolder(@NonNull final XRecyclerView.ViewHolder holder, int position) {

        holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {

                AlertDialog.Builder builder = new AlertDialog.Builder(context);
                builder.setTitle("删除");
                builder.setNegativeButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        int pos = holder.getLayoutPosition()-1;//得到下标
                        System.out.println("pos----"+pos);
                        list.remove(pos);//删除集合的数据
                        /*news.data = list;

                       String json =  new Gson().toJson(news);*/

                        notifyItemRemoved(pos);//局部删除当前view并局部刷新
                    }
                });
                builder.setNeutralButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {

                    }
                });
                builder.show();


                return true;
            }
        });

        News.Data data = list.get(position);
        if (holder instanceof Type1ViewHolder) {
 //1张图片


            ((Type1ViewHolder) holder).title.setText(data.topic);



        } else if (holder instanceof Type2ViewHolder) {
 //三张图片
            ((Type2ViewHolder) holder).title.setText(data.topic);
            if (data.miniimg != null && data.miniimg.size() > 0) {
                if (data.miniimg.size() == 1) {
                    Glide.with(context).load(data.miniimg.get(0).src).into(((Type2ViewHolder) holder).iv1);
                    Glide.with(context).load(data.miniimg.get(0).src).into(((Type2ViewHolder) holder).iv2);
                    Glide.with(context).load(data.miniimg.get(0).src).into(((Type2ViewHolder) holder).iv3);
                } else if (data.miniimg.size() == 2) {
                    Glide.with(context).load(data.miniimg.get(0).src).into(((Type2ViewHolder) holder).iv1);
                    Glide.with(context).load(data.miniimg.get(1).src).into(((Type2ViewHolder) holder).iv2);
                    Glide.with(context).load(data.miniimg.get(1).src).into(((Type2ViewHolder) holder).iv3);
                } else {
                    Glide.with(context).load(data.miniimg.get(0).src).into(((Type2ViewHolder) holder).iv1);
                    Glide.with(context).load(data.miniimg.get(1).src).into(((Type2ViewHolder) holder).iv2);
                    Glide.with(context).load(data.miniimg.get(2).src).into(((Type2ViewHolder) holder).iv3);
                }
            }
        }
    }

    @Override
    public int getItemViewType(int position) {
        return position % 2 == 0 ? Constants.TYPE1 : Constants.TYPE2;
    }


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

    class Type1ViewHolder extends XRecyclerView.ViewHolder {

        private TextView title;

        public Type1ViewHolder(View itemView) {
            super(itemView);
            title = itemView.findViewById(R.id.title1);
        }
    }

    class Type2ViewHolder extends XRecyclerView.ViewHolder {

        private TextView title;
        private ImageView iv1, iv2, iv3;

        public Type2ViewHolder(View itemView) {
            super(itemView);
            iv1 = itemView.findViewById(R.id.img1);
            iv2 = itemView.findViewById(R.id.img2);
            iv3 = itemView.findViewById(R.id.img3);
            title = itemView.findViewById(R.id.title3);
        }
    }
}
LocalNews

package com.example.kson.monthdemo.bean;

/**
 * Author:kson
 * E-mail:19655910@qq.com
 * Time:2018/05/30
 * Description:
 */
public class LocalNews {
    public String title;
    public String imgurls;
    public String source;
    public String time;
    public boolean isDel;
}

 News

package com.example.kson.monthdemo.bean;

import java.util.List;

/**
 * Author:kson
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值