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

Android自定义View实现不规则图形(6边形)  ,可将其做为背景并在上面放置图片,或可将其用作特殊的按钮。实现了滑动功能(点击功能和放缩功能有待实现,有时间将进行完善)

代码如下:

<span style="font-size:18px;">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);</span>
<span style="font-size:18px;">         //自定义属性 
	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");
<span style="font-family: Arial, Helvetica, sans-serif;"> //如果布局采用wrapp_content 必须重写onMeasure并在这里判断mode (wrap_content对应AT_MOST)</span><span style="font-family: Arial, Helvetica, sans-serif;">直接获取到的size是parent的宽度,这里给出自定义</span><span style="font-family: Arial, Helvetica, sans-serif;">的最大宽度</span></span>
<span style="font-size:18px;">	        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;
		}
	


}</span><pre name="code" class="java"></span>
 
<span style="font-size:18px;"><span style="font-size:18px;"><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    </span><pre code_snippet_id="1923381" snippet_file_name="blog_20161011_6_7927139" name="code" class="java"><span style="font-size:18px;">//自定义命名空间 后面是res-auto </span><pre code_snippet_id="1923381" snippet_file_name="blog_20161011_7_8276586" name="code" class="java"><span style="font-size:18px;">//xmlns:custom="http://schemas.android.com/apk/res-auto"</span>
 
<com.example.zidingyiview.custom android:layout_width="200dp" android:layout_height="200dp" custom:backg="@drawable/ic_launcher" /></LinearLayout></span> 
 
<span style="font-size:18px;"><?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable
        name="myview" >

        <attr name="backg" format="reference"/>
        </declare-styleable>
</resources>
</span></span>
//在values下新建的attrs.xml

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值