仿QQ5.3.1左右滑动效果实现

工作之余无聊,研究一下QQ的特效,不过还是有些区别的!

效果图如下:

左滑:

右滑:

滑动是实现主要是HorizontalScrollView来实现的,可能会与qq的有些区别,但是大致效果还是出来了!

区别:

1.可以左右滑动,qq的不可以右滑。

2.左滑和右滑的背景切换效果和qq的有区别

3.还有些细节上的差别

主要实现代码如下:

import android.content.Context;

import android.content.res.TypedArray;

import android.util.AttributeSet;

import android.util.DisplayMetrics;

import android.util.Log;

import android.util.TypedValue;

import android.view.MotionEvent;

import android.view.View;

import android.view.ViewGroup;

import android.view.WindowManager;

import android.widget.HorizontalScrollView;

import android.widget.LinearLayout;

import android.widget.Toast;

import com.nineoldandroids.view.ViewHelper;

import com.xiaoyi.tencent.R;

public class SlidingMenu extends HorizontalScrollView

{

private LinearLayout mWapper;

private ViewGroup mMenu;

private ViewGroup mContent;

private int mScreenWidth;

private int mMenuWidth;

// dp

private int mMenuRightPadding = 50;

private boolean once;

public boolean isLeftOpen;

public boolean isRightOpen;

Context context;

/**

* 未使用自定义属性时,调用

*

* @param context

* @param attrs

*/

public SlidingMenu(Context context, AttributeSet attrs)

{

this(context, attrs, 0);

this.context=context;

}

/**

* 当使用了自定义属性时,会调用此构造方法

*

* @param context

* @param attrs

* @param defStyle

*/

public SlidingMenu(Context context, AttributeSet attrs, int defStyle)

{

super(context, attrs, defStyle);

this.context=context;

// 获取我们定义的属性

TypedArray a = context.getTheme().obtainStyledAttributes(attrs,

R.styleable.SlidingMenu, defStyle, 0);

int n = a.getIndexCount();

for (int i = 0; i < n; i++)

{

int attr = a.getIndex(i);

switch (attr)

{

case R.styleable.SlidingMenu_rightPadding:

mMenuRightPadding = a.getDimensionPixelSize(attr,

(int) TypedValue.applyDimension(

TypedValue.COMPLEX_UNIT_DIP, 50, context

.getResources().getDisplayMetrics()));

break;

}

}

a.recycle();

WindowManager wm = (WindowManager) context

.getSystemService(Context.WINDOW_SERVICE);

DisplayMetrics outMetrics = new DisplayMetrics();

wm.getDefaultDisplay().getMetrics(outMetrics);

mScreenWidth = outMetrics.widthPixels;

Log.d("TAG", "slidingMenu");

}

public SlidingMenu(Context context)

{

this(context, null);

this.context=context;

}

/**

* 设置子View的宽和高 设置自己的宽和高

*/

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)

{

if (!once)

{

mWapper = (LinearLayout) getChildAt(0);

mMenu = (ViewGroup) mWapper.getChildAt(0);

mContent = (ViewGroup) mWapper.getChildAt(1);

mMenuWidth = mMenu.getLayoutParams().width = mScreenWidth

- mMenuRightPadding;

mContent.getLayoutParams().width = mScreenWidth;

once = true;

mContent.setClickable(true);

mContent.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View arg0) {

Log.d("TAG", "setOnClickListener");

if (isRightOpen)

{

closeRightMenu();

} else if(isLeftOpen)

{

closeMenuLeft();

}

}

});

}

Log.d("TAG", "onMeasure");

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

}

/**

* 通过设置偏移量,将menu隐藏

*/

@Override

protected void onLayout(boolean changed, int l, int t, int r, int b)

{

super.onLayout(changed, l, t, r, b);

if (changed)

{

this.scrollTo(mMenuWidth, 0);

}

}

@Override

public boolean onTouchEvent(MotionEvent ev)

{

Log.e("TAG", "onTouchEvent  ");

int action = ev.getAction();

switch (action)

{

case MotionEvent.ACTION_UP:

// 隐藏在左边的宽度

int scrollX = getScrollX();

if (scrollX >= mMenuWidth / 2&&scrollX<=mMenuWidth)

{

this.smoothScrollTo(mMenuWidth, 0);

isLeftOpen = false;

} else if(scrollX<mMenuWidth / 2){

this.smoothScrollTo(0, 0);

isLeftOpen = true;

}else if(scrollX>=mMenuWidth+30){

this.smoothScrollTo(mMenuWidth*2, 0);

isRightOpen = true;

}else{

this.smoothScrollTo(mMenuWidth, 0);

isRightOpen = false;

}

return true;

}

return super.onTouchEvent(ev);

}

