同步发表于http://avenwu.net/2015/02/24/custom_slide_panel_layout_as_reside_style_on_dribble_and_qq

Fork on github https://github.com/avenwu/support

14年的时候曾经在csdn上看到过一篇介绍Android中ResideMenu实现的推荐项目,也分析了一把,详见Android控件源码分析--AndroidResideMenu菜单

,那时候QQ还没有redisemenu的效果。效果还是不错的,但是有一个确定就是不支持平滑拖动时对菜单,容器的控制,只是简单的动画实现。

项目灵感据说是来自于dribble网站上的两个交互设计原型:



相关链接如下

1116265-Instasave-iPhone-App

https://dribbble.com/shots/1114754-Social-Feed-iOS7

现在QQ的侧滑ResideMenu效果和上面非常类似,同时支持平滑拖动的处理;

网络上也有一些高仿QQ策划效果的实现,比如基于HorizonalScrollView的,基于SlideMenu修改的,都是不错的思路;本文打算基于android 官方v4包进行扩展,还是更偏向使用官方的东西:)

下面是qq效果和自定义的效果:



实现

基于v4扩展包的SlidePanelLayout可以比较方便就实现需要的效果。

核心在于对互动状态的处理,SlidePanelLayout有一个setPanelSlideListener监听,类似于onScroll,通过这个回调可以很容易知道当前欢动的百分比,从而改变视图的位置,实现动画中效果。

需要注意的是这里用到了level 11以后的方法,所以如果要兼容11以前的设备可以用nineoldedroid做修改。

package net.avenwu.support.widget;

import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.os.Build;
import android.support.v4.widget.SlidingPaneLayout;
import android.util.AttributeSet;
import android.view.View; /**
* Support level 11 and later;
* TODO use nineolddroid for devices under level 11
* <p/>
* Created by chaobin on 2/18/15.
*/
@TargetApi(11)
public class CustomSlidePanelLayout extends SlidingPaneLayout {
protected View mMenuPanel;
protected float mSlideOffset;
protected boolean isCustomable = false; public CustomSlidePanelLayout(Context context) {
this(context, null);
} public CustomSlidePanelLayout(Context context, AttributeSet attrs) {
this(context, attrs, -1);
} public CustomSlidePanelLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
isCustomable = true;
setPanelSlideListener(new SimplePanelSlideListener() {
@Override
public void onPanelSlide(View panel, float slideOffset) {
mSlideOffset = slideOffset;
if (mMenuPanel == null) {
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
if (child != panel) {
mMenuPanel = child;
break;
}
}
}
final float scaleLeft = 1 - 0.3f * (1 - slideOffset);
mMenuPanel.setPivotX(-0.3f * mMenuPanel.getWidth());
mMenuPanel.setPivotY(mMenuPanel.getHeight() / 2f);
mMenuPanel.setScaleX(scaleLeft);
mMenuPanel.setScaleY(scaleLeft); final float scale = 1 - 0.2f * slideOffset;
panel.setPivotX(0);
panel.setPivotY(panel.getHeight() / 2.0f);
panel.setScaleX(scale);
panel.setScaleY(scale);
}
});
setSliderFadeColor(0);
} } @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (isCustomable) {
dimOnForeground(canvas);
}
} @Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
boolean result = super.drawChild(canvas, child, drawingTime);
if (isCustomable && child == mMenuPanel) {
dimOnForeground(canvas);
}
return result;
} /**
* dim the view
*
* @param canvas
*/
private void dimOnForeground(Canvas canvas) {
canvas.drawColor(Color.argb((int) (0xff * (1 - mSlideOffset)), 0, 0, 0));
}
}

相关链接

  1. https://github.com/romaonthego/RESideMenu
  2. https://github.com/SpecialCyCi/AndroidResideMenu

