自定义左下角弧形旋转菜单栏

这里写图片描述

要做这种效果

1- 整个自定义控件其实就是一个ArcMenu .(半圆形那一圈),左下角的图标没有加入进控件中。 
写这个自定义menu.之前有参考 
daCapricorn/ArcMenu

2- 我基于他的类改了点。

  • 他是将左下角的关闭icon都加入到整个自定义menu的layout中的,我是独立出来

  • 我menu中的item添加的思路是首先都给它固定在界面的最左边,往屏幕左边外面便宜半个item的宽度。然后在draw时,将每一个item的位置根据自身的角度,设置rotate值,不但外面要rotate到item本身应该所在的位置(pivot要设置为左下角为原点),它自身也得根据偏移的角度rotate到一个正确的向上的角度。其实在初始化时都给它们偏移过了。

3- 当然现在6.0、7.0上的那些自带效果比我这漂亮多了,不过为了完成设计师给的设计稿,不得不这样写。所以轻喷。

4- 下面po上实现步骤。

a,自定义一个类ArcMenu继承自FrameLayout.重载三个构造方法。

public class ArcMenu extends FrameLayout {
public ArcMenu(Context context) {super(context);}
public ArcMenu(Context context, AttributeSet attrs) {super(context, attrs);}
<span style="font-family: 'microsoft yahei'; background-color: rgb(246, 246, 246);">
</span>
<span style="font-family: 'microsoft yahei'; background-color: rgb(246, 246, 246);">b,重写 onSizeChanged方法,确定控件的高宽,并初始化控件中的一些参数</span>
<span style="font-family: 'microsoft yahei'; background-color: rgb(246, 246, 246);"><img src="data:image/png;base64,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" alt="" />
</span>
<span style="font-family: 'microsoft yahei'; background-color: rgb(246, 246, 246);">
</span>
<span style="font-family: 'microsoft yahei'; background-color: rgb(246, 246, 246);"></span><pre style="font-family: 'Source Code Pro'; background-color: rgb(199, 237, 204);"><span style="font-size:14px;"><span style="color: rgb(0, 0, 128); "><strong>private void </strong></span>init() {

      <span style="color: rgb(0, 0, 128); "><strong>if </strong></span>(!isInEditMode()) {
         <span style="color: rgb(0, 0, 128); "><strong>for </strong></span>(<span style="color: rgb(0, 0, 128); "><strong>int </strong></span>i = <span style="color: rgb(0, 0, 255);">0</span><span style="color: rgb(24, 14, 6);">; </span>i < <span style="color: rgb(102, 14, 122);  "><strong><em>ICON_COUNT</em></strong></span><span style="color: rgb(24, 14, 6);">; </span>i++) {</span>
	   //初始化默认和点击的图片bitmap
            m_iconGrayBitmaps[i] = DrawableManager.instance().getAssetBitmap(s_iconNamePrefixes[i] + "_gray.png");
            m_iconWhiteBitmaps[i] = DrawableManager.instance().getAssetBitmap(s_iconNamePrefixes[i] + "_white.png");
//       m_tangent[i] = Math.tan(90.0f / ICON_COUNT * i);
         }
      }
      m_arcWidth = m_height / 4;//弧形的宽度
//    m_itemIndex = 0;
      m_startDegree = 90.0f / ICON_COUNT / 2; //第一个item初始化时应该待的位置的偏移角度
      m_stepDegree = 90.0f / ICON_COUNT;  //每一个item相对前一个item所偏移的角度

      //新建一个矩形,中心点为左下角

      m_arcRect = new RectF(-(m_width - m_arcWidth / 2), m_arcWidth / 2,
            m_width - m_arcWidth / 2, 2 * m_height - m_arcWidth / 2);

      int shadow_arc_width = Utils.dp2px(SHADOW_ARC_WIDTH);
      m_arcShadow = new RectF(-(m_width - m_arcWidth - shadow_arc_width / 2), m_arcWidth + shadow_arc_width / 2,
            (m_width - m_arcWidth - shadow_arc_width / 2), 2 * m_height - m_arcWidth - shadow_arc_width / 2);

      m_arcbgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
      m_arcbgPaint.setStyle(Paint.Style.STROKE);
      m_arcbgPaint.setStrokeWidth(m_arcWidth);
      m_arcbgPaint.setColor(getResources().getColor(R.color.bg_menu_arc));
      m_arcfgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
      m_arcfgPaint.setStyle(Paint.Style.STROKE);
      m_arcfgPaint.setStrokeWidth(m_arcWidth);
      m_arcfgPaint.setColor(getResources().getColor(R.color.fg_menu_arc));
      m_shadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
      m_shadowPaint.setStyle(Paint.Style.STROKE);
      m_shadowPaint.setStrokeWidth(shadow_arc_width);
      m_shadowPaint.setColor(getResources().getColor(R.color.default_black));

      setOnTouchListener(new OnTouchListener() {
         @Override
         public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
               int index = pointInArc(event.getX(), event.getY());
               if (index >= 0) {
                  Logger.debug("click on icon " + index);
                  m_itemIndex = index;
                  invalidate();
                  m_itemClickedListener.onMenuItemClicked(index);
                  return true;
               }
            }
            return false;
         }
      });
   }
 
 
