前言

自定义view能够做出很多不同寻常的效果,圆形菜单交互效果不错,目前网上有两个版本,虽然比较庞大,但非常值得研究与学习。

radial-menu-widget: https://code.google.com/p/radial-menu-widget/

Radial-Menu-Widget-Android:https://github.com/strider2023/Radial-Menu-Widget-Android

这两个版本呢实际上第一个是最原始的作者Jason Valestin,后来被Arindam Nath修改后出现了后面的版本。在分析过程中可以逐个击破,关键在于理解要点,本文讲自定义一个圆形的view作为自定义圆形菜单的一个入门基础,暂且命名为CircleView,点击后变化颜色。

源码链接: https://github.com/avenwu/RadialDemo/tree/draw_circle

实现

如果要自定义一个圆形的菜单,那么现有的LinearLayout或者RelativeLayout等都已经无法满足,我们需要从View直接继承,由于需要处理触摸事件,所以需要重载onTouchEvent(),来根据当前触摸的坐标额动作状态调整view

,除此之外需要判断点击的位置出于菜单的可是区域内,在Android中所有的view本质上是矩形区域的,所以需要通过数学计算来判断当前是否点中了菜单,现在我们对这两个关键做类似的实现。

1.初始化画笔菜单位置及大小

在合适的地方初始化资源是很重要的,对画笔和菜单半径等我们可以在构造方法内赋值,

绘制一个圆还需要中心坐标,这个值我们在view的大小确定时初始化,不要尝试直接获取view的高宽,这两个值必须在view绘制后才拿的到,这里我们在onMeasure和onSizeChanged都可以得到view的大小。

2.通过画布绘制菜单

绘制一个圆形比较简单,直接调用canvas的drawCircle方法

3.处理触摸事件

重载onTouchEvent方法我们监听到view上面的触摸动作,一般来说ACTION_DOWN, ACTION_UP, ACTION_MOVE都是比较重要的

我们在点击view的时候更改画笔的颜色为粉红色,当手离开时改回默认的红色,所以可以在ACTION_DOWN时设置color为Color.MAGENTA, 在ACTION_UP时设置为Color.RED

另外在我们按住屏幕后移动位置,这是有可能会移除菜单区域,所以在ACTION_MOVE时我们也需要设置

4.计算触摸位置是否在菜单内

这一步将直接影响我们的触摸效果,这里我们的区域是圆形,所以比较好处理,只需计算触摸点到圆心的距离就可以知道相对位置。

后面当单一圆形菜单分割为多个菜单项时,位置计算会复杂一些。

完整代码:

package com.avenwu.radialdemo;import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;/*** @author chaobin* @date 1/10/14.*/
public class CircleView extends View {private float mCenterX;private float mCenterY;private float mRadius;private Paint mPaint;public CircleView(Context context) {this(context, null);}public CircleView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}private void init() {mRadius = getContext().getResources().getDisplayMetrics().density * 100;mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mPaint.setColor(Color.RED);mPaint.setStrokeWidth(getContext().getResources().getDisplayMetrics().density * 5);}@Overrideprotected void onDraw(Canvas canvas) {canvas.drawCircle(mCenterX, mCenterY, mRadius, mPaint);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int width = MeasureSpec.getSize(widthMeasureSpec) / 2;int height = MeasureSpec.getSize(heightMeasureSpec) / 2;Log.d("CircleView", "onMeasure, height=" + height + ", width=" + width);updateCenter(width, height);}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);Log.d("CircleView", "onSizeChanged: w=" + w + ", h=" + h);updateCenter(w, h);}void updateCenter(int x, int y) {mCenterX = x / 2;mCenterY = y / 2;}boolean isInside(float x, float y) {return Math.pow(x - mCenterX, 2) + Math.pow(y - mCenterY, 2)<= Math.pow(mCenterX - getPaddingLeft(), 2);}@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:if (isInside(event.getX(), event.getY())) {mPaint.setColor(Color.MAGENTA);}break;case MotionEvent.ACTION_UP:mPaint.setColor(Color.RED);break;case MotionEvent.ACTION_MOVE:if (!isInside(event.getX(), event.getY())) {mPaint.setColor(Color.RED);}Log.d("CircleView", "position, x=" + event.getX() + ", y=" + event.getY());break;}invalidate();return true;}}

