自定义圆角矩形---BitmapShader

原创 2015年07月08日 16:48:01

今天,在网络上学习时发现了一个好东西啊--BitmapShader ,改变图片的形状,自定义控件后可以重复使用--哈哈。

这里我进行了自己的理解并且自己实现了一个,我会对每一个代码语句进行注解。

如果想自己详细的学习,请看鸿洋大大的作品-http://blog.csdn.net/lmj623565791/article/details/41967509%20mutable


在上图中有 3个图片,第一章是原始图片,由于截图需要,在xml文件中是指宽高是制定了宽高:

android:layout_width="200dp"
android:layout_height="150dp"

下面介绍一下原理。

实现第一张美女图片时,啥也不用做,进行ImageView控件的正常设置即可。

第二张 图片进行自定义控件,在这里就要说明一下我们要用到的BitmapShader这个牛B家伙了,这个伙计可以对图片3中模式的操作

Shader.TileMode 

CLAMP 

replicate the edge color if the shader draws outside of its original bounds  

Shader.TileMode 

MIRROR 

repeat the shader's image horizontally and vertically, alternating mirror images so that adjacent images always seam  

Shader.TileMode 

REPEAT 

repeat the shader's image horizontally and vertically  


哎,英文我是不行了,看了头大啊,

Shader.TileMpde.CLAMP 这个是说,这里就不得不说他的构造函数了,不然不好解释,小伙们我们一起看他的创造者,

BitmapShader(Bitmap bitmap, Shader.TileMode tileX, Shader.TileMode tileY)

Call this to create a new shader that will draw with a bitmap.

英文解释好像是(我自己的理解,如果有错,表明你英文牛哄哄的大笑),

调用这个函数生成一个shapder对象,然后可以用shader对象画一个bitmap(这个bitmap是你资源文件中的图片通过代码装换出来(后面代码有如何转换),这个bitmap看构造函数就是通过构造函数传进来的,后面的参数就是对图片进行拉伸操作,白痴说话是,通过构造函数中的3中模式中的一个,对你传进来的bitmap图片进行在加工,出厂后就是你想要的东西)。

好了,言归正传Shader.TileMpde.CLAMP 是拉伸,恩,这里要注意啦,不是只要设置了它,就一定会执行,只用当图片的宽高,小于view的宽高是它参会拉神,好难理解啊,我们看图说话:


从图看,当图片层的矩形小于view层的大小才可以拉伸,拉伸的是上下左右每一个边上的1个像素点,那么是不是当他们的大小一样大(白痴的说就是重合)他们会如何?

哈哈答案就是什么也不做,不进行拉伸操作,还有一点就是他先对Y轴进行拉伸,在对x轴进行拉神,我盗用了爱神的图片,看看拉伸的图片


上图中的shader是BitmapShader(Bitmap bitmap, Shader.TileMode.CLAMPShader.TileMode.CLAMP)长生的,对X轴和Y周方向进行拉伸,先对Y后拉伸在对X轴拉伸。

原图片仅仅占据了左上角的一小部分,但是view占据了整个手机屏幕,所以对图片进行了拉伸来满足view的大小。

具体实现:

自定义属性:

<attr name="borderRadius" format="dimension"/>

<attr name="type">
    <enum name="circle" value="0"/>
    <enum name="round" value="1"/>
</attr>

<declare-styleable name="RoundImageView">
    <attr name="borderRadius"/>
    <attr name="type"/>
</declare-styleable>

自定义控件

package com.luo.cutomimageview.view;

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.RectF;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.widget.ImageView;

import com.luo.cutomimageview.R;


/**
 * Created by luolawn on 15/7/8.
 * 自定义圆角图片
 */
public class RoundImageView extends ImageView {

    public static final int BORDER_RADIUS_DEFAULT = 10;
    private static final int TYPE_CIRCLE = 0;
    private static final int TYPE_ROUND = 1;
    private final Matrix matrix;
    private final Paint mPaint;
    private int mBorderRadius;
    private int type;
    private int mRaduis;
    private BitmapShader mBitmapShader;
    private int mWidth;
    private RectF mRoundRect;

    public RoundImageView(Context context, AttributeSet attrs) {
        super(context, attrs);


        matrix = new Matrix();

        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        getAttrsFromXML(context,attrs);
    }


    /**
     * 取得自定义的属性值
     */
    private void getAttrsFromXML(Context context,AttributeSet attrs){

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundImageView);

        mBorderRadius = a.getDimensionPixelSize(R.styleable.RoundImageView_borderRadius,
                (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,BORDER_RADIUS_DEFAULT
                        ,getResources().getDisplayMetrics()));

        type = a.getInt(R.styleable.RoundImageView_type,TYPE_CIRCLE); // 默认原型

