- 浏览: 335387 次
最新评论
-
ax003d:
你好,我使用这种方法,在gridview里显示图片,当图片数量 ...
ScrollView嵌套GridView、ListView的解决办法 -
yunzhu:
Firefox下有Xmarks书签同步插件,很好用,可以方便地 ...
开发人员应该具备的工具----欲善其事,先利其器 -
mjlixm:
Android入门:ContentProvider 学习了! ...
Android入门:ContentProvider -
bluesky329:
很好收益匪浅!
一个软件工程师的经验之谈 -
qinglongyun:
每天工作4小时的程序员
本文来自http://blog.csdn.net/hellogv/ ,欢迎转摘,引用必须注明出处!
上次介绍了基础篇,讲解了自定义抽屉控件的基础实现,这次就在基础篇的基础上加入拖拉功能。拖拉功能基于GestureDetector,GestureDetector的基本使用方式不是本文介绍的重点,有兴趣的童鞋可以上网查询相关的教程。
本文的抽屉控件相对于基础篇的抽屉控件多了以下功能:
1.支持手势拖拉
2.拖拉到一半时,可以自动展开或者收缩。
具体如下图:
本文的源码可以到这里下载:http://download.csdn.net/detail/hellogv/3642418
只贴出抽屉组件的源码,其他源文件与基础篇的一样:
- <span style="font-family:Comic Sans MS;font-size:18px;">public class Panel extends LinearLayout implements GestureDetector.OnGestureListener{
- public interface PanelClosedEvent {
- void onPanelClosed(View panel);
- }
- public interface PanelOpenedEvent {
- void onPanelOpened(View panel);
- }
- private final static int HANDLE_WIDTH=30;
- private final static int MOVE_WIDTH=20;
- private Button btnHandler;
- private LinearLayout panelContainer;
- private int mRightMargin=0;
- private Context mContext;
- private GestureDetector mGestureDetector;
- private boolean mIsScrolling=false;
- private float mScrollX;
- private PanelClosedEvent panelClosedEvent=null;
- private PanelOpenedEvent panelOpenedEvent=null;
- public Panel(Context context,View otherView,int width,int height) {
- super(context);
- this.mContext=context;
- //定义手势识别
- mGestureDetector = new GestureDetector(mContext,this);
- mGestureDetector.setIsLongpressEnabled(false);
- //改变Panel附近组件的属性
- LayoutParams otherLP=(LayoutParams) otherView.getLayoutParams();
- otherLP.weight=1;
- otherView.setLayoutParams(otherLP);
- //设置Panel本身的属性
- LayoutParams lp=new LayoutParams(width, height);
- lp.rightMargin=-lp.width+HANDLE_WIDTH;
- mRightMargin=Math.abs(lp.rightMargin);
- this.setLayoutParams(lp);
- this.setOrientation(LinearLayout.HORIZONTAL);
- //设置Handler的属性
- btnHandler=new Button(context);
- btnHandler.setLayoutParams(new LayoutParams(HANDLE_WIDTH,height));
- //btnHandler.setOnClickListener(handlerClickEvent);
- btnHandler.setOnTouchListener(handlerTouchEvent);
- this.addView(btnHandler);
- //设置Container的属性
- panelContainer=new LinearLayout(context);
- panelContainer.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
- LayoutParams.FILL_PARENT));
- this.addView(panelContainer);
- }
- private View.OnTouchListener handlerTouchEvent=new View.OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- if(event.getAction()==MotionEvent.ACTION_UP && //onScroll时的ACTION_UP
- mIsScrolling==true)
- {
- LayoutParams lp=(LayoutParams) Panel.this.getLayoutParams();
- if (lp.rightMargin >= (-mRightMargin/2)) {//往左超过一半
- new AsynMove().execute(new Integer[] { MOVE_WIDTH });// 正数展开
- }
- else if (lp.rightMargin < (-mRightMargin/2)) {//往右拖拉
- new AsynMove().execute(new Integer[] { -MOVE_WIDTH });// 负数收缩
- }
- }
- return mGestureDetector.onTouchEvent(event);
- }
- };
- /**
- * 定义收缩时的回调函数
- * @param event
- */
- public void setPanelClosedEvent(PanelClosedEvent event)
- {
- this.panelClosedEvent=event;
- }
- /**
- * 定义展开时的回调函数
- * @param event
- */
- public void setPanelOpenedEvent(PanelOpenedEvent event)
- {
- this.panelOpenedEvent=event;
- }
- /**
- * 把View放在Panel的Container
- * @param v
- */
- public void fillPanelContainer(View v)
- {
- panelContainer.addView(v);
- }
- /**
- * 异步移动Panel
- * @author hellogv
- */
- class AsynMove extends AsyncTask<Integer, Integer, Void> {
- @Override
- protected Void doInBackground(Integer... params) {
- int times;
- if (mRightMargin % Math.abs(params[0]) == 0)// 整除
- times = mRightMargin / Math.abs(params[0]);
- else
- // 有余数
- times = mRightMargin / Math.abs(params[0]) + 1;
- for (int i = 0; i < times; i++) {
- publishProgress(params);
- try {
- Thread.sleep(Math.abs(params[0]));
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- return null;
- }
- @Override
- protected void onProgressUpdate(Integer... params) {
- LayoutParams lp = (LayoutParams) Panel.this.getLayoutParams();
- if (params[0] < 0)
- lp.rightMargin = Math.max(lp.rightMargin + params[0],
- (-mRightMargin));
- else
- lp.rightMargin = Math.min(lp.rightMargin + params[0], 0);
- if(lp.rightMargin==0 && panelOpenedEvent!=null){//展开之后
- panelOpenedEvent.onPanelOpened(Panel.this);//调用OPEN回调函数
- }
- else if(lp.rightMargin==-(mRightMargin) && panelClosedEvent!=null){//收缩之后
- panelClosedEvent.onPanelClosed(Panel.this);//调用CLOSE回调函数
- }
- Panel.this.setLayoutParams(lp);
- }
- }
- @Override
- public boolean onDown(MotionEvent e) {
- mScrollX=0;
- mIsScrolling=false;
- return false;
- }
- @Override
- public boolean onSingleTapUp(MotionEvent e) {
- LayoutParams lp = (LayoutParams) Panel.this.getLayoutParams();
- if (lp.rightMargin < 0)// CLOSE的状态
- new AsynMove().execute(new Integer[] { MOVE_WIDTH });// 正数展开
- else if (lp.rightMargin >= 0)// OPEN的状态
- new AsynMove().execute(new Integer[] { -MOVE_WIDTH });// 负数收缩
- return false;
- }
- @Override
- public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
- float distanceY) {
- mIsScrolling=true;
- mScrollX+=distanceX;
- LayoutParams lp=(LayoutParams) Panel.this.getLayoutParams();
- if (lp.rightMargin < -1 && mScrollX > 0) {//往左拖拉
- lp.rightMargin = Math.min((lp.rightMargin + (int) mScrollX),0);
- Panel.this.setLayoutParams(lp);
- Log.e("onScroll",lp.rightMargin+"");
- }
- else if (lp.rightMargin > -(mRightMargin) && mScrollX < 0) {//往右拖拉
- lp.rightMargin = Math.max((lp.rightMargin + (int) mScrollX),-mRightMargin);
- Panel.this.setLayoutParams(lp);
- }
- if(lp.rightMargin==0 && panelOpenedEvent!=null){//展开之后
- panelOpenedEvent.onPanelOpened(Panel.this);//调用OPEN回调函数
- }
- else if(lp.rightMargin==-(mRightMargin) && panelClosedEvent!=null){//收缩之后
- panelClosedEvent.onPanelClosed(Panel.this);//调用CLOSE回调函数
- }
- Log.e("onScroll",lp.rightMargin+"");
- return false;
- }
- @Override
- public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
- float velocityY) {return false;}
- @Override
- public void onLongPress(MotionEvent e) {}
- @Override
- public void onShowPress(MotionEvent e) {}
- }
- </span>
发表评论
-
Android入门:ContentProvider
2012-07-02 00:06 1978一、ContentProvider介绍 Cont ... -
Android入门:监听ContentProvider数据改变
2012-07-02 00:06 1438一、监听ContentProvider主要步骤 1 ... -
android 使用广播接收者监听短信和拦截外拨电话
2012-06-27 23:31 2217如果你想监听自己或者别人接收到的短信,设置黑名单等功能, ... -
android 广播接收者--BroadcastReceiver
2012-06-27 23:30 3568BroadcastReceiver初识: ... -
一个项目只使用一个Activity初探
2012-06-27 23:29 995提供一个简单案例: 1,新建一个项目 修改和添加 ... -
android 之访问WebService显示手机号码归属地
2012-06-27 23:27 1486发送XML 通过URL封装路径打开一个HttpURLC ... -
Android开发从入门到精通(8) _9
2012-04-24 21:45 2477Spinner 第八章(9) 在本节中将为Spinne ... -
Android开发从入门到精通(8) _8
2012-04-24 21:44 993RadioGroup 第八章(8) 在本章中将为Rad ... -
Android开发从入门到精通(8) _7
2012-04-24 21:43 984EditText 第八章(7) 在本节中,和上一节很类 ... -
Android开发从入门到精通(8) _6
2012-04-24 21:43 870CheckBox 第八章(6) 在本节中,将为Chec ... -
Android开发从入门到精通(8) _5
2012-04-24 21:42 904按钮 第八章(5) 看看下面的代码。这段代码代表了四个 ... -
Android开发从入门到精通(8) _4
2012-04-23 22:18 1084为AutoComplete创建一个 ... -
Android开发从入门到精通(8) _3
2012-04-23 22:17 1205使用菜单 第八章(3) 在本节中,你将建造一个应用 ... -
Android开发从入门到精通(8) _2
2012-04-23 22:17 1113修改AndroidManifest.xml文件 第八章( ... -
Android开发从入门到精通(8) _1
2012-04-23 22:16 907列表,菜单和其它Views 第八章(1) 关键技能 & ... -
Android开发从入门到精通(7) _8
2012-04-23 22:16 1113试试这个:修改AndoridPhoneDialer项目 ... -
Android开发从入门到精通(7) _7
2012-04-22 15:14 1005执行一个EditText View 第七章(7) ... -
Android开发从入门到精通(7) _6
2012-04-22 15:13 1153修改AndroidPhoneDialer 第七章(6) ... -
Android开发从入门到精通(7) _5
2012-04-22 15:13 929编辑活动许可 第七章(5) 大多数的Activit ... -
Android开发从入门到精通(7) _4
2012-04-22 15:12 1022在本节中你将会 ...
相关推荐
本篇将深入探讨如何创建一个可动态布局的Android抽屉组件,提供一个完整的实现案例源码。 首先,抽屉组件的基本概念:DrawerLayout是Android提供的一个视图容器,它可以包含两个主要区域——主内容视图和一个或多个...
本篇将深入探讨如何构建一个支持动态布局的Android抽屉组件,以ExPanel(1)为例。 首先,抽屉组件的核心是`android.support.v4.widget.DrawerLayout`,它是Android Support Library中的一个控件,用于创建滑动抽屉...
`<android.support.v4.widget.DrawerLayout>` 作为根元素,包含主布局和抽屉布局。抽屉视图使用 `android:layout_gravity` 属性来定位,如 "start" 或 "end" 表示从左侧或右侧滑出。 6. **数据绑定和菜单项点击事件...
在Android开发中,"可左右两侧挤压傍边布局的Android抽屉"是一种常见的设计模式,通常用于实现侧滑菜单效果。这种布局允许用户从屏幕的边缘向内滑动,显示隐藏的内容,比如导航选项或者更多功能。在Android的UI设计...
首先,Android抽屉的实现主要依赖于`SlidingDrawer`组件(尽管在较新的API级别中已被弃用)或者`NavigationView`结合`DrawerLayout`。在这个案例中,`slidingdrawer`可能是指一个包含实现抽屉功能的源代码文件。`...
通过以上步骤,你可以创建一个具有上下伸缩和展开效果的Android抽屉下拉菜单。这个过程中,不断优化用户体验,让交互更加自然流畅,是提升应用品质的关键。同时,持续学习和分享新的实现方式,也是提升个人技能的...
总的来说,Android抽屉结合`Fragment`是一种常见的应用设计模式,它提供了良好的用户体验和高效的导航结构。开发者需要熟悉`NavigationView`和`DrawerLayout`的使用,以及如何与`Fragment`协作,才能实现流畅的抽屉...
本篇文章将详细解析如何在Android4.4中创建一个下拉抽屉效果。 首先,下拉抽屉在Android中通常通过`NavigationView`或者`SlidingPaneLayout`来实现。`NavigationView`是Google推荐用来构建侧边栏菜单的组件,而`...
在Android应用开发中,抽屉效果(DrawerLayout)是一种常见的设计模式,用于...以上就是关于Android抽屉效果实现的基本知识和步骤。在实际项目中,你可能需要根据具体需求进行调整,例如添加动画效果、定制菜单样式等。
`DrawerLayout`是Android SDK中的一个布局容器,它可以容纳一个或两个抽屉视图,通常是从屏幕左侧或右侧滑出。在XML布局文件中,你可以将主内容视图和抽屉视图分别作为`DrawerLayout`的子元素来设置。 以下是一个...
描述中的"android多方向抽屉drawer,上下左右均可"表明我们将关注如何实现一个可以沿着屏幕四个边界的抽屉。在Android中,虽然官方的`android.widget.SlidingDrawer`类已经被废弃,但开发者仍然可以通过自定义视图...
以上就是关于“android抽屉组件实例”的核心知识点。通过学习和实践这个实例,初学者不仅可以掌握抽屉组件的基本用法,还能进一步理解Android布局和事件处理机制,为今后的Android开发打下坚实的基础。记得在实际...
总的来说,这个“android抽屉效果源码”是一个很好的学习资源,它涵盖了Android手势检测、视图动画、自定义布局等多个关键知识点。通过分析和运行这个示例,开发者可以深入理解Android滑动抽屉的实现原理,并将其...
这个从gitHub上整理的Android抽屉效果项目,涵盖了左滑、右滑、上滑和下滑等多种交互方式,为开发者提供了实现各种菜单效果的工具。 首先,我们来了解一下抽屉布局的基本概念。抽屉布局(DrawerLayout)是Android ...
滑动抽屉通常包含在一个Activity的布局文件中,利用`android.support.v4.widget.DrawerLayout`作为根视图。`DrawerLayout`是Android支持库的一部分,用于实现这种侧滑菜单效果。它可以承载两个子视图:主要内容视图...
以上就是使用`DrawerLayout`和`RecyclerView`实现Android抽屉效果的基本流程。实际开发中,你可能还需要根据具体需求进行调整,比如添加自定义头部视图、实现下拉刷新等高级功能。熟练掌握这些组件的使用,能帮助...
Android抽屉效果的核心组件是`NavigationView`和`DrawerLayout`,它们是Android SDK中的两个关键布局组件。 1. **NavigationView**: 这是一个用于创建侧滑菜单的视图组件。它可以显示一个包含头像、用户名、菜单项...
本示例"Android抽屉fragment实现demo"着重展示了如何使用Fragment来构建这种交互效果,并且包含了抽屉的进入和退出动画,使得用户体验更为流畅。 首先,抽屉功能的实现主要依赖于`android.support.v4.widget....
在Android应用开发中,...总结,"android各种抽屉样式"项目提供了一个学习和参考Android抽屉实现的宝贵资源。通过研究和实践,开发者可以了解如何根据需求和设计规范创建多样化、高效的抽屉样式,提升应用的用户体验。