Android开源项目LifeUtil 之数据展示

来源:互联网 发布:关于程序员的搞笑图片 编辑:程序博客网 时间:2024/05/28 04:55

在上一篇文章中,我们已经实现了从网络获取(抓爬)数据。得到数据之后,我们首先要做的肯定就是让它以优美的形式展示出来啦。这就是我们本节要讲的内容!!!数据展示

废话不多说,先上图

  • 列表图:
    这里写图片描述

  • 详情图:
    这里写图片描述

下面,就来说说怎么实现这个”美妙的UI界面“(好丑),
首先,先看看这样一个效果用到了什么技术。可以从图片上得知,这是一个可以左右切换的列表。这里使用了viewpager + TabLayout +fragment实现,即先将不同分类的Fragment加载到viewpager,再使用TabLayout实现指示条效果。简单的实现了这样一个可切换的效果。

内容展示项,这里使用了一个RecyclerView + CardView实现。然后图片和阅读项具体布局内容(列表图中两者的布局)会有所不同,两个布局都很简单。

  • 下面主要讲Adapter如何设计,先看下“阅读”模块的Adapter实现,下面跟着代码来看下实现步骤。
public class ReadAdapter extends RecyclerView.Adapter<ReadAdapter.ReadHolder> {    //用来装载数据    private List<ReadItem> readlist;    private Context context;    private LayoutInflater inflater;    public ReadAdapter(Context context, List<ReadItem> list) {        this.context = context;        this.readlist = list;        this.inflater = LayoutInflater.from(context);    }    @Override    public ReadHolder onCreateViewHolder(ViewGroup parent, int viewType) {        View view = inflater.inflate(R.layout.item_read, parent, false);        ReadHolder holder = new ReadHolder(view);        return holder;    }    @Override    public void onBindViewHolder(final ReadHolder holder, int position) {        final ReadItem item = readlist.get(position);        holder.rootView.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {      //使用WebView跳转,查看详情界面      WebUtils.openInternal(context,item.getUrl());            }        });        //将标题设置为 序号.内容这种格式        holder.tv_name.setText(String.format("%s. %s", position + 1, item.getName()));        holder.tv_info.setText(item.getUpdateTime() + " • " + item.getFrom());        //使用Glide加载图片,并且将图片缓存到本地      Glide.with(context).load(item.getIcon()).asBitmap().diskCacheStrategy(DiskCacheStrategy.ALL).fitCenter().into(new SimpleTarget<Bitmap>() {            @Override            public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {            //圆形图片                RoundedBitmapDrawable circularBitmapDrawable =                        RoundedBitmapDrawableFactory.create(context.getResources(), resource);                circularBitmapDrawable.setCircular(true);                holder.iv.setImageDrawable(circularBitmapDrawable);            }        });    }    /**     * 设置新内容     * @param data 新内容     */    public void setNewData(List<ReadItem> data) {        this.readlist = data;        notifyDataSetChanged();    }    @Override    public int getItemCount() {        return readlist == null ? 0 : readlist.size();    }    //取得data数据    public List<ReadItem> getData() {        return readlist;    }    //添加data数据    public void addData(int position, List<ReadItem> data) {        this.readlist.addAll(position, data);        //只更新新加入的数据        this.notifyItemRangeInserted(position, data.size());    }    class ReadHolder extends RecyclerView.ViewHolder {        TextView tv_name;        TextView tv_info;        ImageView iv;        View rootView;        ReadHolder(View view) {            super(view);            rootView = view;            tv_name = (TextView) view.findViewById(R.id.tv_read_name);            tv_info = (TextView) view.findViewById(R.id.tv_read_info);            iv = (ImageView) view.findViewById(R.id.iv_read_icon);        }    }}

上面代码中,我们实现了RecyclerView中Adapter必须要实现的接个方法,然后添加了一个setNewData和addData。两个方法来重置和更新数据。具体注意事项上面代码有写注释,主要是RecyclerView 的Adapter的实现方式。

在Fragment中,这里因为数据数量比较特殊,每一页是有限的并且不大,所以不需要采用分页显示,而每次刷新重新获取全部即可。而在“图片”的靓女专题 因为数据量太大,每此只刷新显示6张图片。后面的需要上拉加载才能显示。所以这里会有一点小小的区别。