/**

* 打开左边菜单

*/

public void openMenuLeft()

{

if (isLeftOpen)

return;

this.smoothScrollTo(0, 0);

isLeftOpen = true;

}

/**

* 打开右边菜单

*/

public void openRightMenu()

{

if (isRightOpen)

return;

this.smoothScrollTo(mMenuWidth*2, 0);

isRightOpen = true;

}

public void closeMenuLeft()

{

if (!isLeftOpen)

return;

this.smoothScrollTo(mMenuWidth, 0);

isLeftOpen = false;

}

/**

* 关闭右边菜单

*/

public void closeRightMenu()

{

if (!isRightOpen)

return;

this.smoothScrollTo(mMenuWidth, 0);

isRightOpen = false;

}

/**

* 切换菜单左边

*/

public void toggleLeft()

{

if (isLeftOpen)

{

closeMenuLeft();

} else

{

openMenuLeft();

}

}

/**

* 切换菜单右边

*/

public void toggleRight()

{

if (isRightOpen)

{

closeRightMenu();

} else

{

openRightMenu();

}

}

/**

* 关闭菜单

*/

public void closeMune()

{

if (isRightOpen)

{

Toast.makeText(context, "isRightOpen关闭菜单", Toast.LENGTH_LONG).show();

closeRightMenu();

} else if(isLeftOpen)

{

Toast.makeText(context, "isLeftOpen关闭菜单", Toast.LENGTH_LONG).show();

closeMenuLeft();

}

}

/**

* 滚动发生时

*/

@Override

protected void onScrollChanged(int l, int t, int oldl, int oldt)

{

super.onScrollChanged(l, t, oldl, oldt);

if(l<=mMenuWidth){//显示左边菜单

float scale = l * 1.0f / mMenuWidth; // 1 ~ 0

/**

* 区别1:内容区域1.0~0.7 缩放的效果 scale : 1.0~0.0 0.7 + 0.3 * scale

*

* 区别2:菜单的偏移量需要修改

*

* 区别3:菜单的显示时有缩放以及透明度变化 缩放:0.7 ~1.0 1.0 - scale * 0.3 透明度 0.6 ~ 1.0

* 0.6+ 0.4 * (1- scale) ;

*

*/

float rightScale = 0.7f + 0.3f * scale;

float leftScale = 1.0f - scale * 0.3f;

float leftAlpha = 0.6f + 0.4f * (1 - scale);

// 调用属性动画,设置TranslationX

ViewHelper.setTranslationX(mMenu, mMenuWidth * scale * 0.8f);

ViewHelper.setScaleX(mMenu, leftScale);

ViewHelper.setScaleY(mMenu, leftScale);

ViewHelper.setAlpha(mMenu, leftAlpha);

// 设置content的缩放的中心点

ViewHelper.setPivotX(mContent, 0);

ViewHelper.setPivotY(mContent, mContent.getHeight() / 2);

ViewHelper.setScaleX(mContent, rightScale);

ViewHelper.setScaleY(mContent, rightScale);

}else{//显示右边菜单

float scale =1- (l * 1.0f- mMenuWidth)/ mMenuWidth; // 1 ~ 0

float contentScale = 0.7f + 0.3f * scale;

float rightScale = 1.0f - scale * 0.3f;

float rightAlpha = 0.6f + 0.4f * (1 - scale);

// 调用属性动画,设置TranslationX

ViewHelper.setTranslationX(mMenu, -mMenuWidth * scale * 0.8f);

ViewHelper.setScaleX(mMenu, rightScale);

ViewHelper.setScaleY(mMenu, rightScale);

ViewHelper.setAlpha(mMenu, rightAlpha);

// 设置content的缩放的中心点

ViewHelper.setPivotX(mContent, mContent.getWidth());

ViewHelper.setPivotY(mContent, mContent.getHeight() / 2);

ViewHelper.setScaleX(mContent, contentScale);

ViewHelper.setScaleY(mContent, contentScale);

}

}

}

中间是张图片,左右菜单布局是写出来的。

git地址:https://github.com/xiaoyi848699/Tencent

csdn下载地址:http://download.csdn.net/detail/xiaoyi848699/8382649

时间: 2024-10-05 04:45:22

仿QQ5.3.1左右滑动效果实现的相关文章

android用最简单的方法实现QQ5.0的侧边栏滑动效果

