一起撸个朋友圈吧(step5) - 控件篇【内容(上)】
项目地址:https://github.com/razerdp/FriendCircle
一起撸个朋友圈吧这是本文所处文集,所有更新都会在这个文集里面哦,欢迎关注
上篇链接:http://www.jianshu.com/p/ff9788581fb0
下篇链接:http://www.jianshu.com/p/3d0cc6882e1a
内容页里面今天主要实现图文的内容,因为纯文字的话内容页是无需展示的,网页分享则是固定的,只有图文是变化的。
如果平时浏览朋友圈,我们不难发现图文混编时,图片的数量对控件的大小是有影响的。
下面直接上两张图,很容易就可以发现端倪:
图1
图2
图3
- 图一:当图片是单张的时候,我们可以发现图片的大小并非固定的,但可以肯定的是,对于但张图片是有宽高上限。
- 图二:无论是两列还是三列,其item宽度都是一样的,而且都是正方形
- 图三:图片为4张是,呈“田”字排版,而且遵循第二点的规则。
而解决方案目前如下:
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,则手动修改类型。
也许有人会觉得每次遍历这效率太低,而且会不会阻塞,这里回答一下:
- 首先,这个数组的长度是跟我们请求时发送的count有关,比如我们发送8条,就只会请求8条,所以这里的耗时几乎可以忽略
- 其次,我们的解析是覆写volley的request,在request里面执行的(parseNetworkResponse),volley每个请求都会弄到队列,而这个是异步的,所以并不会阻塞UI线程。详情可以看这里
这两部做好后,我们开始动工我们的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里面实现我们的操作:
在开干之前,我们先想想可以如何实现自适应大小:
- 得到图片的宽高,与我们的最大宽高相比,然后动态设置imageview的LayoutParams,然后再载入图片
- 得到图片的宽高,与我们的最大宽高相比,然后缩放图片
大致这两个方案,一个操作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