        a.recycle();   //在把所有的属性取出后,把TypeArray清空

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        if (TYPE_CIRCLE == type) {
            /**
             * 如果我们目标是画出圆形,那么我们要画出一个正方形的矩形,以测量的高和宽中的最小值为正方形的边长
             * 当我们进行填充图片时,在对图片进行适当的matrix
             */
             mWidth = Math.min(getMeasuredHeight(), getMeasuredWidth());

            mRaduis = mWidth / 2;

            setMeasuredDimension(mWidth, mWidth);

        }
    }


        /**
         * 设置bitmapShader
         */

        private void setupBitmapShader(){


            //取得用户设置的图片
            Drawable drawable = getDrawable();
            if (drawable == null){
                return;
            }
            Bitmap bitmap = drawableToBitmap(drawable);

            mBitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

            float scal = 1.0f;


            if (type == TYPE_CIRCLE){

                int bSize = Math.min(bitmap.getWidth(),bitmap.getHeight());

                scal = mWidth * 1.0f / bSize;

            }else if (type == TYPE_ROUND){

                scal = Math.max(getHeight() * 1.0f / bitmap.getHeight(),getWidth() * 1.0f / bitmap.getWidth());
            }
            scal = 0.2f;

            matrix.setScale(scal,scal);


          //  mBitmapShader.setLocalMatrix(matrix);

            setImageMatrix(matrix);

            mPaint.setShader(mBitmapShader);

        }


    /**
     * 把drawable转化成bitmap
     * @param drawable
     * @return
     */
    private Bitmap drawableToBitmap(Drawable drawable) {

        if (drawable instanceof BitmapDrawable){
            BitmapDrawable bd = (BitmapDrawable) drawable;
            return bd.getBitmap();
        }
        int w = drawable.getIntrinsicWidth();
        int h = drawable.getIntrinsicHeight();

        //现在设置一个具有宽高的bitmap
        Bitmap b = Bitmap.createBitmap(w,h, Bitmap.Config.ARGB_8888);

        Canvas canvas = new Canvas(b);

        drawable.setBounds(0,0,w,h);

        drawable.draw(canvas); //把图片画到canva中去

        return b;
    }


    @Override
    protected void onDraw(Canvas canvas) {

        if(getDrawable() == null){
            return;
        }

        setupBitmapShader();

        if (type == TYPE_CIRCLE){
            canvas.drawCircle(mRaduis,mRaduis,mRaduis,mPaint);
        }else if (type == TYPE_ROUND){

            canvas.drawRoundRect(mRoundRect,mBorderRadius,mBorderRadius,mPaint);
        }


    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        if (type == TYPE_ROUND){
            mRoundRect = new RectF(0,0,getWidth(),getHeight());
        }
    }






}


布局文件
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:zhy="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
   >
    <ImageView
        android:layout_width="200dp"
        android:layout_height="150dp"
        android:src="@drawable/gril"/>

    <com.luo.cutomimageview.view.RoundImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/gril"/>

    <com.luo.cutomimageview.view.RoundImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/gril"
        zhy:type="round"
        zhy:borderRadius="60dp"/>



</LinearLayout>
</ScrollView


mainActivity.java不需要进行更改


相关文章推荐

Android BitmapShader 实战 实现圆形、圆角图片

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/41967509,本文出自:【张鸿洋的博客】1、概述记得初学那会写过一篇博客Andr...

图片处理之 ——— Bitmap(常见方法及图片圆角实现)

作者:夏至 欢迎转载,也请保留这段申明最常用的就是Bitmap了,可以把它看成是一个画架,我们可以在上面进行一些处理,比如压缩,旋转切割,获取信息等。 而他也是造成OOM的元凶之一,现在我们...

在5.0以上手机上用系统原生方式实现波纹涟漪效果

1.使用5.0以上的sdk,并设置value-21的style的AppBaseTheme为parent=”android:Theme.Material.Light”类型。 //此时假如不给textv...

自定义AvatarImageView满足你所有头像显示需求

我们一般实现自定义形状的图形有三种方式:PorterDuffXfermode 、BitmapShader、ClipPath。...
  • Amazing7
  • Amazing7
  • 2016年07月02日 14:57
  • 11272

Android自定义View【实战教程】4⃣️----BitmapShader详解及圆形、圆角、多边形实现

BitmapShader 的作用官方定义:Shader used to draw a bitmap as a texture BitmapShader的作用是使用特定的图片来作为纹理来使用。简单使用...

自定义View—使用clipPath或者BitmapShader实现圆角图片

实现圆角图片的方式有三种,上篇文章中是使用了Xfermode,这篇文章则将总结剩下的两种clipPath、BitmapShader。这里我们跟上一篇一样继承自ImageView。公共部分无论是使用哪种...

自定义的圆角矩形

  • 2017年06月23日 21:38
  • 30.47MB
  • 下载

Android自定义View——可设置形状(圆形、圆角矩形、椭圆)的ImageView,抗锯齿

(如果对自定义View不太熟悉,可以查看上篇文章《Android自定义View——基础知识篇》) 有时显示的图片(如用户头像)是圆形或者圆角矩形的,如果我们把每一种形状的图片都裁剪成一个图片文件...

Android自定义ImageView实现图片圆形 ,椭圆和矩形圆角显示

android中的ImageView只能显示矩形的图片,为了用户体验更多,Android实现圆角矩形,圆形或者椭圆等图形,一般通过自定义ImageView来实现,首先获取到图片的Bitmap,然后通过...

Android自定义ViewGroup(一)——带箭头的圆角矩形菜单

今天要做一个带尖角的圆角矩形菜单,大概长下面这个样子: 要求顶上的尖角要对准菜单锚点,菜单项按压反色,菜单背景色和按压色可配置。 最简单的做法就是让UX给个三角形的图片往上一贴,但是转念一想这样是不是...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:自定义圆角矩形---BitmapShader
举报原因:
原因补充:

(最多只允许输入30个字)