1、前言
有时候,我们在应用中加载图片时并不知道图片确切的宽高数值,但是需要保持宽高比,比如我就遇到这样的设计:图片的宽度填满屏幕,宽高比例为16:9,高度根据这个比例自适应。这样加载出来的图片就形同一张卡片。由于不同手机的屏幕宽度不一样,所以图片宽高无法提前在布局中确定,但好在我们还是可以在代码中动态实现的,现在我们就来看看吧。
2、UI布局
为了便于比较,我在布局中放置了两个ImageView,它们除了id以外,其它的属性都一样。一个正常加载图片,两一个则保持16:9的宽高比。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.lindroid.scaleimageview.SecondActivity">
<TextView
android:layout_marginTop="10dp"
android:gravity="center"
android:text="普通加载"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ImageView
android:scaleType="centerCrop"
android:id="@+id/iv_normal"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:layout_marginTop="10dp"
android:gravity="center"
android:text="宽高比为16:9"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ImageView
android:scaleType="centerCrop"
android:id="@+id/iv_scale"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
另外,为了保持图片拉伸之后不变形,我们在所有的ImageView中都加上android:scaleType="centerCrop"
属性。
3、在代码中动态设置宽高
3.1 计算图片左右间距
首先,我们当然是要拿到图片的宽度。前面提到的图片在宽度上占满屏幕的说法其实不太严谨,因为为了美观,我们往往在左右会留出一些间距。这里我们将左右间距都设为15dp,两者之和即为30dp.
int padding = 15;
int spacePx = (int) (UIUtil.dp2px(this, padding) * 2);
这里用到的工具类UIUtil代码如下:
public class UIUtil {
/**
* 获取屏幕高度(px)
*/
public static int getScreenHeight(Context context) {
return context.getResources().getDisplayMetrics().heightPixels;
}
/**
* 获取屏幕宽度(px)
*/
public static int getScreenWidth(Context context) {
return context.getResources().getDisplayMetrics().widthPixels;
}
public static float dp2px(Context context, float dp) {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics());
}
public static float px2dp(Context context, float px) {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, px, context.getResources().getDisplayMetrics());
}
}
3.2 计算图片宽度
知道了图片距离屏幕左右的间距,图片的宽度自然就是屏幕宽度减去左右间距之和了:
int imageWidth = UIUtil.getScreenWidth(this) - spacePx;
3.3 计算图片高度
得到宽度,现在就可以去计算高度了,首先要算出宽高比:
float scale = 16f / 9f;
注意这里一定要使用浮点型,不然scale的值就是1!
然后根据宽高比去算出高度:
int imageHeight = (int) (imageWidth / scale);
3.4 设置ImageView父布局参数
我们的ImageView的父布局是LinearLayout,所以通过它来设置ImageView的位置:
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( imageWidth,imageHeight);
//设置左右边距
params.leftMargin = (int) UIUtil.dp2px(this, padding);
params.rightMargin = (int) UIUtil.dp2px(this, padding);
ivScale.setLayoutParams(params);
左右的边距除了在布局中动态设置外,大家也可以到xml文件中设置,效果是一样的。
3.5 加载图片资源
最后一步当然是加载图片资源了。我这里加载的是本地文件,如果需要加载网络图片,大家可以使用Glide或者Picasso等框架:
ivScale.setImageResource(R.mipmap.cat);
实现的效果图如下:
跟普通加载的图片比起来,效果还是可以的。
最后随便给一下Activity中的完整代码吧:
public class MainActivity extends Activity {
private ImageView ivNormal;
private ImageView ivScale;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ivNormal = findViewById(R.id.iv_normal);
ivScale = findViewById(R.id.iv_scale);
ivNormal.setImageResource(R.mipmap.cat);
//计算图片左右间距之和
int padding = 15;
int spacePx = (int) (UIUtil.dp2px(this, padding) * 2);
//计算图片宽度
int imageWidth = UIUtil.getScreenWidth(this) - spacePx;
//计算宽高比,注意数字后面要加上f表示浮点型数字
float scale = 16f / 9f;
//根据图片宽度和比例计算图片高度
int imageHeight = (int) (imageWidth / scale);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( imageWidth,imageHeight);
//设置左右边距
params.leftMargin = (int) UIUtil.dp2px(this, padding);
params.rightMargin = (int) UIUtil.dp2px(this, padding);
ivScale.setLayoutParams(params);
ivScale.setImageResource(R.mipmap.cat);
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。