您的位置:首页 > 移动开发 > Android开发

Android实现仿QQ5.0的侧滑效果

2014-11-08 15:32 323 查看
前段时间准备学习下侧滑效果的实现,不经意间发现了穆课网有个介绍QQ5.0侧滑的视频,于是学习了下,稍作整理,留作自用。

首先看一下效果,第一张就是截的QQ的图模拟内容界面,第二张为向左侧滑时的效果。





一、整体实现思路

两个界面本质是一个View,左右排列,通过一个水平滚动条来实现(示例中自定义了一个View继承自HorizontalScrollView)。起始状态滚动条在靠近中间的位置,这样就显示出了内容区域。当从内容区向左侧滑时,滑到一定的范围就直接将滚动条设置到最左边,这样就看到了左边的菜单。向右侧滑也是类似。为了达到在菜单边界露出内容区域的效果,需要设置菜单的宽度比屏幕宽度小一些(小的宽度就是露出内容区域的宽度)。需要的知识点如下:1. 自定义View的onMeasure事件与onLayout事件;2.
onTouchEvent事件;3.获取屏幕的宽度和高度;4. 获取和设置滚动条的偏移量并实现切换的动画;5.单位换算;6.设置不显示标题。

二、例子所需的知识储备

1. 自定义View的onMeasure事件与onLayout事件;

首先View的onMeasure事件可以设置View中子控件的大小,onLayout事件可设置子控件在该View中的位置。 在这个例子中在onMeasure事件中设置左边菜单的宽度和右边内容区域的宽度,然后在onLayout事件中确定初始显示内容区域(设置滚动条的位置)。

2. onTouchEvent事件

这个响应用户的滑动事件,当用户手指抬起的时候要判断水平滑动的距离,当达到一定的范围就切换界面(也就是设置滚动条的位置)。

3.获取屏幕的宽度和高度

WindowManager wm = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
mScreenWidth = outMetrics.widthPixels;

4. 获取和设置滚动条的偏移量并实现切换的动画

设置滚动条的位置采用scrollTo,该方法是不带动画,而smoothScrollTo是带动画的,能让人看到滑过去的效果,而不是直接切换。

示例中this.smoothScrollTo(mMenuWidth, 0);表示将滚动条移动到mMenuWidth宽度处。

5.单位换算

TypedValue.applyDimension方法,示例如下:

// 把DP转换成px
mMenuRightPadding = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 50, context.getResources()
.getDisplayMetrics());

6.设置不显示标题

在AndroidManifest.xml设置主题android:theme="@android:style/Theme.NoTitleBar"。

三、完整示例代码:

activity_main.xml代码:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/left_menu" >
<com.example.qq1024.SlidingMenu
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal" >
<include layout="@layout/left_menulayout" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/qq_main" >
</LinearLayout>
</LinearLayout>
</com.example.qq1024.SlidingMenu>
</RelativeLayout>


left_menulayout.xml代码:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/left_menu" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/first_img"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:src="@drawable/first_menu" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_toRightOf="@id/first_img"
android:text="第一个菜单"
android:textColor="#FFF"
android:textSize="20sp" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/second_img"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:src="@drawable/second_menu" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_toRightOf="@id/second_img"
android:text="第二个菜单"
android:textColor="#FFF"
android:textSize="20sp" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/third_img"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:src="@drawable/third_menu" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_toRightOf="@id/third_img"
android:text="第三个菜单"
android:textColor="#FFF"
android:textSize="20sp" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/forth_img"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:src="@drawable/forth_menu" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_toRightOf="@id/forth_img"
android:text="第四个菜单"
android:textColor="#FFF"
android:textSize="20sp" />
</RelativeLayout>
</LinearLayout>
</RelativeLayout>


SlidingMenu.java代码:

package com.example.qq1024;

import android.content.Context;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;

public class SlidingMenu extends HorizontalScrollView {

private LinearLayout mWapper;
private ViewGroup mMenu;
private ViewGroup mContent;
private int mScreenWidth;
private int mMenuRightPadding = 50;
private boolean once = false;
private int mMenuWidth;

public SlidingMenu(Context context, AttributeSet attrs) {
super(context, attrs);

WindowManager wm = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);

mScreenWidth = outMetrics.widthPixels;
// 把DP转换成px mMenuRightPadding = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 50, context.getResources() .getDisplayMetrics());
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (!once) {
mWapper = (LinearLayout) getChildAt(0);
mMenu = (ViewGroup) mWapper.getChildAt(0);
mContent = (ViewGroup) mWapper.getChildAt(1);
mMenu.getLayoutParams().width = mScreenWidth - mMenuRightPadding;
mContent.getLayoutParams().width = mScreenWidth;
mMenuWidth = mMenu.getLayoutParams().width;
once = true;
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

@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) {
int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_UP:
int scrollx = getScrollX();
if (scrollx >= mMenuWidth / 2) {
this.smoothScrollTo(mMenuWidth, 0);
} else {
this.smoothScrollTo(0, 0);
}
return true;

default:
break;
}
return super.onTouchEvent(ev);
}
}


MainActivity.java代码:

package com.example.qq1024;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}

最后还是要感谢穆课网上的hyman的视频,代码内容几乎跟视频中的一样,只是做了点事件的调查和界面的修饰,然后以文字显示,方便以后使用。


源码下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: