热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Android笔记: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);
    }
    
}













推荐阅读
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文讲述了如何通过代码在Android中更改Recycler视图项的背景颜色。通过在onBindViewHolder方法中设置条件判断,可以实现根据条件改变背景颜色的效果。同时,还介绍了如何修改底部边框颜色以及提供了RecyclerView Fragment layout.xml和项目布局文件的示例代码。 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • 带添加按钮的GridView,item的删除事件
    先上图片效果;gridView无数据时显示添加按钮,有数据时,第一格显示添加按钮,后面显示数据:布局文件:addr_manage.xml<?xmlve ... [详细]
  • 微信小程序导航跟随的实现方法
    本文介绍了在微信小程序中实现导航跟随的方法。通过设置导航的position属性和绑定滚动事件,可以实现页面向下滚动到导航位置时,导航固定在页面最上方;页面向上滚动到导航位置时,导航恢复到原始位置;点击导航可以平滑跳转到相应位置。代码示例也给出了具体实现方法。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • Oracle seg,V$TEMPSEG_USAGE与Oracle排序的关系及使用方法
    本文介绍了Oracle seg,V$TEMPSEG_USAGE与Oracle排序之间的关系,V$TEMPSEG_USAGE是V_$SORT_USAGE的同义词,通过查询dba_objects和dba_synonyms视图可以了解到它们的详细信息。同时,还探讨了V$TEMPSEG_USAGE的使用方法。 ... [详细]
  • 突破MIUI14限制,自定义胶囊图标、大图标样式,支持任意APP
    本文介绍了如何突破MIUI14的限制,实现自定义胶囊图标和大图标样式,并支持任意APP。需要一定的动手能力和主题设计师账号权限或者会主题pojie。详细步骤包括应用包名获取、素材制作和封包获取等。 ... [详细]
  • Activiti7流程定义开发笔记
    本文介绍了Activiti7流程定义的开发笔记,包括流程定义的概念、使用activiti-explorer和activiti-eclipse-designer进行建模的方式,以及生成流程图的方法。还介绍了流程定义部署的概念和步骤,包括将bpmn和png文件添加部署到activiti数据库中的方法,以及使用ZIP包进行部署的方式。同时还提到了activiti.cfg.xml文件的作用。 ... [详细]
  • 1简介本文结合数字信号处理课程和Matlab程序设计课程的相关知识,给出了基于Matlab的音乐播放器的总体设计方案,介绍了播放器主要模块的功能,设计与实现方法.我们将该设 ... [详细]
  • 今天就跟大家聊聊有关怎么在Android应用中实现一个换肤功能,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根 ... [详细]
author-avatar
_自己疼__374
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有