  • “图片”模块 靓女专题 的Adapter,之前有提到过他与其他的不一样,所以这里做特殊处理。而其他的图片项,则是跟上面的阅读区使用一样的实现,只是显示的内容View不一样罢了。

下面说一下”靓女专题“的实现,它跟其他项不一样的区别在于它是使用API接口(接口在下面)回调的Gson数据,而其他的均是网上爬取。所以他们的区别在于靓女专题的数据很大,不适合在一次全部读取下来,而应该在用户需要的时候在加载更多。

public interface GirlsController {    @GET ("http://gank.io/api/data/%E7%A6%8F%E5%88%A9/6/{page}")    Observable<BaseGankResponse<List<Girl>>> getGank(@Path("page") String page);    @GET ("http://gank.io/api/data/%E7%A6%8F%E5%88%A9/10/{page}")    Observable<ResponseBody> getGankBody(@Path("page") String page);}

下面来看下它的Adapter是如何实现的。代码如下:

public class GankGirlAdapter extends RecyclerView.Adapter<GankGirlAdapter.GirlViewHolder> {    private List<Girl> girlList = new ArrayList<>();    private Context mContext;    public GankGirlAdapter(Context context, List<Girl> girlList) {        mContext = context;        this.girlList = girlList;    }    /**     * 添加数据     *     * @param datas 新增的数据     */    public void addDatas(List<Girl> datas) {        girlList.addAll(datas);        notifyItemChanged(getItemCount());    }    /**     * 设置新内容     *     * @param data 新内容     */    public void setNewData(List<Girl> data) {        this.girlList = data;        notifyDataSetChanged();    }    @Override    public GirlViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        View view = LayoutInflater.from(mContext).inflate(R.layout.item_photo, parent,                false);//这个布局就是一个imageview用来显示图片        GirlViewHolder holder = new GirlViewHolder(view);        return holder;    }    @Override    public void onBindViewHolder(GirlViewHolder holder, final int position) {        ViewGroup.LayoutParams params = holder.iv.getLayoutParams();        params.width = 520;        params.height = (new Random().nextInt(100) + 600);        holder.iv.setLayoutParams(params);        holder.name.setText(girlList.get(position).getName());        holder.date.setText(girlList.get(position).getDate());        holder.iv.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                Intent intent = PicDetailActivity.newIntent(mContext, girlList.get(position).getUrl(), "");                mContext.startActivity(intent);            }        });        //使用params,width 和params.heght 去加载图片        Glide.with(mContext)                .load(girlList.get(position)                        .getUrl())                .override(params.width, params.height) //设置加载尺寸                .centerCrop()                .diskCacheStrategy(DiskCacheStrategy.ALL)                .into((holder).iv);//加载网络图片    }    @Override    public int getItemCount() {        return girlList == null ? 0 : girlList.size();    }    //自定义ViewHolder,用于加载图片    class GirlViewHolder extends RecyclerView.ViewHolder {        ImageView iv;        TextView name;        TextView date;        GirlViewHolder(View view) {            super(view);            iv = (ImageView) view.findViewById(R.id.img);            name = (TextView) view.findViewById(R.id.name);            date = (TextView) view.findViewById(R.id.date);        }    }}

你会觉得这个是曾相识,是的!没错。跟第一个没什么区别,因为重点不在这,而在Fragment中。小二,上代码!好嘞。

 /**     * 获取数据     *     * @param curPage 当前页     */    public void getGank(int curPage) {        ApiFactory.getGirlsController().getGank(curPage + "").subscribeOn(Schedulers.io())                .observeOn(AndroidSchedulers.mainThread())                .subscribe(new Subscriber<BaseGankResponse<List<Girl>>>() {                    @Override                    public void onCompleted() {                        ((MainActivity) getActivity()).showSnack("加载完成");                        binding.swipRefreshLayout.setRefreshing(false);                    }                    @Override                    public void onError(Throwable e) {                        ((MainActivity) getActivity()).showSnack("加载失败");                        binding.swipRefreshLayout.setRefreshing(false);                    }                    @Override                    public void onNext(BaseGankResponse<List<Girl>> response) {                        for (Girl girl : response.datas) {                            if (girl.getHeight() == 0) {                                girl.setHeight((new Random().nextInt(100)) + 500);                            }                        }                        if (isRefresh) {                            adapter.setNewData(response.datas);                        } else {                            adapter.addDatas(response.datas);                        }                    }                });    }

可以看到,我们在得到图片数据之后,进行了判断如果是上拉的话就调用adapter.setNewData(response.datas)方法,如果是下拉刷新就调用adapter.addDatas(response.datas)。

下面是判断是否到达底部的代码:

 binding.gridRecycler.addOnScrollListener(new RecyclerView.OnScrollListener()         {            @Override            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {                //判断是否还能下滑                if (!binding.gridRecycler.canScrollVertically(1)) {                    isRefresh = false;                    getGank(++curPage);                }            }            @Override            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {                super.onScrolled(recyclerView, dx, dy);            }        });

主要代码为!binding.gridRecycler.canScrollVertically(1),用于判断是否还能下拉,如果不能就调用下拉刷新的代码。

这样,两个模块的数据显示就实现了。。。下文将讲解关于界面和设置界面,敬请期待。

0 0
原创粉丝点击