android自定义实现抽屉SlidingDrawer的功能
最近项目中需要实现上拉功能,首先想到的就是Android本身自带的抽屉SlidingDrawer,最后也实现了不过,出现的问题就是设置背景色问题,handler和content是两个不同的部分,这就造成图片要做成两部分,从而产生两个部分图片看起来不是一个整体,而且我这个上拉功能,里面要实现一个水平滚动功能,而SlidingDrawer还有其他的限制,同时官方给出api 17以后,这个功能已经废弃,所以自己自定这样一个上拉功能是必须的。
这里我是继承LinearLayout同时实现GestureDetector.OnGestureListener来实现上拉功能。下面是代码:
package com.example.test; import android.content.Context;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.widget.LinearLayout;
import android.widget.RelativeLayout; public class PanelBom extends LinearLayout implements GestureDetector.OnGestureListener{ GestureDetector mGesture = null;
private boolean isScrolling = false;
private int MAX_HEIGHT = 80;//拖动的最大高度,当前布局位于父布局下面-80位置,这个仅仅是调试参数,这个变量是动态设置的。
private float mScrollX; // 滑块滑动距离
public PanelBom(Context context) {
super(context);
init();
}
public PanelBom(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
//初始化一些参数
public void init(){
mGesture = new GestureDetector(this);
mGesture.setIsLongpressEnabled(false);
setBackgroundResource(R.drawable.button_bar);
} @Override
public boolean onTouchEvent(MotionEvent event) {
if (MotionEvent.ACTION_UP == event.getAction() && isScrolling == true) {
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)getLayoutParams();
// 缩回去
if (layoutParams.bottomMargin < -MAX_HEIGHT / 2) {
new AsynMove().execute(-20);//负--往下
} else {
new AsynMove().execute(20);//正--往上
}
}
return mGesture.onTouchEvent(event);
}
//Touch down时触发
@Override
public boolean onDown(MotionEvent e) {
mScrollX = 0;
isScrolling = false;
// 将之改为true,不然事件不会向下传递.
return true;
}
//Touch了还没有滑动时触发
@Override
public void onShowPress(MotionEvent e) { }
@Override
public boolean onSingleTapUp(MotionEvent e) {
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams();
// 说明在上面,要往下
if (layoutParams.bottomMargin >= 0) {
new AsynMove().execute(-20);//负--往下
} else {
new AsynMove().execute(20);//正--往上
}
return true;
}
//Touch了滑动时触发
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
isScrolling = true;
mScrollX += distanceY;
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)getLayoutParams();
layoutParams.bottomMargin += mScrollX;
if (layoutParams.bottomMargin >= 0) {
isScrolling = false;// 拖过头了不需要再执行AsynMove了
layoutParams.bottomMargin = 0;
} else if (layoutParams.bottomMargin <= -MAX_HEIGHT) {
// 拖过头了不需要再执行AsynMove了
isScrolling = false;
layoutParams.bottomMargin = -MAX_HEIGHT;
}
setLayoutParams(layoutParams);
return false;
}
//Touch了不移动一直Touch down时触发
@Override
public void onLongPress(MotionEvent e) { }
//Touch了滑动一点距离后,up时触发。
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
return false;
}
//异步更新布局的位置
class AsynMove extends AsyncTask<Integer, Integer, Void> {
@Override
protected Void doInBackground(Integer... params) {
int times = 0;
int divi = Math.abs(params[0]);
if (MAX_HEIGHT % divi == 0)// 整除
times = MAX_HEIGHT / Math.abs(params[0]);
else
times = MAX_HEIGHT / divi + 1;// 有余数 for (int i = 0; i < times; i++) {
publishProgress(params[0]);
try {
Thread.sleep(divi);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams();
if (values[0] < 0) {
layoutParams.bottomMargin = Math.max(layoutParams.bottomMargin + values[0], -MAX_HEIGHT);
} else {
layoutParams.bottomMargin = Math.min(layoutParams.bottomMargin + values[0], 0);
}
setLayoutParams(layoutParams); super.onProgressUpdate(values);
}
}
}
主界面:
package com.example.test; import android.app.Activity;
import android.os.Bundle;
import android.widget.RelativeLayout; public class Main5 extends Activity{ RelativeLayout Parent;
PanelBom panelBom;
RelativeLayout.LayoutParams parentParams;
RelativeLayout.LayoutParams paneBomParams;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Parent = new RelativeLayout(getApplicationContext());
panelBom = new PanelBom(getApplicationContext());
parentParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
paneBomParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, 150);
paneBomParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
paneBomParams.bottomMargin = -80;
Parent.addView(panelBom, paneBomParams);
setContentView(Parent, parentParams);
} }
实现的效果是:
拖拉,点击实现上拉功能,效果图如下:
android自定义实现抽屉SlidingDrawer的功能的更多相关文章
- Android -- 滑式抽屉SlidingDrawer(非原创)
SlidingDrawer(滑动式抽屉)隐藏屏外的内容,并允许用户拖拽一个handle以显示隐藏的内容.SlidingDrawer可以在垂直或者水平使用.它由两个子视图组成:一个是用户拖拽的handl ...
- android 自定义view之选座功能
效果图: 界面比较粗糙,主要看原理. 这个界面主要包括以下几部分 1.座位 2.左边的排数 3.左上方的缩略图 4.缩略图中的红色区域 5.手指移动时跟随移动 6.两个手指缩放时跟随缩放 主要技术点 ...
- Android控件之SlidingDrawer(滑动式抽屉)详解与实例
SlidingDrawer效果想必大家也见到过,它就是1.5模拟器上进入应用程序列表的效果.下面是截图 一.简介 SlidingDrawer隐藏屏外的内容,并允许用户通过handle以显示隐藏内容.它 ...
- Android抽屉(SlidingDrawer --类似android通知栏下拉效果)
Android抽屉(SlidingDrawer)的实现发 - 红黑联盟http://www.2cto.com/kf/201301/182507.html 可动态布局的Android抽屉之基础http: ...
- (转)[原] Android 自定义View 密码框 例子
遵从准则 暴露您view中所有影响可见外观的属性或者行为. 通过XML添加和设置样式 通过元素的属性来控制其外观和行为,支持和重要事件交流的事件监听器 详细步骤见:Android 自定义View步骤 ...
- Android 自定义View合集
自定义控件学习 https://github.com/GcsSloop/AndroidNote/tree/master/CustomView 小良自定义控件合集 https://github.com/ ...
- [原] Android 自定义View步骤
例子如下:Android 自定义View 密码框 例子 1 良好的自定义View 易用,标准,开放. 一个设计良好的自定义view和其他设计良好的类很像.封装了某个具有易用性接口的功能组合,这些功能能 ...
- [原] Android 自定义View 密码框 例子
遵从准则 暴露您view中所有影响可见外观的属性或者行为. 通过XML添加和设置样式 通过元素的属性来控制其外观和行为,支持和重要事件交流的事件监听器 详细步骤见:Android 自定义View步骤 ...
- Android 自定义title 之Action Bar
Android 自定义title 之Action Bar 2014-06-29 飞鹰飞龙... 摘自 博客园 阅 10519 转 25 转藏到我的图书馆 微信分享: Action Ba ...
随机推荐
- winform判断输入是否是数字
private bool IsNum(string str) { try { foreach (char c in str) { if (char.IsDigit(c)) return true; r ...
- 关于C++异常机制的笔记(SEH, try-catch)
昨天晚上加班解决了一个问题,是由于无法正确的捕获到异常导致的.刚开始用try-catch,但是没法捕获到异常:后面改成SEH异常才解决.因此今天将这个问题重新梳理了一遍,关于try-catch, SE ...
- 通过 HTTPS 和 SSL 确保 Windows Azure 网站 (WAWS) 安全
编辑人员注释:本文章由 Windows Azure 网站团队的项目经理 Erez Benari 撰写. 随着身份盗窃和各种形式的网络犯罪迅速增多,使用安全套接字层 (SSL) 对网站进行保护变得越来越 ...
- 基于visual Studio2013解决C语言竞赛题之0905文件读写显示
题目
- Gora_百度百科
Gora_百度百科 Gora 编辑 目录 1什么是Apache Gora 2为什么要使用Apache Gora 3Gora的一个源代 ...
- 一步一步重写 CodeIgniter 框架 -- 原因和思路
CodeIgniter 是一个非常轻量级的 PHP 框架,说是轻量级,最新版的代码只有不到2M. 其最重要的特点就是 MVC 模式来编写代码,如果大家看过一些用 PHP 来编写网站的书籍或教程,无一例 ...
- [置顶] android 自定义TextView
系统自带的控件TextView有时候没满一行就换行了,为了解决这个问题,自定义了一个TextView,只有一行显示不完全的情况下才会去换行显示,代码如下: package com.open.textv ...
- SSH-Struts(一)——基本原理
简单介绍 Struts框架是MVC的一个实现,它非常好的结合了JSP.Servlet.JavaBean.Taglib等技术.它为MVC的各层提供了良好的支持,就像房地产商盖房子时先盖的大楼框架. 仅仅 ...
- 在Centos下安装matlab
首先科普一下什么事matlab MATLAB是美国MathWorks公司出品的商业数学软件,用于算法开发.数据可视化.数据分析以及数值计算的高级技术计算语言和交互式环境,主要包含MATLAB和Simu ...
- MDK的优化应用
MDK的优化应用 http://blog.163.com/zhaojun_xf/blog/static/300505802011291384721/ 使用Keil/MDK这么多年了,一直都没有使用它的 ...