上面图画错了。。绿色框其实就是外面的m_arcRect
shadowArc其实是 那一层黑色的arc..我懒得再画了。。
</pre><pre name="code" class="java">接下来就是画图了。把那些item要画上去,还得画上这两层弧形
用到dipatchDraw
<pre style="font-family: 'Source Code Pro'; font-size: 9pt; background-color: rgb(199, 237, 204);"><span style="color:#808000;">@Override
</span><span style="color:#000080;"><strong>protected void </strong></span>dispatchDraw(Canvas canvas) {
   Path path = <span style="color:#000080;"><strong>new </strong></span>Path()<span style="color:#180e06;">;
</span><span style="color:#180e06;">   </span><span style="color:#808080;"><em>/// draw out arc
</em></span><span style="color:#808080;"><em>   </em></span>path.arcTo(<span style="color:#660e7a;"><strong>m_arcRect</strong></span><span style="color:#180e06;">, </span><span style="color:#0000ff;">270.0f</span><span style="color:#180e06;">, </span><span style="color:#0000ff;">90.0f</span>)<span style="color:#180e06;">;
</span><span style="color:#180e06;">   </span>canvas.drawPath(path<span style="color:#180e06;">, </span><span style="color:#660e7a;"><strong>m_arcbgPaint</strong></span>)<span style="color:#180e06;">;
</span><span style="color:#180e06;">
</span><span style="color:#180e06;">   </span>canvas.drawArc(<span style="color:#660e7a;"><strong>m_arcRect</strong></span><span style="color:#180e06;">, </span><span style="color:#0000ff;">270.0f </span>+ <span style="color:#660e7a;"><strong>m_stepDegree </strong></span>* <span style="color:#660e7a;"><strong>m_itemIndex</strong></span><span style="color:#180e06;">, </span><span style="color:#660e7a;"><strong>m_stepDegree</strong></span><span style="color:#180e06;">, </span><span style="color:#000080;"><strong>false</strong></span><span style="color:#180e06;">, </span><span style="color:#660e7a;"><strong>m_arcfgPaint</strong></span>)<span style="color:#180e06;">;
</span><span style="color:#180e06;">   </span><span style="color:#808080;"><em>/// draw shadow arc
</em></span><span style="color:#808080;"><em>   </em></span>canvas.drawArc(<span style="color:#660e7a;"><strong>m_arcShadow</strong></span><span style="color:#180e06;">, </span><span style="color:#0000ff;">270.0f</span><span style="color:#180e06;">, </span><span style="color:#0000ff;">90.0f</span><span style="color:#180e06;">, </span><span style="color:#000080;"><strong>false</strong></span><span style="color:#180e06;">, </span><span style="color:#660e7a;"><strong>m_shadowPaint</strong></span>)<span style="color:#180e06;">;
</span><span style="color:#180e06;">
</span><span style="color:#180e06;">   </span><span style="color:#808080;"><em>/// draw bitmaps
</em></span><span style="color:#808080;"><em>   </em></span><span style="color:#000080;"><strong>for </strong></span>(<span style="color:#000080;"><strong>int </strong></span>i = <span style="color:#0000ff;">0</span><span style="color:#180e06;">; </span>i < <span style="color:#660e7a;"><strong><em>ICON_COUNT</em></strong></span><span style="color:#180e06;">; </span>i++) {
      Bitmap bitmap<span style="color:#180e06;">;
</span><span style="color:#180e06;">      </span><span style="color:#000080;"><strong>if </strong></span>(i == <span style="color:#660e7a;"><strong>m_itemIndex</strong></span>) { <span style="color:#808080;"><em>/// selected icon
</em></span><span style="color:#808080;"><em>         </em></span>bitmap = <span style="color:#660e7a;"><strong>m_iconWhiteBitmaps</strong></span>[i]<span style="color:#180e06;">;
</span><span style="color:#180e06;">      </span>} <span style="color:#000080;"><strong>else </strong></span>{    <span style="color:#808080;"><em>/// not selected
</em></span><span style="color:#808080;"><em>         </em></span>bitmap = <span style="color:#660e7a;"><strong>m_iconGrayBitmaps</strong></span>[i]<span style="color:#180e06;">;
</span><span style="color:#180e06;">      </span>}
      <span style="color:#000080;"><strong>if </strong></span>(bitmap != <span style="color:#000080;"><strong>null</strong></span>) {
         Matrix matrix = <span style="color:#000080;"><strong>new </strong></span>Matrix()<span style="color:#180e06;">;
</span><span style="color:#180e06;">         </span>matrix.postTranslate(-bitmap.getWidth() / <span style="color:#0000ff;">2</span><span style="color:#180e06;">, </span>(<span style="color:#660e7a;"><strong>m_arcWidth </strong></span>- bitmap.getHeight()) / <span style="color:#0000ff;">2</span>)<span style="color:#180e06;">;
</span><span style="color:#180e06;">         </span>matrix.postRotate(-<span style="color:#660e7a;"><strong>m_startDegree </strong></span>- <span style="color:#660e7a;"><strong>m_stepDegree </strong></span>* i<span style="color:#180e06;">, </span><span style="color:#0000ff;">0</span><span style="color:#180e06;">, </span><span style="color:#660e7a;"><strong>m_arcWidth </strong></span>/ <span style="color:#0000ff;">2</span>)<span style="color:#180e06;">;
</span><span style="color:#180e06;">         </span>matrix.postRotate(<span style="color:#660e7a;"><strong>m_startDegree </strong></span>+ <span style="color:#660e7a;"><strong>m_stepDegree </strong></span>* i<span style="color:#180e06;">, </span><span style="color:#0000ff;">0</span><span style="color:#180e06;">, </span><span style="color:#660e7a;"><strong>m_height</strong></span>)<span style="color:#180e06;">;
</span><span style="color:#180e06;">         </span>canvas.drawBitmap(bitmap<span style="color:#180e06;">, </span>matrix<span style="color:#180e06;">, </span><span style="color:#000080;"><strong>null</strong></span>)<span style="color:#180e06;">;
</span><span style="color:#180e06;">      </span>}
   }

   <span style="color:#000080;"><strong>super</strong></span>.dispatchDraw(canvas)<span style="color:#180e06;">;
</span>}

 
 
