1、遇到的问题
项目中采用的是viewpager+Fresco实现图集的预览,但是如果图片过长会出现图片的高度在屏幕内被撑满,而宽度没有撑满的情况。
如图:

而现在需要的效果是宽度撑满,高度自适应。应该是下图这种:

2、解决思路
2.1. 将viewpager的宽度设置为图片的宽度,viewpager的高度设置为自适应即可。但是接口返回的图片的宽度就是屏幕的宽度,项目采用的是Fresco加载,缩放模式为fitCenter
fitCenter: 保持宽高比,缩小或者放大,使得图片完全显示在显示边界内,且宽或高契合显示边界。居中显示。
图片的高度就是屏幕的高度。这就导致图片的加载固定在屏幕区域内,无法设置宽度自适应。因此想到第二种思路改变缩放模式
2.2. 更改图片的缩放模式
采用centerCrop缩放模式,这种模式能够做到屏幕内的图片宽高自适应了,但是向上或者向下滑动图片,发现图片被截取了,这是因为父控件的高度就是屏幕的高度。没办法全部加载。

parentRect.height()的值就是屏幕的高度。
因此我们可以采用自定义缩放类型来处理,让Fresco加载全部图片:
public class AtlasScaleType implements ScalingUtils.ScaleType {
private int imageWidth=-1;
private int imageHeight=-1;
public AtlasScaleType(int imageWidth,int imageHeight){
this.imageWidth=imageWidth;
this.imageHeight=imageHeight;
}
//parent bounds(View坐标系中对图片的限制区域)
//child size (要放置的图片高宽)
//focus point (图片坐标系中的聚焦点位置
@Override
public Matrix getTransform(M atrix outTransform, Rect parentBounds, int childWidth, int childHeight, float focusX, float focusY) {
// 取宽度和高度需要缩放的倍数中最大的一个
final float scaleX = (float) parentBounds.width() / (float) childWidth;
final float scaleY = (float) parentBounds.height() / (float) childHeight;
float scale ;
float dx;
float dy;
//当图片的高度大于屏幕的高度时,我们认为是长图,加载方式为从长图的顶部加载全部。parentBounds.bottom设置为imageHeight,
//这样parentBounds.height即为图片的高度;
if(imageHeight >UIUtils.getHeight()){ //超长图
scale= Math.max(scaleX, scaleY);
parentBounds.bottom=imageHeight;
dx = parentBounds.left + (parentBounds.width() - childWidth * scale) * 0.5f;
dy = parentBounds.top ; //长图顶部
}else{
scale = Math.min(scaleX, scaleY);
dx = parentBounds.left + (parentBounds.width() - childWidth * scale) * 0.5f;
dy = parentBounds.top + (parentBounds.height() - childHeight * scale) * 0.5f;
}
// Log.e("XXXX"," p_W "+parentBounds.width()+" p_H "+parentBounds.height() +" child_W "+childWidth+" child_H"
// +childHeight+"f_X"+focusX+"f_Y"+focusY+ " scale "+scale + " dx"+dx+" dy"+dy);
outTransform.setScale(scale, scale);
outTransform.postTranslate((int) (dx + 0.5f), (int) (dy + 0.5f));
return outTransform;
}