Android笔记:SlidingDrawer

一、概述

  抽屉控件,官方已不建议用;但在某些需求下直接使用这个控件还是相当方便的。


<SlidingDrawer
    android:id="@+id/drawer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
     android:handle="@+id/handle"
    android:content="@+id/content">
     <ImageView
        android:id="@+id/handle"
        android:layout_width="88dip"
        android:layout_height="44dip" />
     <GridView
        android:id="@+id/content"
         android:layout_width="match_parent"
        android:layout_height="match_parent" />
 </SlidingDrawer>

1.XML文件中的属性


属性名称


描述


android:allowSingleTap


是否可通过单击handle打开或关闭抽屉。 默认是true。(如果是false,用户必须通过拖动,滑动或者使用轨迹球。)


android:animateOnClick


顾名思义,点击的时候是否有动画。默认是true。


android:bottomOffset


“手柄”距离SlidingDrawer底部的额外距离 。


android:content


SlidingDrawer的内容。


android:handle


SlidingDrawer的“手柄”。


android:orientation


SlidingDrawer的方向。


android:topOffset


“手柄”距离SlidingDrawer顶部的额外距离 。

 

2.一些重要的方法:

void setOnDrawerCloseListener (SlidingDrawer.OnDrawerCloseListener onDrawerCloseListener)

设置一个监听器,用来接收当抽屉被关闭时候的通知。

void setOnDrawerOpenListener (SlidingDrawer.OnDrawerOpenListener onDrawerOpenListener)

Since: API Level 3

设置一个监听器,用来接收当抽屉被打开的时候的通知。

void setOnDrawerScrollListener (SlidingDrawer.OnDrawerScrollListener onDrawerScrollListener)

设置一个监听器,用来接收当抽屉处于正在打开或者正在结束的滚动时候的通知。

animateClose():

使用动画关闭抽屉。

animateOpen ():

使用动画打开抽屉

getContent():

获取内容

isMoving():

指示SlidingDrawer是否在移动。

isOpened():

指示SlidingDrawer是否已全部打开

lock():

屏蔽触摸事件。

unlock():

解除屏蔽触摸事件。

toggle():

切换打开和关闭的抽屉SlidingDrawer。

3.一个简单的例子:

public class SlidingDrawerDemoActivity extends Activity {  
            private SlidingDrawer myDrawer;
            private ImageView myImageView;
            private GridView myGridView;
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.main);
                myDrawer = (SlidingDrawer) findViewById(R.id.drawer);
                myImageView = (ImageView)findViewById(R.id.handle);
                myGridView = (GridView)findViewById(R.id.content);
                myDrawer.setOnDrawerOpenListener(newSlidingDrawer.OnDrawerOpenListener() {
                    @Override
                    public void onDrawerOpened() {
                        myImageView.setImageResource(R.drawable.down);
                    }
                });
                myDrawer.setOnDrawerCloseListener(newSlidingDrawer.OnDrawerCloseListener() {
                    @Override
                    public void onDrawerClosed() {
                        myImageView.setImageResource(R.drawable.up);
                    }
                });    
    }
}

二、可监听按钮点击事件的自定义SlidingDrawer

import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SlidingDrawer;

/**
 * 自定义SlidingDrawer:可监听按钮点击事件
 * @author zeng
 *
 */

public class ClickableSlidingDrawer extends SlidingDrawer
{
    private ViewGroup mHandleLayout;
    private final Rect mHitRect = new Rect();
    
    public ClickableSlidingDrawer(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
    }
    
    public ClickableSlidingDrawer(Context context, AttributeSet attrs)
    {
        super(context, attrs);
    }
    
    @Override
    protected void onFinishInflate()
    {
        super.onFinishInflate();
        
        View handle = getHandle();
        
        if (handle instanceof ViewGroup)
        {
            mHandleLayout = (ViewGroup) handle;
        }
    }
    
    @Override
    public boolean onInterceptTouchEvent(MotionEvent event)
    {
        if (mHandleLayout != null)
        {
            int childCount = mHandleLayout.getChildCount();
            int handleClickX = (int) (event.getX() - mHandleLayout.getX());
            int handleClickY = (int) (event.getY() - mHandleLayout.getY());
            
            Rect hitRect = mHitRect;
            
            for (int i = 0; i < childCount; i++)
            {
                View childView = mHandleLayout.getChildAt(i);
                childView.getHitRect(hitRect);
                
                if (hitRect.contains(handleClickX, handleClickY))
                {
                    return false;
                }
            }
        }
        
        return super.onInterceptTouchEvent(event);
    }
}

三、控制SlidingDrawer在屏幕低端,而不会填满整个屏幕,同时handle按钮可点击的自定义SlidingDrawer


注:解决SlidingDrawer的高度设置为wrap_content时无法做到非全屏的问题。

import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SlidingDrawer;

/**
 * 自定义SlidingDrawer,控制SlidingDrawer在屏幕低端,而不会填满整个屏幕,同时handle按钮可点击
 * @author zeng
 *
 */

public class ClickableWrapSlidingDrawer extends SlidingDrawer
{
    private ViewGroup mHandleLayout;
    private final Rect mHitRect = new Rect();
    
    private boolean mVertical;
    private int mTopOffset;
    
    public ClickableWrapSlidingDrawer(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
        int orientation = attrs.getAttributeIntValue("android", "orientation", ORIENTATION_VERTICAL);
        mTopOffset = attrs.getAttributeIntValue("android", "topOffset", 0);
        mVertical = (orientation == SlidingDrawer.ORIENTATION_VERTICAL);
    }
    
    public ClickableWrapSlidingDrawer(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        int orientation = attrs.getAttributeIntValue("android", "orientation", ORIENTATION_VERTICAL);
        mTopOffset = attrs.getAttributeIntValue("android", "topOffset", 0);
        mVertical = (orientation == SlidingDrawer.ORIENTATION_VERTICAL);
    }
    
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
        
        final View handle = getHandle();
        final View content = getContent();
        measureChild(handle, widthMeasureSpec, heightMeasureSpec);
        
        if (mVertical)
        {
            int height = heightSpecSize - handle.getMeasuredHeight() - mTopOffset;
            content.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(height, heightSpecMode));
            heightSpecSize = handle.getMeasuredHeight() + mTopOffset + content.getMeasuredHeight();
            widthSpecSize = content.getMeasuredWidth();
            if (handle.getMeasuredWidth() > widthSpecSize)
                widthSpecSize = handle.getMeasuredWidth();
        }
        else
        {
            int width = widthSpecSize - handle.getMeasuredWidth() - mTopOffset;
            getContent().measure(MeasureSpec.makeMeasureSpec(width, widthSpecMode), heightMeasureSpec);
            widthSpecSize = handle.getMeasuredWidth() + mTopOffset + content.getMeasuredWidth();
            heightSpecSize = content.getMeasuredHeight();
            if (handle.getMeasuredHeight() > heightSpecSize)
                heightSpecSize = handle.getMeasuredHeight();
        }
        
        setMeasuredDimension(widthSpecSize, heightSpecSize);
    }
    
    
    
    
    
    @Override
    protected void onFinishInflate()
    {
        super.onFinishInflate();
        
        View handle = getHandle();
        
        if (handle instanceof ViewGroup)
        {
            mHandleLayout = (ViewGroup) handle;
        }
    }
    
    @Override
    public boolean onInterceptTouchEvent(MotionEvent event)
    {
        if (mHandleLayout != null)
        {
            int childCount = mHandleLayout.getChildCount();
            int handleClickX = (int) (event.getX() - mHandleLayout.getX());
            int handleClickY = (int) (event.getY() - mHandleLayout.getY());
            
            Rect hitRect = mHitRect;
            
            for (int i = 0; i < childCount; i++)
            {
                View childView = mHandleLayout.getChildAt(i);
                childView.getHitRect(hitRect);
                
                if (hitRect.contains(handleClickX, handleClickY))
                {
                    return false;
                }
            }
        }
        
        return super.onInterceptTouchEvent(event);
    }
    
}
时间: 2024-12-24 01:18:46

Android笔记:SlidingDrawer的相关文章

Android笔记之 开机自启动