写到这里不知道怎么说了。。干脆贴代码算了。
<pre style="font-family: 'Source Code Pro'; font-size: 9pt; background-color: rgb(199, 237, 204);"><span style="color:#808080;"><em>/**
</em></span><span style="color:#808080;"><em> * check if point (x, y) is within arc icon
</em></span><span style="color:#808080;"><em> *
</em></span><span style="color:#808080;"><em> * </em></span><span style="color:#808080;"><strong><em>@param </em></strong></span><span style="color:#3d3d3d;"><strong><em>x
</em></strong></span><span style="color:#3d3d3d;"><strong><em> </em></strong></span><span style="color:#808080;"><em>* </em></span><span style="color:#808080;"><strong><em>@param </em></strong></span><span style="color:#3d3d3d;"><strong><em>y
</em></strong></span><span style="color:#3d3d3d;"><strong><em> </em></strong></span><span style="color:#808080;"><em>* </em></span><span style="color:#808080;"><strong><em>@return </em></strong></span><span style="color:#808080;"><em>index of the icon clicked, or -1
</em></span><span style="color:#808080;"><em> */
</em></span><span style="color:#000080;"><strong>private int </strong></span>pointInArc(<span style="color:#000080;"><strong>float </strong></span>x<span style="color:#180e06;">, </span><span style="color:#000080;"><strong>float </strong></span>y) {
   <span style="color:#000080;"><strong>float</strong></span>[] pts = {x<span style="color:#180e06;">, </span>y}<span style="color:#180e06;">;
</span><span style="color:#180e06;">   </span><span style="color:#000080;"><strong>float</strong></span>[] target_pts = <span style="color:#000080;"><strong>new float</strong></span>[<span style="color:#0000ff;">2</span>]<span style="color:#180e06;">;
</span><span style="color:#180e06;">   </span>Matrix matrix = <span style="color:#000080;"><strong>new </strong></span>Matrix()<span style="color:#180e06;">;
</span><span style="color:#180e06;">   </span>matrix.postRotate(-<span style="color:#660e7a;"><strong>m_startDegree</strong></span><span style="color:#180e06;">, </span><span style="color:#0000ff;">0</span><span style="color:#180e06;">, </span><span style="color:#660e7a;"><strong>m_height</strong></span>)<span style="color:#180e06;">;
</span><span style="color:#180e06;">   </span><span style="color:#000080;"><strong>for </strong></span>(<span style="color:#000080;"><strong>int </strong></span>i = <span style="color:#0000ff;">0</span><span style="color:#180e06;">; </span>i < <span style="color:#660e7a;"><strong><em>ICON_COUNT</em></strong></span><span style="color:#180e06;">; </span>i++) {
      matrix.mapPoints(target_pts<span style="color:#180e06;">, </span>pts)<span style="color:#180e06;">;
</span><span style="color:#180e06;">      </span><span style="color:#000080;"><strong>if </strong></span>(pointInStartRectOfIcon(target_pts)) {
         <span style="color:#000080;"><strong>return </strong></span>i<span style="color:#180e06;">;
</span><span style="color:#180e06;">      </span>}
      matrix.postRotate(-<span style="color:#660e7a;"><strong>m_stepDegree</strong></span><span style="color:#180e06;">, </span><span style="color:#0000ff;">0</span><span style="color:#180e06;">, </span><span style="color:#660e7a;"><strong>m_height</strong></span>)<span style="color:#180e06;">;
</span><span style="color:#180e06;">   </span>}

   <span style="color:#000080;"><strong>return </strong></span>-<span style="color:#0000ff;">1</span><span style="color:#180e06;">;
</span>}

