android六边形imageview

Posted 楠之枫雪

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android六边形imageview相关的知识,希望对你有一定的参考价值。

最近有个蜂巢布局的需求,需求实现android六边形imageview,实现了正:1.六边形图片截取显示。2.截取居中内容。

效果如下:

转载注明:http://blog.csdn.net/u014614038/article/details/77481041
代码如下:

package beehive.hw.com.beehivecontent;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Region;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ImageView;


/**
 * Created by bifan-wei
 */

public class HexagonImageView extends ImageView 
    private String tag = "HexagonImageView";
    private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
    private static final int COLORDRAWABLE_DIMENSION = 1;
    private static final Matrix mShaderMatrix = new Matrix();
    private static final Paint mBitmapPaint = new Paint();
    private BitmapShader mBitmapShader;
    private int mBitmapWidth;
    private int mBitmapHeight;
    private int mWidth = 0;
    private Bitmap mBitmap;

    public HexagonImageView(Context context) 
        super(context);
        init();
    

    public HexagonImageView(Context context, AttributeSet attrs) 
        super(context, attrs, 0);
        init();
    

    public HexagonImageView(Context context, AttributeSet attrs, int defStyleAttr) 
        super(context, attrs, defStyleAttr);
        init();
    

    private void init() 
        this.setClickable(true);
    

    @Override
    protected void onDraw(Canvas canvas) 
        Drawable drawable = getDrawable();
        if (drawable == null || getWidth() * getHeight() == 0) 
            return;
        
        mBitmap = getBitmapFromDrawable(drawable);
        if (mBitmap == null) 
            return;
        

        setup();
        canvas.drawPath(getHexagonPath(), mBitmapPaint);

    

    private Path mPath = null;
    public Path getHexagonPath() 
        if (mPath == null) 
            mPath = new Path();
        
            float d = (float) ((float)mWidth / 4 * (2 - Math.sqrt(3)));//六边形到边到内切圆的距离
            float r = mWidth/4;
            float p0x = r;
            float p0y = d;

            float p1x = r*3;
            float p1y = d;

            float p2x = mWidth;
            float p2y = mWidth/2;

            float p3x = p1x;
            float p3y = mWidth-d;

            float p4x = p0x;
            float p4y = p3y;

            float p5x = 0;
            float p5y = p2y;

            mPath.reset();
            mPath.moveTo(p0x,p0y);
            mPath.lineTo(p1x,p1y);
            mPath.lineTo(p2x,p2y);
            mPath.lineTo(p3x,p3y);
            mPath.lineTo(p4x,p4y);
            mPath.lineTo(p5x,p5y);
            mPath.lineTo(p0x,p0y);

        return mPath;
    

    private Boolean DownOnEffectiveArea = false;


    @Override
    public void setOnTouchListener(OnTouchListener l) 
        super.setOnTouchListener(l);
    

    @Override
    public boolean onTouchEvent(MotionEvent event) 
        switch (event.getAction())
            case MotionEvent.ACTION_DOWN:
                CheckIfDownOnffectiveArea(event);
                break;
            case MotionEvent.ACTION_MOVE:
                break;
            case MotionEvent.ACTION_UP:
                break;
        
        return super.onTouchEvent(event);
    

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) 
        //if (event.getAction() == MotionEvent.ACTION_DOWN) 
            if (!CheckIfDownOnffectiveArea(event))  return false;
       // 
        return super.dispatchTouchEvent(event);
    

    private Boolean CheckIfDownOnffectiveArea(MotionEvent event) 
        DownOnEffectiveArea = computeRegion(mPath).contains((int)event.getX(),(int)event.getY());
        return DownOnEffectiveArea;
    

    private Region computeRegion(Path path) 
        Region region = new Region();
        RectF f = new RectF();
        path.computeBounds(f, true);
        region.setPath(path, new Region((int) f.left, (int) f.top, (int) f.right, (int) f.bottom));
        return region;
    

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);//限制为正方形
        mWidth = Math.min(getMeasuredWidth(), getMeasuredHeight());
        setMeasuredDimension(mWidth, mWidth);
    

    public  int getmWidth() 
        return mWidth;
    

    @Override
    public void setImageBitmap(Bitmap bm) 
        super.setImageBitmap(bm);
        invalidate();
    

    @Override
    public void setImageDrawable(Drawable drawable) 
        super.setImageDrawable(drawable);
        invalidate();
    

    @Override
    public void setImageResource(int resId) 
        super.setImageResource(resId);
        invalidate();
    

    private Bitmap getBitmapFromDrawable(Drawable drawable) 
        if (drawable == null) 
            return null;
        
        if (drawable instanceof BitmapDrawable) 
            return ((BitmapDrawable) drawable).getBitmap();
        

        try 
            Bitmap bitmap;
            if (drawable instanceof ColorDrawable) 
                bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION,
                        COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);
             else 
                bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
                        drawable.getIntrinsicHeight(), BITMAP_CONFIG);
            

            Canvas canvas = new Canvas(bitmap);
            drawable.setBounds(0, 0, mWidth, mWidth);
            drawable.draw(canvas);
            return bitmap;
         catch (OutOfMemoryError e) 
            return null;
        
    

    private void setup() 
        if (mBitmap != null) 
        mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        mBitmapPaint.setAntiAlias(true);
        mBitmapHeight = mBitmap.getHeight();
        mBitmapWidth = mBitmap.getWidth();
        updateShaderMatrix();
        mBitmapPaint.setShader(mBitmapShader);
        
    



    private void updateShaderMatrix() 
        float scale;
        mShaderMatrix.set(null);
        if (mBitmapWidth != mBitmapHeight) 
            scale = Math.max((float) mWidth / mBitmapWidth, (float) mWidth / mBitmapHeight);
         else 
            scale = (float) mWidth / mBitmapWidth;
        

        mShaderMatrix.setScale(scale, scale);//放大铺满

        float dx = mWidth - mBitmapWidth * scale;
        float dy = mWidth - mBitmapHeight * scale;
        mShaderMatrix.postTranslate(dx / 2, dy / 2);//平移居中
        mBitmapShader.setLocalMatrix(mShaderMatrix);
    



使用:

 <beehive.hw.com.beehivecontent.HexagonImageView
        android:id="@+id/hexagonview1"
        android:layout_gravity="center"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@mipmap/pic"
        />
holder.hexagonImageView.setImageResource(R.mipmap.pic);

以上是关于android六边形imageview的主要内容,如果未能解决你的问题,请参考以下文章

如何为 ImageView 赋予六边形形状

poj 3525 凸多边形多大内切圆

POJ 3525 Most Distant Point from the Sea (半平面交 + 凸多边形最大内切圆 + 二分)

poj3525计算凸多边形最大内切圆(模板 半平面交向量平移)

CAD怎么画不规则多边形

六边形 ImageView 圆角