注册

Android自定义控件六边形



Android自定义六边形控件

一.效果图

原文地址: https://blog.csdn.net/oMengHui/article/details/45540645

20150506195536825.gif

二.核心算法
平面内一个坐标点是否在多边形内判断,使用射线法判断。从目标点出发引一条射线,看这条射线和多边形所有边的交点数目。如果是奇数个交点,则说明点在多边形内部;如果是偶数个交点,则说明在外部。

20150506195740393.jpeg

算法图解:

20150506195748111.jpeg

参考代码:

int pnpoly(int nvert, float *vertx, float *verty, float testx, float testy)
{
int i, j, c = 0;
for (i = 0, j = nvert-1; i < nvert; j = i++)
{
if ( ((verty[i]>testy) != (verty[j]>testy)) &&
(testx < (vertx[j]-vertx[i]) * (testy-verty[i]) / (verty[j]-verty[i]) + vertx[i]) )
c = !c;
}
return c;
}
复制代码

更多参考信息

三.知识点
1.控件属性自定义和使用 在values->attrs->declare-styleable中定义属性;在布局中引入(格式xmls:sec=”schemas.android.com/apk/res/程序包…;

2.Paint画笔使用 class继承View后重写onDraw方法,Paint paint=new Paint().setStyle(Style.FILL); canvas.drawText(“Hello”,x,y,paint);

3.Path路径使用 Path path=new Path(); path.moveTo(x1,y1); path.lineTo(x2,y2); path.close(); canvas.drawPath(path,paint);

4.图片缩放平铺居中 六边形视图显示为正方形,如属性设置图片宽高不相等直接使用图片会被拉伸变形。通过逻辑处理以图片宽高较小值居中裁剪图片。

 /**
* 按宽/高缩放图片到指定大小并进行裁剪得到中间部分图片
*
* @param bitmap 源bitmap
* @param w 缩放后指定的宽度
* @param h 缩放后指定的高度
* @return 缩放后的中间部分图片
*/
public static Bitmap zoomBitmap(Bitmap bitmap, int w, int h) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
float scaleWidht, scaleHeight, x, y;
Bitmap newbmp;
Matrix matrix = new Matrix();
if (width > height) {
scaleWidht = ((float) h / height);
scaleHeight = ((float) h / height);
x = (width - w * height / h) / 2;// 获取bitmap源文件中x做表需要偏移的像数大小
y = 0;
} else if (width < height) {
scaleWidht = ((float) w / width);
scaleHeight = ((float) w / width);
x = 0;
y = (height - h * width / w) / 2;// 获取bitmap源文件中y做表需要偏移的像数大小
} else {
scaleWidht = ((float) w / width);
scaleHeight = ((float) w / width);
x = 0;
y = 0;
}
matrix.postScale(scaleWidht, scaleHeight);
try {
newbmp = Bitmap.createBitmap(bitmap, (int) x, (int) y,
(int) (width - x), (int) (height - y), matrix, true);// createBitmap()方法中定义的参数x+width要小于或等于bitmap.getWidth(),y+height要小于或等于bitmap.getHeight()
} catch (Exception e) {
e.printStackTrace();
return null;
}
return newbmp;
}
复制代码

5.动画(ScaleAnimation)

Animation scaleAnimation = new ScaleAnimation(start, end, start, end,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
scaleAnimation.setDuration(30);
scaleAnimation.setFillAfter(true);
this.startAnimation(endAnimation);
复制代码

6.监听实现

HexagonView.java ->
public interface OnHexagonViewClickListener {
public void onClick(View view);
}
public void setOnHexagonClickListener(OnHexagonViewClickListener listener) {
this.listener = listener;
}
OnHexagonViewClickListener hexagonListener=new OnHexagonViewClickListener();//实例化
/**
*系统onTouchEvent
*/
public boolean onTouchEvent(MotionEvent event){
if(!isOn){//未点中六边形
break;
}
switch(event.getAction()){
case MotionEvent.ACTION_UP:
if(hexagonListener!=null){
hexagonListener.click(this);
}
break;
}
}

MainActivity->
public class MainActivity extends Activity implements HexagonView.OnHexagonViewClickListener{
HexagonView hexagonViewHello;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
hexagonViewHello=(HexagonView)this.findViewById(R.id.hexagonviewhello);
hexagonViewHello.setOnHexagonClickListener(this);
}
/**
* 事件监听
*/
public void onClick(View view){
Log.d(TAG,"onClick()");
switch (view.getId()){
case R.id.hexagonviewhello:
Toast.makeText(this,"Hello",Toast.LENGTH_SHORT).show();
break;
}
}

}

0 个评论

要回复文章请先登录注册