自定义抽屉菜单

           Android App开发过程中,很多时候会遇到系统框架中提供的控件无法满足我们产品的设计需求,那么这时候我们可以选择先Google下有没有比较成熟的开源项目可以让我们用,当然现在Github上面的项目非常丰富,能够满足我们绝不多数的开发需求,但是在使用这些炫酷的第三方控件时,我们也要想一想,我们是不是也可以发挥自己的想象力,动手实现自己想要的控件,尽可能掌控实现的细节!

View绘制过程:

           onDraw()��:  view中onDraw()是个空函数,也就是说具体的视图都要覆写该函数来实现自己的绘制。对于ViewGroup则不需要实现该函数,因为作为容器是“没有内容“的

          ��onLayout()�:    主要是为viewGroup类型布局子视图用的,在View中这个函数为空函数。

          ��onMeasure():��  用于计算视图大小(即长和宽)的方式。

          ��onTouchEvent��  定义触屏事件来响应用户操作。

View:

Android所有的控件都是View或者View的子类,它其实表示的就是屏幕上的一块矩形区域,用一个Rect来表示,left,top表示View相对于它的parent View的起点,width,height表示View自己的宽高,通过这4个字段就能确定View在屏幕上的位置,确定位置后就可以开始绘制View的内容了。

获取屏幕宽度:

Android已经提供DisplayMetircs类可以很方便的获取分辨率。

WindowManager wm = (WindowManager) context�.getSystemService(Context.WINDOW_SERVICE);

�DisplayMetrics outMetrics = new DisplayMetrics();

wm.getDefaultDisplay().getMetrics(outMetrics);

�screenWidth = outMetrics.widthPixels;

自定义属性:

        有时候Android传统的页面布局不足以满足我们的需求,常常需要自己定义view,通常继承View,然后重写构造方法以及onDraw等函数,再具体实现自己定义的复杂view。我们知道在给控件赋属性时,通常使用的是android系统自带的属性,比如 android:layout_height="wrap_content",除此之外,我们亦可以自己定义属性,这样在使用的时候我们就可以使用形

         如 myapp:myTextSize="20sp"的方式了

步骤大致如下:

1》在项目文件res/value下面创建一个attr.xml文件,该文件中包含若干个attr集合,例如:


format还可以指定其他的类型比如;

reference   表示引用,参考某一资源ID

�string   表示字符串

�color   表示颜色值

�dimension   表示尺寸值

�boolean   表示布尔值

�integer   表示整型值

float   表示浮点值

�fraction   表示百分数

enum   表示枚举值


可以看到我们的命名空间:xmlns:zhy="http://schemas.android.com/apk/res/com.example.zhy_slidingmenu" 是http://schemas.android.com/apk/res/加上我们的包名;


   我们在自定义View 时,一般都会用到 �TypedArray obtainStyledAttributes(�AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes);  对于它的前面2个参数可能大家都知道

defStyleAttr 指向当前theme 某个item 描述的style 该style指定了一些默认值为这个TypedArray�defStyleRes  当defStyleAttr 找不到或者为0, 可以直接指定某个style

TypedArray中的函数是获取自定义属性的

获取px像素值:

ta.getDimensionPixelOffset(attr,def)

Dp转px方法

int size = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, context.getResources().getDisplayMetrics());��这里COMPLEX_UNIT_DIP是单位,20是数值,也就是20dp


代码:

  效果图:


适配文件Sliding

package com.example.myslidingmenub;

import android.content.Context;

import android.util.AttributeSet;

import android.util.DisplayMetrics;

import android.util.TypedValue;

import android.view.MotionEvent;

import android.view.ViewGroup;

import android.view.WindowManager;

import android.widget.HorizontalScrollView;

import android.widget.LinearLayout;

public class Slidingitem extends HorizontalScrollView {

//屏幕的宽度

private int screenWidth;

//内容区域的宽度

private int contentWidth;

//菜单的宽度

private int menuWidth;

//菜单一半的宽度

private int halfmenuWidth;

//菜单的右边距

private int rightPading;

private boolean isMesure;

//是否已经打开菜单

private boolean isOpen;

/*

* 当没有使用自定义属性时,调用

* */

public Slidingitem(Context context, AttributeSet attrs) {

super(context, attrs);

// TODO Auto-generated constructor stub

WindowManager wm=(WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

DisplayMetrics outMetrics=new DisplayMetrics();

wm.getDefaultDisplay().getMetrics(outMetrics);

screenWidth=outMetrics.widthPixels;

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

// TODO Auto-generated method stub

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

if(!isMesure){

isMesure=true;//避免mesure方法多次调用

//获取菜单和内容试图

LinearLayout wrapper=(LinearLayout) getChildAt(0);

ViewGroup menu=(ViewGroup) wrapper.getChildAt(0);

ViewGroup content=(ViewGroup) wrapper.getChildAt(1);

//计算右边距100dp转为px

rightPading = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100, content.getResources().getDisplayMetrics());

menuWidth = screenWidth-rightPading;

halfmenuWidth=menuWidth/2;

//给菜单和内容区域设置宽度

menu.getLayoutParams().width=menuWidth;

content.getLayoutParams().width=screenWidth;

}

}

@Override

protected void onLayout(boolean changed, int l, int t, int r, int b) {

// TODO Auto-generated method stub

super.onLayout(changed, l, t, r, b);

if(changed){

this.scrollTo(menuWidth, 0);

}

}

@Override

public boolean onTouchEvent(MotionEvent ev) {

// TODO Auto-generated method stub

switch (ev.getAction()) {

case MotionEvent.ACTION_UP:

//getScrollX()获得划出屏幕左侧的宽度

int scrollx=getScrollX();

if(scrollx>halfmenuWidth){

this.smoothScrollTo(menuWidth, 0);

}else{

this.smoothScrollTo(0, 0);

}

return true;

}

return super.onTouchEvent(ev);

}

public void openDrawer() {

// TODO Auto-generated method stub

if(isOpen){

return;

}

this.smoothScrollTo(0, 0);

isOpen=true;

}

public void close() {

// TODO Auto-generated method stub

if(isOpen){

this.smoothScrollTo(menuWidth, 0);

isOpen=false;

}

}

public void toggle(){

if(isOpen){

close();

}else{

openDrawer();

}

}

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,265评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,078评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,852评论 0 347
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,408评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,445评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,772评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,921评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,688评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,130评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,467评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,617评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,276评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,882评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,740评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,967评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,315评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,486评论 2 348

推荐阅读更多精彩内容