weex实现微信朋友圈动态条目中图片自适应展示效果
话不多说,先上效果图:
image
此处图片资源是在wanandroid中找的,能看到效果就行。
思路:
1,如何显示图片的自动换行,相信这个应该难不到大家,我这里使用的是 一个自动换行属性 “flex-warp:warp”,
2,处理特殊数目的图片,这里,我们只需要处理 1张图片,4张图片,其余数目的图片这三种情况。
3,细节处理,1张图片的时候,其实是对图片做了等比缩放之后展示全图,而多张的时候,其实就是展示了一个裁剪效果的图。
4,这里四张的时候,如何实现正方形展示,我这里是修改了图片的宽高,和间距,第三张图片无法在剩余的空间内展示,只有换行。当然这里也有其他的方法,比如在图片数组中索引为2的位置动态添加一个空的src也是可以的。
5,如果你在集成的时候,有自己实现ImageAdaper,那么还需要注意一点,要实现这个效果,原生代码里面的imageAdapter里面也需要做相应的处理,给图片加载框架添加加载完成的监听,在监听内部回调Weex提供的API。可以查看github上adapter的实现例子。
代码:
<template>
<div class="list">
<div v-for="(item, index) in data" :style="{width: `${width + 8}px`, height: `${height + 8}px`}">
<image :src="item.src" alt="" :resize="dataLenght == 1 ? 'stretch' : 'cover'" class="img" @load="handleLoad"/>
</div>
</div>
</template>
<script>
const animation = weex.requireModule('animation');
export default {
name: "ImageWidget",
props:{
data:{
type:Array,
}
},
data () {
return {
//设置图片的默认大小
width:224,
height:224,
}
},
computed : {
dataLenght () {
return this.data ? this.data.length : 0;
}
},
methods : {
//event表示图片加载完成的一个回调,里面包含成功之后和失败时候的信息
handleLoad (event) {
if (event.success){
if (this.data.length === 1) {
// this.loading = true;
//获取图片加载完成之后的真实宽高(实际上是原生中图片生成的bitmap的宽高)
let w = event.size.naturalWidth;
let h = event.size.naturalHeight;
//获取高宽比例
let ratio = h / w;
//以下的值是通过高宽比重新计算 缩放后的图片大小,相当于等比缩放
let tempWidth = 0;
if (ratio <= 1 && w < 690) {
tempWidth = w
}
if (ratio <= 1 && w >= 690) {
tempWidth = 500
}
if (ratio > 1 && ratio <= 2) {
tempWidth = 300
}
if (ratio > 2) {
tempWidth = 200
}
this.width = tempWidth;
this.height = tempWidth * ratio;
//让计算之后的图片做缩放动画至我们设置的实际尺寸,这里如果修改duration的值,
//可以看到明显的动画效果。
//这样做是由于我们直接改变image控件的大小,此时的image已经加载完成,如果直接
//设置的话,是无效的
animation.transition(event.target, {
styles: {
width: `${this.width}px`,
height: `${this.height}px`
},
duration: 0,
timingFunction: 'ease',
delay: 0
})
} else if (this.data.length === 4) {
this.width = 226;
this.height = 226;
} else {
this.width = 224;
this.height = 224;
}
}
}
}
}
</script>
<style scoped>
.list{
/*自动换行*/
flex-wrap: wrap;
/*上下padding为0 左右为26px*/
padding: 0px 26px;
flex-direction: row;
align-items: center;
}
.img {
width: 224px;
height: 224px;
margin: 4px;
}
</style>
注意:由于博主对typora使用的不6,导致代码粘贴过来有换行,如果你刚好用到这个,复制到你的项目中去,记得把<template>中的换行干掉。因为有时候,换行会导致莫名其妙的问题。
Android端代码:
public class ImageAdapter implements IWXImgLoaderAdapter {
public ImageAdapter() {
}
@Override
public void setImage(final String url, final ImageView view,
WXImageQuality quality, final WXImageStrategy strategy) {
WXSDKManager.getInstance().postOnUiThread(new Runnable() {
@Override
public void run() {
if(view==null||view.getLayoutParams()==null){
return;
}
if (TextUtils.isEmpty(url)) {
view.setImageBitmap(null);
return;
}
if (url.startsWith("file://")) {
Glide.with(WXEnvironment.getApplication()).load(url).into(view);
return;
}
//判断是否是Base64的图片
if(url.startsWith("data:"))
{
Bitmap bitmap = Util.stringToBitmap(url);
if(null != bitmap)
{
view.setImageBitmap(bitmap);
}
return;
}
String temp = url;
if (url.startsWith("//")) {
temp = "http:" + url;
}
if (view.getLayoutParams().width <= 0 || view.getLayoutParams().height <= 0) {
return;
}
if(!TextUtils.isEmpty(strategy.placeHolder)){
Picasso.Builder builder = new Picasso.Builder(WXEnvironment.getApplication());
Picasso picasso=builder.build();
picasso.load(Uri.parse(strategy.placeHolder)).into(view);
view.setTag(strategy.placeHolder.hashCode(),picasso);
}
Picasso.with(WXEnvironment.getApplication())
.load(temp)
.transform(new BlurTransformation(strategy.blurRadius))
.into(view, new Callback() {
@Override
public void onSuccess() {
if(strategy.getImageListener()!=null){
strategy.getImageListener().onImageFinish(url,view,true,null);
}
if(!TextUtils.isEmpty(strategy.placeHolder)){
((Picasso) view.getTag(strategy.placeHolder.hashCode())).cancelRequest(view);
}
}
@Override
public void onError() {
if(strategy.getImageListener()!=null){
strategy.getImageListener().onImageFinish(url,view,false,null);
}
}
});
}
},0);
}
}
如果以上代码有什么问题,欢迎评论留言!











网友评论