Android自定义View实现不规则图形(6边形) ,可将其做为背景并在上面放置图片,或可将其用作特殊的按钮。实现了滑动功能(点击功能和放缩功能有待实现,有时间将进行完善)
代码如下:
public class custom extends View {
private Bitmap bitmap=null;
private int mWidth;
private int mHeight;
private int mLength;
private Paint mPaint;
private Path mPath;
private float lastDownX,lastDownY;
private WindowManager windowManager;
//View当前的位置
private int rawX = 0;
private int rawY = 0;
//View之前的位置
private int lastX = 0;
private int lastY = 0;
//private float offsetX,offsetY;
//private int sixWidth,sixHeight,sixLength;
//这里三个构造方法都必须实现,否则会报错
public custom(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public custom(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// TODO Auto-generated constructor stub
}
public custom(Context context, AttributeSet attrs) {
super(context, attrs);
//自定义属性
TypedArray typearray=context.obtainStyledAttributes(attrs,R.styleable.myview);
BitmapDrawable a=(BitmapDrawable)typearray.getDrawable(R.styleable.myview_backg);
if(a!=null){
bitmap=a.getBitmap();
typearray.recycle();
//获取屏幕的高度和宽度用到WindowManager
windowManager=(WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
}
// TODO Auto-generated constructor stub
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
//super.onMeasure(widthMeasureSpec, heightMeasureSpec);
Log.d("taa","onmesure");
//如果布局采用wrapp_content 必须重写onMeasure并在这里判断mode (wrap_content对应AT_MOST)直接获取到的size是parent的宽度,这里给出自定义的最大宽度
int height=300;
int widthmode=MeasureSpec.getMode(widthMeasureSpec);
int widthsize=MeasureSpec.getSize(heightMeasureSpec);
int heightmode=MeasureSpec.getMode(heightMeasureSpec);
int heightsize=MeasureSpec.getSize(heightMeasureSpec);
if(widthmode==MeasureSpec.AT_MOST&&heightmode==MeasureSpec.AT_MOST){
setMeasuredDimension(Math.min(widthsize, width),Math.min(height, heightsize));
}
else if(widthmode==MeasureSpec.AT_MOST){
setMeasuredDimension(Math.min(widthsize, width),heightsize);
}
else if(heightmode==MeasureSpec.AT_MOST){
setMeasuredDimension(widthsize,Math.min(height, heightsize));
}
else{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
Log.d("taa","ondraw");
mWidth=getWidth();
mHeight=getHeight();
mLength = mWidth / 2;
double radian30 = 30 * Math.PI / 180;
float a = (float) (mLength * Math.sin(radian30));
float b = (float) (mLength * Math.cos(radian30));
float c = (mHeight - 2 * b) / 2;
System.out.println("cccc"+c);
mPaint=new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(Color.BLUE);
mPaint.setStyle(Paint.Style.FILL);
//画六边形 (大小可在布局中随意设置的6边形)
Path path = new Path();
path.moveTo(getWidth(),getHeight() / 2);
path.lineTo(getWidth() - a, getHeight() - c);
path.lineTo(getWidth() - a - mLength, getHeight() - c);
path.lineTo(0, getHeight() / 2);
path.lineTo(a, c);
path.lineTo(getWidth() - a, c);
path.close();
canvas.drawPath(path, mPaint);
mPaint.setColor(Color.GRAY);
Matrix matrix=new Matrix();
matrix.postTranslate(this.getWidth() / 2 - bitmap.getWidth() / 2,
this.getHeight() / 2 - bitmap.getHeight() / 2);
canvas.drawBitmap(bitmap, matrix, mPaint);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
Log.d("taa","ontouch");
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
float edgeLength = ((float) getWidth()) / 2;
float radiusSquare = edgeLength * edgeLength * 3 / 4;
float dist = (event.getX() - getWidth() / 2)
* (event.getX() - getWidth() / 2)
+ (event.getY() - getHeight() / 2)
* (event.getY() - getHeight() / 2);
if (dist <= radiusSquare) {// 点中六边形区域
rawX=(int) event.getRawX();
rawY=(int) event.getRawY();
lastX=rawX;
lastY=rawY;
}
break;
case MotionEvent.ACTION_MOVE:
edgeLength = ((float) getWidth()) / 2;
radiusSquare = edgeLength * edgeLength * 3 / 4;
dist = (event.getX() - getWidth() / 2)
* (event.getX() - getWidth() / 2)
+ (event.getY() - getHeight() / 2)
* (event.getY() - getHeight() / 2);
if (dist <= radiusSquare) {// 点中六边形区域
rawX=(int) event.getRawX();
rawY=(int) event.getRawY();
int offX=rawX-lastX;
int offY=rawY-lastY;
//获取屏幕的高度和宽度
int window_width=windowManager.getDefaultDisplay().getWidth();
int window_height=windowManager.getDefaultDisplay().getHeight();
if(getLeft()+offX>=0&&getTop()+offY>=0&&getRight()+offX<=window_width&&getBottom()+offY<=window_height){
//通过View.layout来设置左上右下坐标位置
//获得当前的left等坐标并加上相应偏移量
layout(getLeft() + offX,
getTop() + offY,
getRight() + offX,
getBottom() + offY);
//移动过后,更新lastX与lastY
lastX = rawX;
lastY = rawY;
}
}
break;
}
return true;
}
}
//自定义命名空间 后面是res-auto //xmlns:custom="http://schemas.android.com/apk/res-auto"
//在values下新建的attrs.xml