自定义椭圆控制界面
来源:互联网 发布:抽象工厂模式 java 编辑:程序博客网 时间:2024/04/25 20:18
其它的先不说,我们先看看效果图,如下:
这东西,其实不难,就是要计算各个点的位置是比较蛋疼的,还有一个地方就是画扇形的时候,不知道为什么得不到我想要的效果,具体描述,可以看我的代码:
package com.example.a;import android.annotation.SuppressLint;import android.content.Context;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.RectF;import android.graphics.Paint.Style;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.view.View.OnTouchListener;/** * 一个椭圆分区的按钮集界面,没有写成控件的形式,毕竟自定义这东西,还是得按照项目需求来 * * @author zhoudailiang * @since 2015-3-24 17:49 */public class ShapeView extends View implements OnTouchListener{private int radius = 40; // 中间小圆的半径private Paint mPaint;private RectF oval;private int width, height;private boolean top, right, bottom, left, center;private ShapeViewListener onShapListener;//回调,进行各个部分的事件监听public interface ShapeViewListener {public void onTopListener();public void onRightListener();public void onBottomListener();public void onLeftListener();public void onCenterListener();}public void setOnShapeListener(ShapeViewListener onShapListener) {this.onShapListener = onShapListener;}public ShapeView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}public ShapeView(Context context, AttributeSet attrs) {super(context, attrs);init();}public ShapeView(Context context) {super(context);init();}private void init() {mPaint = new Paint();//设置背景为天蓝色setBackgroundColor(0xFF436EEE);setOnTouchListener(this);}@SuppressLint("DrawAllocation")@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);//得到布局的宽度width = this.getMeasuredWidth();height = 2 * width / 3;//画椭圆的矩形区域oval = new RectF(5, 5, width - 5, height - 5);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);mPaint.setStrokeWidth(2);mPaint.setAntiAlias(true);mPaint.setStyle(Style.STROKE);mPaint.setColor(0xffffffff);canvas.drawArc(oval, 0, 360, false, mPaint);canvas.drawCircle(width / 2, height / 2, radius, mPaint);if (center) {mPaint.setStyle(Style.FILL);mPaint.setColor(0xaaffffff);canvas.drawCircle(width / 2, height / 2, radius, mPaint);}//下面这里的扇形范围-56, 112是我调试出来的,MD,不知道为什么-45, 90这样的写法就是有问题,//各位看官,如果知道为什么,还望不吝指教if (right) {mPaint.setStyle(Style.FILL);mPaint.setColor(0xaaffffff);canvas.drawArc(oval, -56, 112, true, mPaint);}if (bottom) {mPaint.setStyle(Style.FILL);mPaint.setColor(0xaaffffff);canvas.drawArc(oval, 57, 66, true, mPaint);}if (left) {mPaint.setStyle(Style.FILL);mPaint.setColor(0xaaffffff);canvas.drawArc(oval, 124, 112, true, mPaint);}if (top) {mPaint.setStyle(Style.FILL);mPaint.setColor(0xaaffffff);canvas.drawArc(oval, 237, 66, true, mPaint);}//如果上下左右被按了,为了中间的部分不显示,这里画圆遮住了那部分白色if (right || top || bottom || left) {mPaint.setStyle(Style.FILL);mPaint.setColor(0xFF436EEE);canvas.drawCircle(width / 2, height / 2, 38, mPaint);}mPaint.setStyle(Style.STROKE);mPaint.setColor(0xffffffff);mPaint.setStrokeWidth(1);mPaint.setAlpha(100);//根据标准椭圆公式,求得的一个量,我们这里只用再进行坐标变换,就可以得到四个在椭圆上的点了float t = getCoordinate(width - 10, height - 10);//四条区域分割线的起始坐标float[] pts = {width / 2 + getSF(radius), height / 2 + getSF(radius), width / 2 + t, height / 2 + t,width / 2 - getSF(radius), height / 2 + getSF(radius), width / 2 - t, height / 2 + t,width / 2 + getSF(radius), height / 2 - getSF(radius), width / 2 + t, height / 2 - t,width / 2 - getSF(radius), height / 2 - getSF(radius), width / 2 - t, height / 2 - t};canvas.drawLines(pts, mPaint);}private float getCoordinate(int w, int h) {return (float) ((w * h) / (Math.sqrt(w*w + h*h) * 2));}/** 得到圆形的直角边的长度 */private float getSF(int a) {return (float) (a / Math.sqrt(2));}@Overridepublic boolean onTouch(View v, MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:float x = event.getX();float y = event.getY();//不在椭圆内,什么处理都不做if (!isInOval(x, y)) {return false;}if (isInCricle(x,y)) {center = true;if (onShapListener != null) {onShapListener.onCenterListener();}} else {float a = x - y - (width - height) / 2;float b = x + y - (width + height) / 2;if (a > 0) {if (b > 0) {right = true;if (onShapListener != null) {onShapListener.onRightListener();}} else {top = true;if (onShapListener != null) {onShapListener.onTopListener();}}} else {if (b > 0) {bottom = true;if (onShapListener != null) {onShapListener.onBottomListener();}} else {left = true;if (onShapListener != null) {onShapListener.onLeftListener();}}}}invalidate();break;case MotionEvent.ACTION_UP:top = false;right = false;bottom = false;left = false;center = false;invalidate();break;}return true;}/** (x, y)是否在椭圆内部 */private boolean isInOval(float x, float y) {float tmp = (2*x/width - 1) * (2*x/width - 1) + (2*y/height - 1) * (2*y/height - 1);if (tmp <= 1) {return true;} else {return false;}}/** (x, y)是否在中间圆里面 */private boolean isInCricle(float x, float y) {float tmp = (x - width/2) * (x - width/2) + (y - height/2) * (y - height/2);if (tmp <= radius * radius) {return true;} else {return false;}}}
这里是调用的代码:
private ShapeView.ShapeViewListener listener;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);ShapeView view = new ShapeView(this);FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);view.setLayoutParams(lp);setContentView(view);listener = new ShapeView.ShapeViewListener() {@Overridepublic void onTopListener() {show("top");}@Overridepublic void onRightListener() {show("right");}@Overridepublic void onLeftListener() {show("left");}@Overridepublic void onCenterListener() {show("center");}@Overridepublic void onBottomListener() {show("bottom");}};view.setOnShapeListener(listener);}
上面的show函数,是一个封装了的Toast显示。
OK,这篇文章结束了。
0 1
- 自定义椭圆控制界面
- Android中的UI界面控制方式和自定义View
- 自定义view-使用xml控制界面的呈现
- 椭圆
- 自定义Button形状(圆形、椭圆)
- 自定义Button形状(圆形、椭圆)
- 自定义Button形状(圆形、椭圆)
- 自定义Button形状(圆形、椭圆) shape
- 自定义ImageView圆角,椭圆,圆形图片
- 实现自定义图片View圆形、圆角,椭圆
- cocos2dx 实现图片椭圆旋转选择物品界面
- unity3d5.1物体椭圆旋转选择界面实现(一)
- unity3d5.1物体椭圆旋转选择界面实现(二)
- 按键控制移动的椭圆GDI绘图时,画椭圆没有清除上次的痕迹
- <Linux+Qt>Qt4编程控制mplayer嵌入自定义界面监控或视频显示
- Android 左右椭圆形状的ProgressBar 的自定义实现
- 自定义圆形图片、圆角图片,椭圆图片
- 自定义View之圆形圆角椭圆进度条等
- A8U公司的老程序猿的悲惨下场
- mac os 配置web 服务器
- 常用的几个代码
- C#概述
- 第五章 模式匹配
- 自定义椭圆控制界面
- URAL - 1586 Threeprime Numbers
- 第六章 子过程 和子过程引用
- TortoiseSVN checkout 之后图标(绿色勾之类的)没有显示出来的问题
- 如何成为优秀开发人员
- C语言初学 测定数据类型长度
- What Is Key-Value Coding?
- ant打包所遇到问题(外导library项目包)
- JS下拉菜单