布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"><!-- 一级菜单:最底下的圆形图片和房子的图片 --><RelativeLayout android:layout_width="100dp"android:background="@drawable/level1"     最底下的圆形图片android:layout_alignParentBottom="true"   居于父窗体的底部android:id="@+id/level1"android:layout_centerHorizontal="true"    底部水平居中android:layout_height="50dp"><ImageView android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"  水平和竖直居中android:id="@+id/iv_home"             房子的图片android:background="@drawable/icon_home"/></RelativeLayout><!-- 二级菜单:第二层的环形菜单 --><RelativeLayout android:layout_width="180dp"android:layout_height="90dp"android:id="@+id/level2"android:layout_alignParentBottom="true"   居于父窗体的底部android:layout_centerHorizontal="true"    底部水平居中android:background="@drawable/level2">    第二层环形图片第二层环上的3个图片<ImageView android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_marginBottom="10dp"android:layout_marginLeft="10dp"android:background="@drawable/icon_search"/>   <ImageView android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_alignParentRight="true"android:layout_marginBottom="10dp"android:layout_marginRight="10dp"android:background="@drawable/icon_myyouku"/><ImageView android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="5dp"android:id="@+id/iv_menu"android:background="@drawable/icon_menu"android:layout_centerHorizontal="true"/></RelativeLayout><RelativeLayout android:layout_width="280dp"android:layout_height="142dp"android:id="@+id/level3"android:layout_alignParentBottom="true"android:layout_centerHorizontal="true"android:background="@drawable/level3">    第三层环形图片第三层环上的7个图片<ImageView android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_marginBottom="15dp"android:layout_marginLeft="12dp"android:background="@drawable/channel1"/><ImageView android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_marginBottom="15dp"android:layout_alignParentRight="true"android:layout_marginRight="12dp"android:background="@drawable/channel5"/><ImageView android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_marginBottom="55dp"android:layout_marginLeft="32dp"android:background="@drawable/channel2"/><ImageView android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_alignParentRight="true"android:layout_marginBottom="55dp"android:layout_marginRight="32dp"android:background="@drawable/channel6"/><ImageView android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_marginBottom="85dp"android:layout_marginLeft="62dp"android:background="@drawable/channel3"/><ImageView android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:layout_alignParentBottom="true"android:layout_marginBottom="85dp"android:background="@drawable/channel7"android:layout_marginRight="62dp"/><ImageView android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="5dp"android:layout_centerHorizontal="true"android:background="@drawable/channel4"/></RelativeLayout>
</RelativeLayout>

Activity:

package com.heima52.youkumenu;import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.RelativeLayout;public class MainActivity extends Activity implements OnClickListener{private String tag = MainActivity.class.getSimpleName();private ImageView iv_home,iv_menu;private RelativeLayout level1,level2,level3;private boolean isShowLevel2 = true;//是否显示2级菜单private boolean isShowLevel3 = true;//是否显示3级菜单private boolean isShowMenu = true;//是否显示整个菜单,包括1级,2级,3级的菜单
    @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);initView();initListener();}private void initView() {setContentView(R.layout.activity_main);iv_home = (ImageView) findViewById(R.id.iv_home);//房子图片iv_menu = (ImageView) findViewById(R.id.iv_menu);level1 = (RelativeLayout) findViewById(R.id.level1);level2 = (RelativeLayout) findViewById(R.id.level2);level3 = (RelativeLayout) findViewById(R.id.level3);}private void initListener() {iv_home.setOnClickListener(this);//房子的点击事件iv_menu.setOnClickListener(this);//手机的菜单物理按键
    }@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {if(keyCode==KeyEvent.KEYCODE_MENU){//KEYCODE_MENU是常量82,/*public static final int KEYCODE_HEADSETHOOK     = 79;public static final int KEYCODE_FOCUS           = 80;   public static final int KEYCODE_PLUS            = 81;public static final int KEYCODE_MENU            = 82;public static final int KEYCODE_NOTIFICATION    = 83;public static final int KEYCODE_SEARCH          = 84;public static final int KEYCODE_MEDIA_PLAY_PAUSE= 85;public static final int KEYCODE_MEDIA_STOP      = 86;public static final int KEYCODE_MEDIA_NEXT      = 87;*/if(isShowMenu){//按手机菜单物理按键需要关闭所有菜单int startOffset = 0;if(isShowLevel3){//如果三级菜单是显示状态就隐藏,否则是隐藏就不执行。AnimUtil.closeMenu(level3, startOffset);//关闭动画isShowLevel3 = false;startOffset += 200;}if(isShowLevel2){AnimUtil.closeMenu(level2, startOffset);//关闭动画isShowLevel2 = false;startOffset += 200;}AnimUtil.closeMenu(level1, startOffset);//关闭动画}else {//按手机菜单物理按键需要显示所有菜单AnimUtil.showMenu(level1,0);//打开动画AnimUtil.showMenu(level2,200);//打开动画isShowLevel2 = true;AnimUtil.showMenu(level3,400);//打开动画isShowLevel3 = true;}isShowMenu = !isShowMenu;return true;//我们处理不让别的来处理
        }return super.onKeyDown(keyCode, event);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.iv_home:if(AnimUtil.animCount!=0){//说明有动画正在执行,比如有动画正在关闭则不能在未完全关闭之前又执行打开。return;}if(isShowLevel2){//需要隐藏int startOffset = 0;if(isShowLevel3){AnimUtil.closeMenu(level3,startOffset);startOffset += 200;isShowLevel3 = false;}AnimUtil.closeMenu(level2,startOffset);}else{//需要显示
//                Log.e(tag, "执行显示操作");AnimUtil.showMenu(level2,0);}isShowLevel2 = !isShowLevel2;break;case R.id.iv_menu:if(AnimUtil.animCount!=0){//说明有动画正在执行,比如有动画正在关闭则不能在未完全关闭之前又执行打开。return;}if(isShowLevel3){//隐藏3级菜单AnimUtil.closeMenu(level3,0);}else {//显示3级菜单AnimUtil.showMenu(level3,0);}isShowLevel3 = !isShowLevel3;break;default:break;}}
}

工具:

package com.heima52.youkumenu;import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.RotateAnimation;
import android.widget.RelativeLayout;public class AnimUtil {public static int animCount = 0;//记录当前执行的动画数量//旋转动画的关闭public static void closeMenu(RelativeLayout rl,int startOffset){for (int i = 0; i < rl.getChildCount(); i++) {rl.getChildAt(i).setEnabled(false); //子view设为不可用,//因为原生的旋转和位置动画并没有真正改变view的位置,//View还在,也就是说在View消失后点击空白处还是点到了View上面,//此时让view的enable属性置为false就不能点击了
        }//旋转动画RotateAnimation animation = new RotateAnimation(0, -180,//逆时针旋转,所以角度从0到-180RotateAnimation.RELATIVE_TO_SELF, 0.5f,//旋转中心的X坐标是宽的一半处,RotateAnimation.RELATIVE_TO_SELF, 1);//旋转中心的Y坐标是高度一倍处,animation.setDuration(500);//旋转时间是500毫秒animation.setFillAfter(true);//关闭动画结束后保持关闭的状态否则会又还原成显示状态。animation.setStartOffset(startOffset);//设置延时后执行animation.setAnimationListener(new MyAnimationListener());//设置Animation监听器
        rl.startAnimation(animation);}//旋转动画的打开public static void showMenu(RelativeLayout rl,int startOffset){for (int i = 0; i < rl.getChildCount(); i++) {rl.getChildAt(i).setEnabled(true);//子view设为可用,
        }RotateAnimation animation = new RotateAnimation(-180, 0,//从-180到0RotateAnimation.RELATIVE_TO_SELF, 0.5f,RotateAnimation.RELATIVE_TO_SELF, 1);animation.setDuration(500);animation.setFillAfter(true);//打开动画结束后保持打开的状态,
        animation.setStartOffset(startOffset);animation.setAnimationListener(new MyAnimationListener());rl.startAnimation(animation);}static class MyAnimationListener implements AnimationListener{@Overridepublic void onAnimationStart(Animation animation) {animCount++;}@Overridepublic void onAnimationEnd(Animation animation) {animCount--;}@Overridepublic void onAnimationRepeat(Animation animation) {}}
}

自定义控件:1.组合控件:将系统原生控件组合起来,加上动画效果,形成一种特殊的UI效果。2.纯粹自定义控件:继承自系统的View,自己去实现view效果。安卓中能够实现叠加的只有帧布局和相对布局,安卓中的view的边框都是矩形,没有圆形其他形状的。旋转动画:1,角度,逆时针旋转,    0—— -180,2,旋转基于的点是自身最底部,优酷菜单:1.系统原生的旋转和位置动画并没有真正改变view的位置,View还在,也就是说在View消失后点击空白处还是点到了View上面,此时让view的enable属性置为false就不能点击了。如果是真正改变了位置那么其他相对布局的view的位置就会错乱了。