先看个效果 使用两个开源项目 开源侧边栏 :me.tangke.slidemenu 开源动画:nineoldandroids-2.4.0.jar 在项目里我使用的是左边activity,右边activity的样式,activityGroup的方式,如果全用Fragment也是一样的,只要获取Fragment的rootView即可; 滑动时用me.tangke.slidemenu是为获取拖动屏幕的比例,其他的菜单栏也可以使用,只是加个动画; 界面所有逻辑代码不动,使用nineoldandroids

仿VS安装界面小球滑动效果

在Visual Studio 2010后续版本的安装界面中,可以发现一组小球在滑动表示安装程序正在进行: 于是尝试用CSS实现了一下. 首先需要建立用来表示小球的html结构: <div class="container"> <div class="circle c1"></div> <div class="circle c2"></div> <div class="ci

仿QQ5.0以上新版本侧滑效果

1.此效果使用了csdn大神孙国威的代码案例在此感谢附上参考博客地址: http://blog.csdn.net/manoel/article/details/39013095/#plain 2.slidingmenu库不需要修改,弄下来可以直接使用 3.demo中的代码是支持单侧的,我仅仅给加了个双侧支持,当然这个只是双侧仅仅是效果上达到了,还有不完善的地方,就是两侧侧滑会有部分主界面布局实际存在但是看不到的情况,这个大家使用的时候会发现,一般稍微粗心点可能看不到. 4.当主界面布局与未隐藏的

十六、Android 滑动效果汇总

Android 滑动效果入门篇(一)-- ViewFlipper Android 滑动效果入门篇(二)-- Gallery Android 滑动效果基础篇(三)-- Gallery仿图像集浏览 Android 滑动效果基础篇(四)-- Gallery + GridView Android 滑动效果进阶篇(五)-- 3D旋转 Android 滑动效果进阶篇(六)-- 倒影效果 ViewFilpper 是Android官方提供的一个View容器类,继承于ViewAnimator类,用于实现页面切换,

Android 高仿 QQ5.0 侧滑菜单效果 自定义控件来袭【学习鸿洋_视频博客笔记总结】

学习鸿洋博客:http://blog.csdn.net/lmj623565791/article/details/39257409 学习鸿洋视频:慕课网视频 看看Android 高仿 QQ5.0 侧滑菜单效果 自定义控件实现效果: 技术上,继承HorizontalScrollView 加上自定义ViewGroup来实现: 1.onMeasure:决定内部View(子View)的宽和高,以及自己的宽和高 2.onLayout:决定子View的放置位置 3.onTouchEvent[监听动作] 自定

android仿系统Launcher界面,实现分屏,左右滑动效果(ViewSwitcher)

ViewSwitcher代表了视图切换组件, 本身继承了FrameLayout ,可以将多个View叠在一起 ,每次只显示一个组件.当程序控制从一个View切换到另个View时,ViewSwitcher 支持指定动画效果. 为了给ViewSwitcher 添加多个组件, 一般通过ViewSwitcher 的setFactory 方法为止设置ViewFactory ,并由ViewFactory为之创建View 即可. 下面通过一个实例来介绍 ViewSwitcher的用法.(仿Android系统L

【源码】仿QQ5.0和微信的滑动删除聊天列表

仿QQ5.0和微信的滑动删除聊天列表 功能分类:特效 支持平台:Android 运行环境:Android 开发语言:Java 开发工具:Eclipse 源码大小:2.21MB 下载地址:http://t.cn/R7eluap 源码简介 滑动删除ListView的Itemdemo 源码运行截图    

仿一个好玩的滑动效果

起因 昨天跑步的时候,看到一个app(华为手机自带的运动健康)上的滑动效果很有意思,回来之后就想着,能不能在dom上实现一下,于是有了这篇文章.首先看一下效果图,滑动下面的绿色滑块可以看到效果: 贴出app上的效果图,模仿效果可以说是差强人意吧: 实现 其实原理很简单,就是在小圆点移动时,计算数字和小圆点的距离,来控制数字的上升和下降. 首先,要使小圆点跟随鼠标移动起来:代码如下: slide.addEventListener('mousedown', function(e){ e.preven

Android DrawerLayout 高仿QQ5.2双向侧滑菜单

1.概述 之前写了一个Android 高仿 QQ5.0 侧滑菜单效果 自定义控件来袭 ,恰逢QQ5.2又加了一个右侧菜单,刚好看了下DrawerLayout,一方面官方的东西,我都比较感兴趣:另一方面,这玩意用起来的确方便,于是简单写了个demo,高仿QQ5.2双向侧滑,分享给大家. 首先看看效果图: DrawerLayout用起来真的很方便,下面一起看看用法~ 2.DrawerLayout的使用 直接将DrawerLayout作为根布局,然后其内部第一个View为内容区域,第二个View为左侧