自定义ImageView,实现圆角矩形、原型、固定宽高比样式
来源:互联网 发布:喜欢单曲循环的人 知乎 编辑:程序博客网 时间:2024/05/22 16:51
最近,项目中动态展示图片的样式做了调整,宽高比从原来的16:9替换成了2:1。有些地方就要重新计算了。突然觉得,要是ImageView可以自己判断就好了。不想去获取宽度(或者高度),然后利用LayoutParams去修改。
在此基础上,我又加了圆角度数和原型的适配。算是一个小综合吧。
展示图片,我用的Glide。相关Glide,我这里就不做过多解释了。有兴趣的请看
http://blog.csdn.net/u014620028/article/details/78363484
代码实现简单,就直接上代码了
原图:
效果图:
res\values\styles.xml
<declare-styleable name="MyImageViewRatio"> <attr name="ratio" format="float"/> <attr name="angle" format="integer"/> <attr name="isCircle" format="boolean"/> </declare-styleable>
MyImageView
package com.chen.demo;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.BitmapShader;import android.graphics.Canvas;import android.graphics.Matrix;import android.graphics.Paint;import android.graphics.PixelFormat;import android.graphics.RectF;import android.graphics.Shader.TileMode;import android.graphics.drawable.BitmapDrawable;import android.graphics.drawable.Drawable;import android.support.annotation.Nullable;import android.util.AttributeSet;import android.util.Log;import android.widget.ImageView;public class MyImageView extends ImageView { //图片的宽高比 private float ratio = 0; private boolean imgType; /** * 圆角的半径 */ private int mRadius; /** * 3x3 矩阵,主要用于缩小放大 */ private Matrix mMatrix; /** * 绘图的Paint */ private Paint mBitmapPaint; /** * 圆角的大小 */ private int mBorderRadius; /** * 渲染图像,使用图像为绘制图形着色 */ private BitmapShader mBitmapShader; private RectF mRoundRect; private int widthSize; public MyImageView(Context context) { this(context, null); } public MyImageView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, -1); } public MyImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyImageViewRatio); ratio = ta.getFloat(R.styleable.MyImageViewRatio_ratio, 0); mBorderRadius = ta.getInteger(R.styleable.MyImageViewRatio_angle, 0); imgType = ta.getBoolean(R.styleable.MyImageViewRatio_isCircle, false); ta.recycle(); mMatrix = new Matrix(); mBitmapPaint = new Paint(); mBitmapPaint.setAntiAlias(true); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); widthSize = MeasureSpec.getSize(widthMeasureSpec); /** * 如果类型是圆形,则强制改变view的宽高一致,以小值为准 */ if (imgType) { widthSize = Math.min(getMeasuredWidth(), getMeasuredHeight()); mRadius = widthSize / 2; setMeasuredDimension(widthSize, widthSize); } else { if (ratio != 0) { // 告诉系统我要申请这么多的宽高 setMeasuredDimension(widthSize, (int) (widthSize / ratio)); } } } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); Log.e("onSizeChanged=", "onSizeChanged"); // 圆角图片的范围 if (!imgType) mRoundRect = new RectF(0, 0, w, h); } @Override protected void onDraw(Canvas canvas) { setUpShader(); if (imgType) { canvas.drawCircle(mRadius, mRadius, mRadius, mBitmapPaint); } else { canvas.drawRoundRect(mRoundRect, mBorderRadius, mBorderRadius, mBitmapPaint); } } /** * 初始化BitmapShader */ private void setUpShader() { Drawable drawable = getDrawable(); if (drawable == null) { return; } Bitmap bmp = drawableToBitamp(drawable); // 将bmp作为着色器,就是在指定区域内绘制bmp mBitmapShader = new BitmapShader(bmp, TileMode.CLAMP, TileMode.CLAMP); float scale = 1.0f; if (imgType) { // 拿到bitmap宽或高的小值 int bSize = Math.min(bmp.getWidth(), bmp.getHeight()); scale = widthSize * 1.0f / bSize; } else { if (!(bmp.getWidth() == getWidth() && bmp.getHeight() == getHeight())) { // 如果图片的宽或者高与view的宽高不匹配,计算出需要缩放的比例;缩放后的图片的宽高,一定要大于我们view的宽高;所以我们这里取大值; scale = Math.max(getWidth() * 1.0f / bmp.getWidth(), getHeight() * 1.0f / bmp.getHeight()); } } // shader的变换矩阵,我们这里主要用于放大或者缩小 mMatrix.setScale(scale, scale); // 设置变换矩阵 mBitmapShader.setLocalMatrix(mMatrix); // 设置shader mBitmapPaint.setShader(mBitmapShader); } /** * drawable转bitmap * * @param drawable * @return */ private Bitmap drawableToBitamp(Drawable drawable) { if (drawable instanceof BitmapDrawable) { BitmapDrawable bd = (BitmapDrawable) drawable; return bd.getBitmap(); } int w = drawable.getIntrinsicWidth(); int h = drawable.getIntrinsicHeight(); try { Bitmap bitmap = Bitmap.createBitmap(w, h, drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, w, h); drawable.draw(canvas); return bitmap; } catch (OutOfMemoryError outOfMemoryError) { System.gc(); return BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher); } }}
image_item.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/item_tv" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:padding="5dp" android:textSize="25sp"/> <View android:layout_width="match_parent" android:layout_height="3dp" android:background="#55ff0000" /> <com.chen.demo.MyImageView android:id="@+id/iv_1" xmlns:chen="http://schemas.android.com/apk/res/com.chen.demo" android:layout_width="match_parent" android:layout_height="60dp" android:scaleType="fitXY" chen:angle="50" chen:ratio="2" /> <View android:layout_width="match_parent" android:layout_height="3dp" android:background="#5500ff00" /> <com.chen.demo.MyImageView android:id="@+id/iv_2" xmlns:chen="http://schemas.android.com/apk/res/com.chen.demo" android:layout_width="match_parent" android:layout_height="60dp" android:scaleType="fitXY" chen:angle="30" /> <View android:layout_width="match_parent" android:layout_height="3dp" android:background="#550000ff" /> <com.chen.demo.MyImageView android:id="@+id/iv_3" xmlns:chen="http://schemas.android.com/apk/res/com.chen.demo" android:layout_width="match_parent" android:layout_height="60dp" android:layout_gravity="center_horizontal" android:scaleType="fitXY" chen:angle="30" chen:isCircle="true" chen:ratio="2" /></LinearLayout>
在Activity中使用
package com.chen.demo;import android.app.Activity;import android.os.Bundle;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ListView;import android.widget.TextView;import com.bumptech.glide.Glide;public class MainActivity extends Activity { private ListView listview; private String imgUrl = ""; private MyListViewAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listview = findViewById(R.id.listview); imgUrl = "http://pic72.nipic.com/file/20150716/21422793_144600530000_2.jpg"; adapter = new MyListViewAdapter(); listview.setAdapter(adapter); } //ListView数据适配器 private class MyListViewAdapter extends BaseAdapter { @Override public int getCount() { return 20; } @Override public Object getItem(int position) { return position; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder; if (convertView == null) { convertView = LayoutInflater.from(MainActivity.this).inflate(R.layout.image_item, null); viewHolder = new ViewHolder(); viewHolder.item_tv = (TextView) convertView.findViewById(R.id.item_tv); viewHolder.iv_1 = (MyImageView) convertView.findViewById(R.id.iv_1); viewHolder.iv_2 = (MyImageView) convertView.findViewById(R.id.iv_2); viewHolder.iv_3 = (MyImageView) convertView.findViewById(R.id.iv_3); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } viewHolder.item_tv.setText("item==" + position); Glide.with(MainActivity.this).load(imgUrl).into(viewHolder.iv_1); Glide.with(MainActivity.this).load(imgUrl).into(viewHolder.iv_2); Glide.with(MainActivity.this).load(imgUrl).into(viewHolder.iv_3); return convertView; } private class ViewHolder { private TextView item_tv; private MyImageView iv_1; private MyImageView iv_2; private MyImageView iv_3; } }}
阅读全文
0 0
- 自定义ImageView,实现圆角矩形、原型、固定宽高比样式
- 长宽比固定的自定义imageview
- 自定义ImageView实现圆角矩形
- Android 实现自定义宽高比的ImageView
- Android 实现自定义宽高比的ImageView
- 自定义控件View(一)__实现宽高比一致的ImageView
- Android自定义圆角矩形图片ImageView
- android自定义圆角矩形Imageview
- 自定义圆角矩形或者圆形ImageView
- ImageView宽固定,高适应
- 固定元素宽高比
- 安卓学习笔记---自定义ImageView实现图片圆形 ,椭圆和矩形圆角显示(矩形圆角加边框)
- Android自定义ImageView实现图片圆形 ,椭圆和矩形圆角显示
- android 自定义View开发实战(四) 圆角矩形ImageView实现
- css实现宽高比固定小技巧
- 圆角矩形ImageView
- 圆角矩形ImageView
- Android开发之自定义圆角矩形图片ImageView
- 添加MyEclipse WebSphere Portal Server支持
- APP架构设计经验谈:接口的设计
- org.apache.ibatis.binding.BindingException: Parameter '__frch_org_0' not found
- 回溯法解决0-1背包问题
- react table filters筛选用法
- 自定义ImageView,实现圆角矩形、原型、固定宽高比样式
- Git 使用规范流程
- 专家预测产生争议导致数据中心股票下跌
- 人工智能基础了解
- Enum、EnumMap、EnumSet的用法讲解
- Git命令笔记
- ORACLE EBS DATA_BLOCK不显示数据,但Last_query可以查询到数据
- 回溯法
- Java进阶(十九)数组(下)之数组的使用