在项目中用到开机自动运行功能,因此学习了下,在此作为笔记记录下. 主要是以下4个步骤: 1.原理了解: 通过搜查资料发现,当Android启动时,会发出一个系统广播,内容为ACTION_BOOT_COMPLETED,它的字符串常量表示为android.intent.action.BOOT_COMPLETED,因此我们只需要在自己的应用中接收这个广播,然后启动APP即可. 2.编写接收器 既然是接收广播,必然是要用广播接收器,因此新建一个继承自广播BroadcastReceiver的类来专门接收上

android笔记1——开发环境的搭建

Long Long ago...已经成为了历史,我还是要说出一个真相:早年前,那时候,android还不被大众所认知的时候,当然开发者也没不像现在那样趋于饱和状态.一位大牛前辈,也是我的学长,那时候我还在上大学.前辈告诫我有时间得去看看android开发,那时候的自己,年轻.冲动.不畏惧,毅然地选择了java服务端开发,放弃了学习android开发. 时隔数年的今天,因为公司业务项目的发展,我还是得去做android开发工作...虽然这几年间断断续续的看了些android开发,但是将成为历史的今

Android笔记之日期选择器

1.主代码 /** * 日期选择器 */ private DatePickerDialog datePickerDialog; /** * 年 */ private int mYear=1993; /** * 月 */ private int mMonth=12-1; /** * 日 */ private int mDay=16; ......................... //构造函数包括mYear, mMonth, mDay用来显示初始日期,同时设置监听 datePickerDial

Android笔记之标题栏的各种操作

1.改变标题栏的背景颜色 this.setTitleColor(textColor); 2.为页面设置返回键 ActionBar actionBar = getActionBar(); actionBar.setDisplayHomeAsUpEnabled(true); ... @Override public boolean onOptionsItemSelected(MenuItem item) { // TODO Auto-generated method stub switch (ite

Android笔记之 Web Service 基础

一.Web Service是什么? 就是网络服务,根据W3C的定义,WebServices(Web服务)是一个用于支持网络间不同机器互操作的软件系统,它是一种自包含.自描述和模块化的应用程序,它可以在网络中被描述.发布和调用,可以将它看作是基于网络的.分布式的模块化组件.  Web Services是建立在通用协议的基础之上的,包括HTTP.SOAP.UDDI.WSDL等.其中Web Service三要素就是SOAP.WSDL和UDDI. SOAP用来描述传递信息的格式, WSDL用来描述如何访

Android笔记 之 旋转木马的音乐效果

一.前言-- 大家一定在百度音乐上在线听过歌,有没有注意到那个旋转唱片-- 就上面那个,当音乐在播放的时候,那个光碟轮子在转,就想旋转木马一般.感觉好好玩啊. 碰巧想起前阵子做音乐播放器,哎,那这个也可以做在手机的音乐播放器上,这样就代替了进度条了. 一想到,就兴奋,于是,首先画圆形,然后放置背景图片,然后使用动画旋转.当音乐播放时,同时 开始播放圆形图片的动画,当音乐暂停时,暂停旋转:当音乐停止播放时,就停止动画,图片回到原点. 二.效果-- 三.源码-- (1)MainActivity <s

Android笔记:获取url或uri字符串中的参数值

d Uri.parse(mArgUrl).getQueryParameter("id") Android笔记:获取url或uri字符串中的参数值

Android抽屉(SlidingDrawer --类似android通知栏下拉效果)

Android抽屉(SlidingDrawer)的实现发 - 红黑联盟http://www.2cto.com/kf/201301/182507.html 可动态布局的Android抽屉之基础http://blog.csdn.net/hellogv/article/details/6789698 android抽屉实现http://blog.csdn.net/wangkuifeng0118/article/details/7229200 Android 使用动画效果后的控件位置处理 类似系统通知栏

Android笔记:SurfaceView与SurfaceHolder对象

摘要 调试Media播放时,不时用到SurfaceView与SurfaceHolder对象,写case测试及实际运行效果, 基本上搞清楚这两个对象的用法及区别 1.SurfaceView public class SurfaceView extends View SurfaceView是视图(View)的继承类, 这个视图里内嵌了一个专门用于绘制 调试Media播放时,不时用到SurfaceView与SurfaceHolder对象,写case测试及实际运行效果, 基本上搞清楚这两个对象的用法及区