自定义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;        }    }}
原创粉丝点击