android自定义viewgroup初步之一----抽屉菜单
转载请注明出处 http://blog.csdn.net/wingichoy/article/details/47832151
几天前在慕课网上看到鸿洋老师的 自定义卫星菜单,感觉很有意思,于是看完视频以后,自己也尝试写了一遍,并且添加了可拖拽效果(光看视频是不管用的,一定要自己动手做!切记不要照着抄代码)。
有兴趣的同学可以去慕课网看看(并非广告):http://www.imooc.com/learn/300
自定义控件这个玩意呢,就得考多练,于是又写了一个抽屉效果的菜单,也是比较简单的。
老规矩,先上效果图:
那么中间的圆圈就是卫星菜单拉,而左下角的呢,是抽屉菜单。
下面进入正题:
自定义Viewgroup的一般步骤:
写构造器,重写onMeasure(),重写onLayout();
由于本篇博客是viewgroup初步,故全部从最简单的开始。 我们来讲抽屉菜单。
首先创建DrawerMenu类,使他继承于ViewGroup
public class DrawerMenu extends ViewGroup
然后添加三个构造器,使用一般的方法,少参数的调用多参数的:
public DrawerMenu(Context context) {
this(context, null);
} public DrawerMenu(Context context, AttributeSet attrs) {
this(context, attrs, 0);
} public DrawerMenu(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
一般在第三个构造器里,我们会使用TypedArray来获得他对应attr.xml里面的属性,这里为了简单,不给这个viewgroup添加任何自定义属性,所以构造器这样就可以。
接下来是重写onMeasure()方法。所谓Measure为测量view的大小
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int count = getChildCount();
for (int i = 0; i < count; i++) {
measureChild(getChildAt(i), widthMeasureSpec, heightMeasureSpec);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
测量模式一共分三种,这里也不多介绍了。因为我们的子view都是wrap_content的,所以我们只要简单测量一下即可。
接下来是关键的地方,onLayout(), 此方法是为子view进行布局。告诉子view他应该在什么位置,首先,我们要布局主按钮,这里我们将它固定在左下角:
protected void onLayout(boolean changed, int l, int t, int r, int b) { layoutBottom();
}
private void layoutBottom() {
mButton_buttom = getChildAt(0);
mButton_buttom.setOnClickListener(this);
mWidth_button_buttom = mButton_buttom.getMeasuredWidth();
mHeight_button_buttom = mButton_buttom.getMeasuredHeight();
mButtonX = 0;
mButtonY = getMeasuredHeight() - mHeight_button_buttom;
mButton_buttom.layout(mButtonX, mButtonY, mWidth_button_buttom, getMeasuredHeight());
}
主要的button 是第一个子view 。我们用getChildAt(index=0)来获得, 然后获取得到的测量好的宽和高.
最后将主按钮layout到合适的位置,如图:
layout里面四个参数为画出圆圈地方的x,y
所以 左上角一点的位置为: 0,height - cHeight 右下角的坐标为 cWidth,height
这样我们便确定了主button的位置。
那么接下来当然是去layout 子view的位置了。相信大家也明白了,子view的位置只要找出坐标就好。所以我们这里继续确定子view的位置。
protected void onLayout(boolean changed, int l, int t, int r, int b) {
Log.i("wing", mIsChanged + "");
if (mIsChanged) {
layoutBottom();
int count = getChildCount();
for (int i = 0; i < count - 1; i++) {
View child = getChildAt(i + 1);
int childWidth = child.getMeasuredWidth();
int childHeight = child.getMeasuredHeight();
child.layout(0, mButtonY - mHeight_button_buttom * (i + 1) * 2, childWidth, getMeasuredHeight()); child.setVisibility(GONE); }
}
}
然后我们为主按钮添加监听: 来切换菜单的状态,如果菜单为关闭,那么按下的时候显示按钮,如果为开启,那么将按钮都GONE。
这里为按钮添加了动画效果,如果你还不了解安卓动画,那么看看这里:http://blog.csdn.net/wingichoy/article/details/47104433
为了好看呢,我们给每个动画的duration加了 i*100的延迟来有渐变的效果
public void onClick(View v) {
toggleMenu(); }
private void toggleMenu() { if (mIsChanged) {
int count = getChildCount();
for (int i = 0; i < count - 1; i++) {
View child = getChildAt(i + 1);
TranslateAnimation ta = new TranslateAnimation(-child.getMeasuredWidth(), 0, 0, 0);
ta.setDuration(1000 + i * 100);
child.startAnimation(ta);
child.setVisibility(VISIBLE);
mIsChanged = false;
}
} else { int count = getChildCount();
for (int i = 0; i < count - 1; i++) {
View child = getChildAt(i + 1);
TranslateAnimation ta = new TranslateAnimation(0, -child.getMeasuredWidth(), 0, 0);
ta.setDuration(1000 + i * 100);
child.startAnimation(ta);
child.setVisibility(GONE); mIsChanged = true;
}
}
这下我们的viewgroup基本大功告成了。添加到mainactivity的xml上来试试
<com.wingsoft.arcmenu.DrawerMenu
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/drawer"/> <ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/drawer"/> <ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/drawer"/> <ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/drawer"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/drawer"/>
</com.wingsoft.arcmenu.DrawerMenu>
嗯。不错。 样子也实现了。 那么接下来大家动动脑筋,自己写个监听器吧~ 今天就到这里。
如果肯努力,技术很快就赶上来了~~
android自定义viewgroup初步之一----抽屉菜单的更多相关文章
- android自定义viewgroup之我也玩瀑布流
先看效果图吧, 继上一篇<android自定义viewgroup实现等分格子布局>中实现的布局效果,这里稍微有些区别,每个格子的高度不规则,就是传说的瀑布流布局,一般实现这种效果,要么用第 ...
- android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu
示意图就不展示了,和上一节的一样,滑动菜单SlidingMenu效果如何大家都比较熟悉,在这里我简单说明一下用自定义ViewGroup来实现. 实现方法:我们自定义一个ViewGroup实现左右滑动, ...
- android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu[转]
http://blog.csdn.net/jj120522/article/details/8095852 示意图就不展示了,和上一节的一样,滑动菜单SlidingMenu效果如何大家都比较熟悉,在这 ...
- Android 自定义ViewGroup,实现侧方位滑动菜单
侧方位滑动菜单 1.现在adnroid流行的应用当中很多都是用的侧方位滑动菜单如图:
- Android自定义ViewGroup(四、打造自己的布局容器)
转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51500304 本文出自:[openXu的博客] 目录: 简单实现水平排列效果 自定义Layo ...
- Android自定义顶部栏及侧滑菜单和fragment+viewpag滑动切换的实现
嘿嘿嘿,关于android滑动的操作,是不是经常都会用到呢. 我肯定也要学习一下啦. https://blog.csdn.net/u013184970/article/details/82882107 ...
- Android 自定义ViewGroup手把手教你实现ArcMenu
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/37567907 逛eoe发现这样的UI效果,感觉很不错,后来知道github上有这 ...
- Android自定义ViewGroup
视图分类就两类,View和ViewGroup.ViewGroup是View的子类,ViewGroup可以包含所有的View(包括ViewGroup),View只能自我描绘,不能包含其他View. 然而 ...
- Android自定义ViewGroup,实现自动换行
学习<Android开发艺术探索>中自定义ViewGroup章节 自定义ViewGroup总结的知识点 一.自定义ViewGroup中,onMeasure理解 onMeasure(int ...
随机推荐
- move_uploaded_file的failed to open stream错误处理
PHP的基本语法学习的差不多了,现在开始学习PHP的文件上传功能实现了.功能中使用到了move_uploaded_file方法,运行时报错: failed to open stream. 经过查资料, ...
- JVM三种垃圾收集算法思想及发展过程
JVM垃圾收集算法的具体实现有很多种,本文只是介绍实现这些垃圾收集算法的三种思想和发展过程.所有的垃圾收集算法的具体实现都是遵循这三种算法思想而实现的. 1.标记-清除算法 标记-清除(Mark-Sw ...
- Weblogic 12c 负载均衡和session复制
在上一篇,我们介绍了weblogic集群的部署和session的复制,如何将请求负载均衡到这个三个服务器上呢? 这里提供两种方式:(1)weblogic自带的proxy代理 (2) ng ...
- Spring基础配置
从毕业到现在我一直从事Android开发,但是对JavaEE一直念念不忘,毕业校招的时候,一个礼拜拿了三个offer,岗位分别是Android.JavaEE和JavaSE,后来觉得Android比较简 ...
- Intellij IDEA 插件开发之自建插件仓库
Intellij IDEA 有一个自己的官方的插件仓库,但是当我们的开发的 Intellij IDEA 的插件不能够对外公开时,我们就需要搭建自己的 Intellij IDEA 的插件仓库.前不久我们 ...
- maven项目管理
systemPath方式 有些不通用的包,maven仓库没有,只能通过本地包依赖,就像下面方式: 在需要依赖的项目建lib文件夹,如下: 然后在pom.xml项目管理文件里面加入本地依赖,如下 这种情 ...
- gitlab的搭建及问题的解决
gitlab则是类似于github的一个工具,github无法免费建立私有仓库,并且为了代码安全,于是在内网安装了一个自己实验室的一个git服务器,gitlab有很多依赖,而bitnami制作了一键安 ...
- FFmpeg的H.264解码器源代码简单分析:解析器(Parser)部分
===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...
- 4.4、Android Studio在命令行运行Gradle
默认情况下,在你的Gradle构建设置中有两种构建类型:一种是为了调试你的应用,debug类型:一种是构建最终的发布版本,release类型.无论你使用哪种模式,你的app必须在安装到设备或虚拟机中之 ...
- Mpg123源代码详解
Mpg123与libmad一样,支持mpeg1,2,2.5音频解码.目前来看mpg123比libmad支持了网络播放功能.而且libmad基本上开源社区在2005年左右,基本停止更新,mpg123至今 ...