Android进阶Android自定义控件自定义view相关

一起撸个朋友圈吧(step5) - 控件篇【内容(上)】

2016-02-27  本文已影响663人  Razerdp

项目地址:https://github.com/razerdp/FriendCircle
一起撸个朋友圈吧这是本文所处文集,所有更新都会在这个文集里面哦,欢迎关注

上篇链接:http://www.jianshu.com/p/ff9788581fb0
下篇链接:http://www.jianshu.com/p/3d0cc6882e1a


内容页里面今天主要实现图文的内容,因为纯文字的话内容页是无需展示的,网页分享则是固定的,只有图文是变化的。

如果平时浏览朋友圈,我们不难发现图文混编时,图片的数量对控件的大小是有影响的。

下面直接上两张图,很容易就可以发现端倪:


图1
图2
图3

而解决方案目前如下:
1 - 单张图片可以针对解决,另外布局
2 - item可以直接给定宽高。
3 - 当图片为4张,动态设置列数为2,由于第二点的原因,宽度都是一致的。

本篇解决第一点


首先需要知道的是,我们服务器下发的图片是一个jsonArray,也就是一个数组,而且type都是11,也就是说这个图组可能是1张,也可能是9张,但他们的type都是11。

因此我们需要在本地转换一下,在用gson解析完后,需要判断图片数量,等于1的话,就直接设定为我们本地定下的type,然后针对使用布局。

首先定义一下我们的type,这次我们定义为9:

type

然后复制原有布局,直接在我们的content里面塞入一个ImageView,定义一下宽高和最大高度。

大概如图效果(宽高最大的情况):

然后建立我们的item,并返回我们的res

/**
 * Created by 大灯泡 on 2016/2/27.
 * 图文(单张)
 * type=9
 */
public class ItemWithImgSingle extends BaseItemDelegate {

    public ItemWithImgSingle(){}

    @Override
    protected void bindData(int position, @NonNull View v, @NonNull MomentsInfo data, int dynamicType) {

    }

    @Override
    public int getViewRes() {
        return R.layout.dynamic_item_with_img_single;
    }

    @Override
    public void onFindView(@NonNull View parent) {

    }
}

得益于我们之前的封装,添加一个布局基本不怎么费力(至少不用去adapter写holder和swithc viewtype),接着我们去adapter注册一下,我们的布局就可以投入使用了。

注册布局

接下来就是实现我们的逻辑。

首先去到我们的请求解析里面,手动判断一下是否单张图片(*本文集并没有写请求相关的代码实现文章):

    @Override
    public void parseResponse(BaseResponse response, JSONObject json, int start, boolean hasMore) throws JSONException {
        hostInfo= JSONUtil.toObject(json.optString("hostInfo"),HostInfo.class);
        List<MomentsInfo> momentsInfos=JSONUtil.toList(json.optString("moments"),new TypeToken<ArrayList<MomentsInfo>>(){}
                .getType());
        setStart(start);
        
        //手动判断
        if (momentsInfos != null) {
            for (int i = 0; i < momentsInfos.size(); i++) {
                MomentsInfo momentsInfo = momentsInfos.get(i);
                if (momentsInfo.dynamicInfo != null &&
                        momentsInfo.dynamicInfo.dynamicType == DynamicType.TYPE_WITH_IMG) {
                    if (momentsInfo.content.imgurl != null && momentsInfo.content.imgurl.size() == 1) {
                        momentsInfo.dynamicInfo.dynamicType = DynamicType.TYPE_IMG_SINGLE;
                    }
                }
            }
        }
        response.setData(momentsInfos);
    }

每次解析完后,我们遍历一次数组,得到type,如果type是图文,则判断图组长度,如果是1,则手动修改类型。

也许有人会觉得每次遍历这效率太低,而且会不会阻塞,这里回答一下:

这两部做好后,我们开始动工我们的item:

首先在onFindView里面初始化一些参数:

   @Override
    public void onFindView(@NonNull View parent) {
        mImageView= (ImageView) parent.findViewById(R.id.img_single);
        if (maxWidth==0){
            maxWidth= UIHelper.getScreenPixWidth(context)-UIHelper.dipToPx(context,90f);
        }
        if (maxHeight==0){
            maxHeight=UIHelper.dipToPx(context,175f);
        }
    }

这里我们主要初始化最大宽高

然后在onBindData里面实现我们的操作:

在开干之前,我们先想想可以如何实现自适应大小:

大致这两个方案,一个操作view,一个操作图片。这里我们采用第二个方案,原因无他,第一个方案不断的设置LayoutParams就会导致requestLayout(),然后导致测量/layout/重绘,造成的,依然是视觉上的卡顿。于是我们采取方案二。

方案二我们可以通过Glide官方文档得知,我们实现如下方法:

Glide.with(yourApplicationContext))
    .load(youUrl)
    .asBitmap()
    .into(new SimpleTarget<Bitmap>(myWidth, myHeight) {
        @Override
        public void onResourceReady(Bitmap bitmap, GlideAnimation anim) {
            // Do something with bitmap here.
        }
    };

可以拿到图片信息,在这里我们就可以判断图片宽高,然后通过Glide的override方法来得到图片了。(ps:在下不知道在Glide里面又调用Glide好不好,直觉不太好,但在下暂时木有想到一个更好的方法。。。希望有经验的大大们可以传授一下-V-

代码如下:

 @Override
    protected void bindData(int position, @NonNull View v, @NonNull MomentsInfo data, int dynamicType) {
        final String imgUrl=data.content.imgurl.get(0);
        if (!TextUtils.isEmpty(imgUrl)){
            Glide.with(context).load(imgUrl).asBitmap().into(new SimpleTarget<Bitmap>() {
                @Override
                public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
                    if (resource.getWidth() >= maxWidth) {
                        width = maxWidth;
                    }
                    else {
                        width = resource.getWidth();
                    }
                    resource.recycle();
                    Glide.with(context)
                         .load(imgUrl)
                         .dontAnimate()
                         .crossFade()
                         .override(width,
                                 (int) (width * ratio))
                         .into(mImageView);

                }
            });
        }
    }

ratio是我们的最大宽高比,我们通过这个来等比压缩图片,而不至于达到fitXY那样的不计较任何成本的压缩。(简言之,压扁了好么。。。。或者压瘦了好么。。。。)

最终效果图如下:

效果图

附:本文使用的三张图片地址:
http://d.hiphotos.baidu.com/zhidao/pic/item/faedab64034f78f06cadf7e97a310a55b3191c01.jpg
http://www.qqpk.cn/Article/UploadFiles/201201/20120108160105455.jpg
http://cdn.duitang.com/uploads/item/201409/27/20140927123303_kdKje.thumb.700_0.jpeg

上一篇下一篇

猜你喜欢

热点阅读