自定义六角形头像图片控件

    xiaoxiao2026-08-08  9

    自定义六角形头像图片控件

    效果图

    最近笔者的一个朋友又委托我帮忙写一个六角形展示,公司给出的效果图,朋友在网上找不到相应的Demo,于是向笔者求助,笔者最近又不是太忙,所以就欣然答应。于是笔者就随便在网上找了一个圆形头像显示图片随意改了一下,下面是效果图 Demo下载地址这里是六角形图片下载的地址 参考项目的地址这里是参考项目的地址 其实该起来也是非常的简单,下面就由笔者交单介绍一下项目的关键代码

    项目的关键代码

    声明一个画笔并设置BitmapShader

    首先声明一个画图片的画笔,再给画笔设置shader

    //用于画图片的画笔 private BitmapShader mBitmapShader; //创建一个BitmapShader对象,并从布局文件的src中获取图片对象,即mBitmap,并传递给BitmapShader mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); mBitmapPaint.setAntiAlias(true); //把BitmapShader设置给画笔 mBitmapPaint.setShader(mBitmapShader);

    计算绘图的区域

    计算绘图的区域,是一个矩形,后期会根据矩形来确定六角形六个点的坐标

    //计算绘制图片的区域,并设置给mBorderRect /**计算绘图的区域及绘图的中心坐标*/ private final RectF mDrawableRect = new RectF(); mDrawableRect.set(calculateBounds()); mDrawableRadius = Math.min(mDrawableRect.height() / 2.0f, mDrawableRect.width() / 2.0f); /** * 计算绘制图片的区域 * @return */ private RectF calculateBounds() {int availableWidth = getWidth() - getPaddingLeft() - getPaddingRight(); int availableHeight = getHeight() - getPaddingTop() - getPaddingBottom(); int sideLength = Math.min(availableWidth, availableHeight); float left = getPaddingLeft() + (availableWidth - sideLength) / 2f; float top = getPaddingTop() + (availableHeight - sideLength) / 2f; return new RectF(left, top, left + sideLength, top + sideLength); }

    绘制六边形

    只要给画笔设置BitmapShader ,我们画什么样字的图形,图形所在位置的图片部分就可以显示出来,这时我们如果画个圆,图片就会成圆形,画个弧。图片就会成弧形,画个六角形,图片就会成六角形,所以你要更改图形的话就更改这里的代码 画六角形的话就用到path和canvas的drawpath方法了

    //声明path对象 Path path=new Path(); //移动到定点 path.moveTo(mDrawableRect.centerX(),0); //下面是点与点之间的连线 path.lineTo((float) (mDrawableRadius*(1.0f-Math.sin(Math.PI/3.0f))),mDrawableRadius/2.0f); path.lineTo((float) (mDrawableRadius*(1.0f-Math.sin(Math.PI/3.0f))),mDrawableRadius*3/2.0f); path.lineTo(mDrawableRect.centerX(),mDrawableRadius*2); path.lineTo((float) (mDrawableRadius*(1.0f+Math.sin(Math.PI/3.0f))),mDrawableRadius*3/2.0f); path.lineTo((float) (mDrawableRadius*(1.0f+Math.sin(Math.PI/3.0f))),mDrawableRadius/2.0f); //连到第六个线时闭合路线 path.close(); //画六角形,就显示六角形图像 canvas.drawPath(path,mBitmapPaint);

    添加一些自定义的属性

    声明属性

    在res文件夹下的values文件夹下创建一个attrs.xml文件 内容如下

    <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="HexagonImageView"> <attr name="civ_border_width" format="dimension" /> <attr name="civ_border_color" format="color" /> <attr name="civ_border_overlay" format="boolean" /> <attr name="civ_fill_color" format="color" /> </declare-styleable> </resources>

    定义命名空间

    使用时在布局文件的布局声明一下命名空间,即添加一下代码

    xmlns:app="http://schemas.android.com/apk/res-auto"

    末尾res-auto的意思在apk的res文件夹下自动寻找属性,这样我们就可以在控件里使用了

    app:civ_border_color="@color/dark" app:civ_border_width="2dp"

    下面是布局文件的代码

    <?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" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <RelativeLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:background="@color/light" android:padding="@dimen/base_padding"> <com.example.hexagonimageview.view.HexagonImageView android:layout_width="160dp" android:layout_height="160dp" android:layout_centerInParent="true" android:src="@drawable/belle" app:civ_border_color="@color/dark" app:civ_border_width="2dp" /> </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:background="@color/dark" android:padding="@dimen/base_padding"> <com.example.hexagonimageview.view.HexagonImageView android:layout_width="160dp" android:layout_height="160dp" android:layout_centerInParent="true" android:src="@drawable/belle" app:civ_border_color="@color/light" app:civ_border_width="2dp" /> </RelativeLayout> </LinearLayout>

    在代码里处理属性

    以上三步配置的属性并不起作用,我们只有在代码里处理才有用处我们一般会在构造函数里去处理,代码如下

    public HexagonImageView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.HexagonImageView, defStyle, 0); mBorderWidth=a.getDimensionPixelSize(R.styleable.HexagonImageView_civ_border_width, DEFAULT_BORDER_WIDTH); mBorderColor=a.getColor(R.styleable.HexagonImageView_civ_border_color, DEFAULT_BORDER_COLOR); mBorderOverlay=a.getBoolean(R.styleable.HexagonImageView_civ_border_overlay, DEFAULT_BORDER_OVERLAY); mFillColor=a.getColor(R.styleable.HexagonImageView_civ_fill_color, DEFAULT_FILL_COLOR); a.recycle(); init(); }

    这样就可以获取在布局文件里配置的属性并进行处理了,这样一个完整的六角形自定义图片空间就完成了

    注意

    demo使用时需把res-values-attrs.xml的文件拷贝到对应的项目的res-values文件夹下 app:civ_border_color=”@color/dark”是指图片边框的颜色 app:civ_border_width=”2dp”是指图片边框的高度

    转载请注明原文地址: https://ju.6miu.com/read-1310991.html
    最新回复(0)