转载请说明出处
最近在做公司新产品的设计,看到腾讯安全管家首页的抽屉效果设计的挺不错,一方面可以讲经常使用的功能模块直接显示给用户,另一方面将用户不常用的功能模块隐藏起来,而这些功能模块的显示和隐藏可以通过一个抽屉组建实现。所以我们想将这个设计理念加入到我们的产品中。腾讯安全管家效果图如下:
虽然android 文档中向我们提供了一个叫SlidingDrawer的抽屉组建,但是这个组建的使用限制比较多,也实现不了我们想要的效果。故到网上搜了一会,也没看到有开发者写这样的组建。所以只能靠自己了,但是在网上还是看到了一下有价值的参考案例。
不费话了,直接上实现后的效果图:
下面是自定义组建的实现代码
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
public class CustomSlidingDrawer extends LinearLayout implements GestureDetector.OnGestureListener, View.OnTouchListener{
private final static String TAG = "CustomSlidingDrawer";
private Button btnHandler;
private LinearLayout container;
private int mBottonMargin=0;
private GestureDetector mGestureDetector;
private boolean mIsScrolling=false;
private float mScrollY;
private int moveDistance;
public CustomSlidingDrawer(Context context,View otherView,int width,int height, int hideDistance) {
super(context);
moveDistance = hideDistance;
//定义手势识别
mGestureDetector = new GestureDetector(context,this);
mGestureDetector.setIsLongpressEnabled(false);
//改变CustomSlidingDrawer附近组件的属性
LayoutParams otherLP=(LayoutParams) otherView.getLayoutParams();
//这一步很重要,要不组建不会显示
otherLP.weight=1;
otherView.setLayoutParams(otherLP);
//设置CustomSlidingDrawer本身的属性
LayoutParams lp=new LayoutParams(width, height);
lp.bottomMargin = -moveDistance;
mBottonMargin=Math.abs(lp.bottomMargin);
this.setLayoutParams(lp);
this.setOrientation(LinearLayout.VERTICAL);
//this.setBackgroundColor(Color.BLUE);
//设置Handler的属性
btnHandler=new Button(context);
btnHandler.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, 35));
btnHandler.setOnTouchListener(this);
this.addView(btnHandler);
//设置Container的属性
container=new LinearLayout(context);
//container.setBackgroundColor(Color.GREEN);
container.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
this.addView(container);
}
/**
* 把View放在CustomSlidingDrawer的Container
* @param v
*/
public void fillPanelContainer(View v)
{
container.addView(v);
}
/**
* 异步移动CustomSlidingDrawer
*/
class AsynMove extends AsyncTask<Integer, Integer, Void> {
@Override
protected Void doInBackground(Integer... params) {
Log.e(TAG, "AsynMove doInBackground");
int times;
if (mBottonMargin % Math.abs(params[0]) == 0)// 整除
times = mBottonMargin / Math.abs(params[0]);
else
// 有余数
times = mBottonMargin / Math.abs(params[0]) + 1;
for (int i = 0; i < times; i++) {
publishProgress(params);
}
return null;
}
@Override
protected void onProgressUpdate(Integer... params) {
Log.e(TAG, "AsynMove onProgressUpdate");
LayoutParams lp = (LayoutParams) CustomSlidingDrawer.this.getLayoutParams();
if (params[0] < 0)
lp.bottomMargin = Math.max(lp.bottomMargin + params[0],
(-mBottonMargin));
else
lp.bottomMargin = Math.min(lp.bottomMargin + params[0], 0);
CustomSlidingDrawer.this.setLayoutParams(lp);
}
}
@Override
public boolean onDown(MotionEvent e) {
mScrollY=0;
mIsScrolling=false;
return false;
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
LayoutParams lp = (LayoutParams) CustomSlidingDrawer.this.getLayoutParams();
if (lp.bottomMargin < 0)
new AsynMove().execute(new Integer[] { moveDistance });// 正数展开
else if (lp.bottomMargin >= 0)
new AsynMove().execute(new Integer[] { -moveDistance });// 负数收缩
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
mIsScrolling=true;
mScrollY+=distanceY;
LayoutParams lp=(LayoutParams) CustomSlidingDrawer.this.getLayoutParams();
if (lp.bottomMargin < -1 && mScrollY > 0) {//往上拖拉
lp.bottomMargin = Math.min((lp.bottomMargin + (int) mScrollY),0);
CustomSlidingDrawer.this.setLayoutParams(lp);
} else if (lp.bottomMargin > -(mBottonMargin) && mScrollY < 0) {//往下拖拉
lp.bottomMargin = Math.max((lp.bottomMargin + (int) mScrollY),-mBottonMargin);
CustomSlidingDrawer.this.setLayoutParams(lp);
}
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) {}
@Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction()==MotionEvent.ACTION_UP && //onScroll时的ACTION_UP
mIsScrolling==true)
{
LayoutParams lp=(LayoutParams) CustomSlidingDrawer.this.getLayoutParams();
if (lp.bottomMargin >= (-mBottonMargin/2)) {//往上超过一半
new AsynMove().execute(new Integer[] { moveDistance });// 正数展开
}
else if (lp.bottomMargin < (-mBottonMargin/2)) {//往下拖拉
new AsynMove().execute(new Integer[] { -moveDistance });// 负数收缩
}
}
return mGestureDetector.onTouchEvent(event);
}
}
下面是demo的源码:
- 大小: 74.2 KB
- 大小: 71.1 KB
- 大小: 51 KB
- 大小: 52.2 KB
分享到:
相关推荐
此例子是模仿腾讯安全管家实现的小火箭拖拽,发射,打下ufo等效果。
android仿腾讯视频启动页及广告页面动画效果实现
Android 利用ViewDragHelper实现的仿腾讯QQ侧滑菜单的实现
请看博客文章: 【Android进阶】如何写一个很屌的动画(3)---高仿腾讯手机管家火箭动画,http://blog.csdn.net/scnuxisan225/article/details/50454948
WPF 仿照电脑管家基础页面,只有页面效果,和电脑管家很相似,采用MVVM,使用阿里iconfont 图标,自定义button 按钮,有一定参考性,不喜勿碰
仿腾讯图库js浏览图片效果 仿腾讯图库js浏览图片效果 仿腾讯图库js浏览图片效果
仿腾讯手机管家界面,基于MFC对话框程序实现,对整个对话框进行了重绘和贴图
防腾讯手机管家火箭升空效果,供兴趣爱好者学习
腾讯电脑管家正式版腾讯电脑管家正式版
android popupwindow 仿新浪、腾讯title弹框效果
Android 开发之仿腾讯视频全部频道 RecyclerView 拖拽效果实现
用LTFrame精美高仿腾讯电脑管家源码
仿腾讯动画的android下载对话框,波浪型下载进度条对话框
腾讯手机管家(PC版) For Android.rar
VS2008做的仿腾讯手机管家程序,十分好的一个Gdi+自绘的框架,值得参考
腾讯手机管家(安卓)
腾讯管家离线安装包.12.15版本. 适合没有外网环境的系统安装.
Android仿腾讯视频悬浮窗的实现--相关图片文件
Android 仿腾讯应用宝 之 Toolbar +Scroolview +tab滑动悬停效果