基于SlidePanelLayout实现ResideMenu的更多相关文章

  1. 【转】仿QQ5.0侧滑菜单ResideMenu

    本文由孙国威 原创.如需转载,请注明出处! 原文:http://blog.csdn.net/manoel/article/details/39013095 为了后续对这个项目进行优化,比如透明度动画. ...

  2. 最近帮客户实施的基于SQL Server AlwaysOn跨机房切换项目

    最近帮客户实施的基于SQL Server AlwaysOn跨机房切换项目 最近一个来自重庆的客户找到走起君,客户的业务是做移动互联网支付,是微信支付收单渠道合作伙伴,数据库里存储的是支付流水和交易流水 ...

  3. 自定义基于 VLC 的视频播放器

    前言(蛋疼的背景故事) 前段时间,接了一个小项目,有个需求是要在系统待机一段时间以后,循环播放 MV(类似于 Windows 系统的屏幕保护). 听到这个需求,我首先想到的是 MediaPlayer ...

  4. 构建一个基本的前端自动化开发环境 —— 基于 Gulp 的前端集成解决方案(四)

    通过前面几节的准备工作,对于 npm / node / gulp 应该已经有了基本的认识,本节主要介绍如何构建一个基本的前端自动化开发环境. 下面将逐步构建一个可以自动编译 sass 文件.压缩 ja ...

  5. 常用 Gulp 插件汇总 —— 基于 Gulp 的前端集成解决方案(三)

    前两篇文章讨论了 Gulp 的安装部署及基本概念,借助于 Gulp 强大的 插件生态 可以完成很多常见的和不常见的任务.本文主要汇总常用的 Gulp 插件及其基本使用,需要读者对 Gulp 有一个基本 ...

  6. 基于spring注解AOP的异常处理

    一.前言 项目刚刚开发的时候,并没有做好充足的准备.开发到一定程度的时候才会想到还有一些问题没有解决.就比如今天我要说的一个问题:异常的处理.写程序的时候一般都会通过try...catch...fin ...

  7. Spring基于AOP的事务管理

                                  Spring基于AOP的事务管理 事务 事务是一系列动作,这一系列动作综合在一起组成一个完整的工作单元,如果有任何一个动作执行失败,那么事务 ...

  8. 基于本地存储的kvm虚拟机在线迁移

    基于本地存储的kvm虚拟机在线迁移 kvm虚拟机迁移分为4种(1)热迁移基于共享存储(2)热迁移基于本地存储(3)冷迁移基于共享存储(4)冷迁移基于本地存储 这里介绍的是基于本地存储的热迁移 动态块迁 ...

  9. 使用C#处理基于比特流的数据

    使用C#处理基于比特流的数据 0x00 起因 最近需要处理一些基于比特流的数据,计算机处理数据一般都是以byte(8bit)为单位的,使用BinaryReader读取的数据也是如此,即使读取bool型 ...

随机推荐

  1. CCF 201612-2 火车购票 (暴力)

    问题描述 请实现一个铁路购票系统的简单座位分配算法,来处理一节车厢的座位分配. 假设一节车厢有20排.每一排5个座位.为方便起见,我们用1到100来给所有的座位编号,第一排是1到5号,第二排是6到10 ...

  2. .android:allowTaskReparenting 等Activity 的task属性

    转自http://blog.csdn.net/javayinjaibo/article/details/8855678 1.android:allowTaskReparenting 这个属性用来标记一 ...

  3. css伪类运用

    <!doctype html><html><head><meta charset="utf-8"><title>CSS输 ...

  4. c# 后台弹出对话框 和前台弹出新页面

    前台: window.showModalDialog("daoru.aspx", "NPOI_daoru_window", "status:false ...

  5. socket进阶

    socketserver(在Python2.*中的是SocketServer模块)是标准库中一个高级别的模块.用于简化网络客户与服务器的实现(在前面使用socket的过程中,我们先设置了socket的 ...

  6. EJB到底是什么,真的那么神秘吗??

    1. 我们不禁要问,什么是"服务集群"?什么是"企业级开发"? 既然说了EJB 是为了"服务集群"和"企业级开发",那么 ...

  7. plsql基础

    语法:declare-->声明变量 begin-->执行部分 exception-->异常 end-->结束 / 最简单的程序:begin null; end; 输出语句:DB ...

  8. WCF的一点补充-Restful相关

    参考 配置WCF心得 对REST架构 风格下WCF的一点补充 Securing WCF REST Service with Azure AppFabric Access Control Service ...

  9. Unity2.0容器自动注册机制

    现如今可能每个人都会在项目中使用着某种 IoC 容器,并且我们的意识中已经形成一些固定的使用模式,有时会很难想象如果没有 IoC 容器工作该怎么进展. IoC 容器通过某种特定设计的配置,用于在运行时 ...

  10. C#与数据库访问技术总结(十八)

    ADO.NET 代码综合示例 前面已经介绍过OLE DB.NET和SQL Server.NET数据提供者可以用来连接不同的数据源. 以下代码不仅综合演示了使用ADO.NET的这两种数据提供者访问数据库 ...