Android Custom View系列《圆形菜单一》相关推荐

  1. android view 渐变动画,Android自定义view渐变圆形动画

    本文实例为大家分享了Android自定义view渐变圆形动画的具体代码,供大家参考,具体内容如下 直接上效果图 自定义属性 attrs.xml文件 创建一个类 ProgressRing继承自 view ...

  2. Android Custom View --- Circular(环形条)

    Android Custom View - Circular(环形条) 这次是实现一个简单的环形条,下图这样的,还是尽量简单的写,让新手能够看懂 这一次没多少代码,就贴一下核心部分,别的大家可以自己看 ...

  3. Android: Custom View和include标签的区别

    Custom View, 使用的时候是这样的: <com.example.home.alltest.view.MyCustomViewandroid:id="@+id/customVi ...

  4. Android自定义View系列之进度指示控件

    我开通微信公众号啦,如果大家喜欢我的文章,欢迎大家关注我的微信号,我会定期为大家推送Android中的热门知识. 今天为大家介绍另一个自定义View--进度指示器,这个在电商App和支付宝等中经常遇到 ...

  5. Android自定义view,圆形的TextView,并通过xml设置属性,AttributeSet中取值

    Android自定义view设置xml属性 一个圆形的自定义TextView,通过xml来设置背景颜色的属性 values/attrs <declare-styleable name=" ...

  6. android打印动画,Android实用View系列------TextView实现打印机效果

    在审美疲劳的今天,如何能开发出一款应用让用户耳目一新呐,适当的动画特效能为你的APP加分不少,这一点在海外的APP上表现颇为明显.今天为大家带来一篇实用的自定义view,就是是TextView实现文字 ...

  7. android 动态进度条,Android实用view系列------炫酷的进度条

    不知不觉距离上次写文章已经过去大半个月了,原本计划每周写一篇的想法在坚持几周之后最终还是被生活中各种各样的琐事打乱,无奈中夹杂这对自己的一点失望. 心痛.jpg 当初的愿望实现了吗 事到如今只好祭奠吗 ...

  8. android 环绕布局,Android自定义View实现圆形环绕效果

    之前项目中需要实现一个四周环绕中心圆形头像的效果,感觉还是自定义比较方便,于是就自己封装了一个控件去实现.先贴张图显示最终效果. 首先自定义一个View继承自LinearLayout,通过动态添加ch ...

  9. Android自定义滑动进度条,Android自定义View实现圆形水波进度条

    每次听到某大牛谈论自定义View,顿时敬佩之心,如滔滔江水连绵不绝,心想我什么时候能有如此境界,好了,心动不如行动,于是我开始了自定义View之路,虽然过程有坎坷,但是结果我还是挺满意的.我知道大牛还 ...

最新文章

  1. 科学计算机乱码,谁知道我的科学计算器这是怎么了?屏幕一堆乱码,什么都按不了...
  2. 带进度的文件复制 - 回复 冷风无泪 的问题
  3. Android基础 EventBus3 0实用教程
  4. 获取ClassLoader的途径
  5. D7控件\dw_cd_VirtualTreeview_v4.5.2\Demos\Advanced---TVirtualStringTree用法
  6. webpack中package-lock.json的作用
  7. Python+Wind:用 Pyautogui 轻松下载 Wind 数据
  8. 中望3d快捷键命令大全_中望CAD快捷键命令大全
  9. 双稳态继电器工作原理图_常见的继电器及工作原理
  10. 从CentOS官网下载系统镜像详细教程
  11. 荣耀手机如何批量删除日历日程?日历日程提醒便签
  12. 下载微软官方原版系统镜像
  13. html怎样给名片加边框,添加边框和底纹
  14. jquery iframe 父子互操作
  15. 华为AP6050DN配置手册
  16. MySQL 异常错误码使用 及 对照表 DataException
  17. 计算机专业毕业生找工作可考虑的公司官方招聘网站(持续更新ing...)
  18. 人工智能之状态空间表示法的简单应用之翻转三枚钱币
  19. 平面设计培训需要学习多久
  20. [数据结构] python 单链表的创建

热门文章

  1. 2位图灵奖得主、7位院士等一众AI大佬云集共议数字化转型 | CNCC 2021
  2. 人工智能时代,怎样高效关注行业趋势、了解AI技术与落地?
  3. 长征五号复飞成功:史上最重最大,2020月岩采样火星探测都要靠它
  4. 看完阿逗比年度炫技大会,我什么都不敢信了
  5. 华为交换机SSH登录失败原因
  6. JAVA 连接MYSQL数据库操作
  7. python测试代理IP地址
  8. 优化SQLServer--表和索引的分区(二)
  9. 广播搜寻服务器的动态IP
  10. Ado.Net 连接数据库