android115 自定义控件相关推荐

  1. 开发Eclipse自定义控件

    摘自:http://www.ibm.com/developerworks/cn/opensource/os-eclipcntl/ 我们在开发自定义控件时主要考虑以下问题: 1. 自定义控件的绘制:通常 ...

  2. qt获取当前系统音量值_Qt编写自定义控件50-迷你仪表盘

    一.前言 这个控件取名叫迷你仪表盘,是以为该控件可以缩小到很小很小的区域显示,非常适合小面积区域展示仪表数据使用,还可以手动触摸调节进度,是我个人觉得最漂亮小巧的一个控件.初次看到类似的控件是在一个音 ...

  3. 【iOS】自定义控件入门:可拖动的环形进度

    有时候UIKit的标准控件并不能满足我们的需求,因此我们可以通过自定义控件得到满足我们需求的控件,例如这篇文章将教你如何自定义一个圆形的进度条,并且用户可以通过拖动进度条上的手柄来改变进度值.主要参考 ...

  4. Android自定义控件系列之基础篇

    一.概述 在android开发中很多UI控件往往需要进行定制以满足应用的需要或达到更加的效果,接下来就通过一个系列来介绍自定义控件,这里更多是通过一些案例逐步去学习,本系列有一些典型的应用,掌握好了大 ...

  5. C#自定义控件四简易时钟

    C#自定义控件四简易时钟 效果图: 简易时钟,顾名思义,简单容易,简单到什么程度呢?界面只有数字和指针,甚至连与当前时间都不能匹配!呵呵!就这么简单,学习嘛,从简单开始. 毫无疑问,这里肯定要用到Ti ...

  6. 对做C#自定义控件的一点心得

    近期在做DSOFramer这个控件,打算自己弄一个自定义控件来封装这个COM组件,中间遇到很多曲折,研究了一个星期,终于完成了 下面总结一下我做DSOFramer这个自定义控件的注意地方: 1.在创建 ...

  7. ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl

    第四章 组合控件开发CompositeControl 大家好,今天我们来实现一个自定义的控件,之前我们已经知道了,要开发自定义的控件一般继承三个基 类:Control,WebControl,还有一个就 ...

  8. Android自定义控件NumberCircleProgressBar(圆形进度条)的实现

    Android自定义控件NumberCircleProgressBar(圆形进度条)的实现

  9. 创建ASP.NET WEB自定义控件——例程2

    本文通过一段完整的代码向读者介绍复合自定义控件的制作,包括:自定义属性.事件处理.控件间数据传递等方面的技术. 作者在http://damao.0538.org有一些控件和代码,并在更新中,有兴趣的读 ...

最新文章

  1. 如何把一段逗号分割的字符串转换成一个数组?
  2. mysql 节点查根_(三)B数、B+树及在数据库索引中应用
  3. 微型计算机dec al,微机原理复习知识点
  4. Follow My Logic 1048 PKU
  5. MySQL - Found option without preceding group in config file
  6. 【软件开发底层知识修炼】二十八 C/C++中volatile的作用
  7. ASP.NET高级配置Web.config和Machine.Config
  8. Shader实例:NGUI制作网格样式血条
  9. 190120每日一句
  10. Sqoop--全量/增量、导入/导出
  11. QOS中 PQ,CQ.RR,WFQ,CBWFQ,LLQ区分
  12. Win32:三菱FX3U/FX5U读写软元件方法和注意事项
  13. 蓝牙 aptx android,没错,现在蓝牙耳机可以开始谈音质了 高通aptX HD SONY LDAC
  14. 上午小博(java小知识)
  15. 如何看待互联网公司 996 现象,是种什么样的体验?
  16. 腾讯QQ大数据:机器学习建模问题中的特征构造方法
  17. HBCPC2017 C++ 训练题 春游 超级密码
  18. django 类视图装饰器_灵活视图处理的模式,第2部分–使用装饰器
  19. 共享红色理念创业计划书PPT模板
  20. 【Python】批量替换word文档内容python-docx的实现

热门文章

  1. python实现邮件发送功能
  2. Spring Cloud Eureka 最简入门示例
  3. 10.22 Ext JS 快速开发工具
  4. 12.12 带触发器按钮的输入框
  5. Web 端 js 导出csv文件(使用a标签)
  6. mybatis分页插件_MyBatis 分页插件 5.2.0 发布
  7. Java中堆、栈和常量池的区别
  8. MATLAB图像处理之二值化以及灰度处理
  9. C语言程序头文件扩展名为_,c语言程序设计 考试模拟题B.doc
  10. KubeSphere配置集(ConfigMap)的使用