<span style="color:#808080;"><em>/**
</em></span><span style="color:#808080;"><em> * check if (target_pts[0], target_pts[1]) is in the start position of icons
</em></span><span style="color:#808080;"><em> *
</em></span><span style="color:#808080;"><em> * </em></span><span style="color:#808080;"><strong><em>@param </em></strong></span><span style="color:#3d3d3d;"><strong><em>target_pts
</em></strong></span><span style="color:#3d3d3d;"><strong><em> </em></strong></span><span style="color:#808080;"><em>* </em></span><span style="color:#808080;"><strong><em>@return
</em></strong></span><span style="color:#808080;"><strong><em> </em></strong></span><span style="color:#808080;"><em>*/
</em></span><span style="color:#000080;"><strong>private boolean </strong></span>pointInStartRectOfIcon(<span style="color:#000080;"><strong>float</strong></span>[] target_pts) {
   <span style="color:#000080;"><strong>return </strong></span>target_pts[<span style="color:#0000ff;">0</span>] > -<span style="color:#660e7a;"><strong>m_arcWidth </strong></span>/ <span style="color:#0000ff;">2 </span>&& target_pts[<span style="color:#0000ff;">0</span>] < <span style="color:#660e7a;"><strong>m_arcWidth </strong></span>/ <span style="color:#0000ff;">2
</span><span style="color:#0000ff;">          </span>&& target_pts[<span style="color:#0000ff;">1</span>] > <span style="color:#0000ff;">0 </span>&& target_pts[<span style="color:#0000ff;">1</span>] < <span style="color:#660e7a;"><strong>m_arcWidth</strong></span><span style="color:#180e06;">;
</span>}
/**
 * Sets the click listener for menu items.
 */
public void setOnItemClickedListener(ArcMenuItemClickedListener itemClickedListener) {
   this.m_itemClickedListener = itemClickedListener;
}

public void setSelectedIcon(int index, boolean bInvalidate) {
   m_itemIndex = index;
   if(bInvalidate) {
      invalidate();
   }
}
就酱吧。。。写个博客烦球死。。
 
 
</pre><pre name="code" class="java">..

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值