Android自定义View实现不规则图形(6边形)

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

你可能感兴趣的:(android)