android 高仿qq5.0,基于Android实现仿QQ5.0侧滑

本课程将带领大家通过自定义控件实现QQ5.0侧滑菜单,课程将循序渐进,首先实现最普通的侧滑菜单,然后引入属性动画与拖动菜单效果相结合,最终实现QQ5.0侧滑菜单效果。通过本课程大家会对侧滑菜单有更深层次的了解,通过自定义控件和属性动画打造千变万化的侧滑菜单效果

效果图如下所示:

51bd6aedd0699b2540d6b52382a85314.png

fd3212154b51fa1bb48dbbe49b342e8a.png

package com.example;

import android.os.Bundle;

import android.support.v7.app.ActionBarActivity;

import android.view.View;

public class MainActivity extends ActionBarActivity {

private SlidingMenu mMenu;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mMenu = (SlidingMenu) findViewById(R.id.id_menu);

}

public void toggleMenu(View view)

{

mMenu.toggle();

}

}

package com.example;

import android.app.Activity;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.Rect;

import android.util.DisplayMetrics;

import android.view.View;

import android.view.WindowManager;

/**

* Created by tuhao-pc on 2015/12/28.

* 获取屏幕相关的辅助类

*/

public class ScreenUtils {

private ScreenUtils() {

}

/**

*获取屏幕的高度

* @param context

* @return

*/

public static int getScreenWidth(Context context){

WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

DisplayMetrics outMetrics = new DisplayMetrics();

wm.getDefaultDisplay().getMetrics(outMetrics);

return outMetrics.widthPixels;

}

/**

* 获取屏幕的高度

* @param context

* @return

*/

public static int getScreenHeight(Context context){

WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

DisplayMetrics outMetrics = new DisplayMetrics();

wm.getDefaultDisplay().getMetrics(outMetrics);

return outMetrics.heightPixels;

}

/**

* 获取手机状态栏的状态

* @param context

* @return

*/

public static int getStatusHeight(Context context){

int statusHeight = -1;

Class> clazz = null;

try {

clazz = Class.forName("com.android.internal.R$dimen");

Object object = clazz.newInstance();

int height = Integer.parseInt(clazz.getField("status_bar_height").get(object).toString());

statusHeight = context.getResources().getDimensionPixelSize(height);

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (NoSuchFieldException e) {

e.printStackTrace();

} catch (InstantiationException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

}

return statusHeight;

}

/**

* 获取当前屏幕截图,包含状态栏

*

* @param activity

* @return

*/

public static Bitmap snapShotWithStatusBar(Activity activity)

{

View view = activity.getWindow().getDecorView();

view.setDrawingCacheEnabled(true);

view.buildDrawingCache();

Bitmap bmp = view.getDrawingCache();

int width = getScreenWidth(activity);

int height = getScreenHeight(activity);

Bitmap bp = null;

bp = Bitmap.createBitmap(bmp, 0, 0, width, height);

view.destroyDrawingCache();

return bp;

}

/**

* 获取当前屏幕截图,不包含状态栏

*

* @param activity

* @return

*/

public static Bitmap snapShotWithoutStatusBar(Activity activity)

{

View view = activity.getWindow().getDecorView();

view.setDrawingCacheEnabled(true);

view.buildDrawingCache();

Bitmap bmp = view.getDrawingCache();

Rect frame = new Rect();

activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);

int statusBarHeight = frame.top;

int width = getScreenWidth(activity);

int height = getScreenHeight(activity);

Bitmap bp = null;

bp = Bitmap.createBitmap(bmp, 0, statusBarHeight, width, height

- statusBarHeight);

view.destroyDrawingCache();

return bp;

}

}

package com.example;

import android.content.Context;

import android.content.res.TypedArray;

import android.util.AttributeSet;

import android.util.TypedValue;

import android.view.MotionEvent;

import android.view.ViewGroup;

import android.widget.HorizontalScrollView;

import android.widget.LinearLayout;

import com.nineoldandroids.view.ViewHelper;

/**

* Created by tuhao-pc on 2015/12/28.

*/

public class SlidingMenu extends HorizontalScrollView{

private int mScreenWidth;

private int mMenuRightPadding;

private int mMenuWidth;

private int mHalfMenuWidth;

private boolean isOpen;

private boolean once;

private ViewGroup mMenu;

private ViewGroup mContent;

public SlidingMenu(Context context) {

this(context,null);

}

public SlidingMenu(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

public SlidingMenu(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

mScreenWidth = ScreenUtils.getScreenWidth(context);

TypedArray a = context.getTheme().obtainStyledAttributes(attrs,R.styleable.SlidingMenu,defStyleAttr,0);

int count = a.getIndexCount();

for(int i = 0;i < count;i++){

int attr = a.getIndex(i);

switch (attr){

case R.styleable.SlidingMenu_rightPadding:{

// 默认是50

mMenuRightPadding = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,50f,getResources().getDisplayMetrics()));

break;

}

}

}

a.recycle();

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

/**

* 显示设置一个宽度

*/

if(!once){

LinearLayout wrapper = (LinearLayout) getChildAt(0);

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

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

mMenuWidth = mScreenWidth - mMenuRightPadding;

mHalfMenuWidth = mMenuWidth/2;

mMenu.getLayoutParams().width = mMenuWidth;

mContent.getLayoutParams().width = mScreenWidth;

}

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);

once = true;

}

}

@Override

public boolean onTouchEvent(MotionEvent ev) {

int action = ev.getAction();

switch (action){

// Up时,进行判断,如果显示区域大于菜单宽度一半则完全显示,否则隐藏

case MotionEvent.ACTION_UP:{

int scrollX = getScrollX();

if(scrollX > mHalfMenuWidth){

this.smoothScrollTo(mMenuWidth,0);

isOpen = false;

}

else{

this.smoothScrollTo(0,0);

isOpen = true;

}

return true;

}

}

return super.onTouchEvent(ev);

}

/**

* 打开菜单

*/

public void openMenu()

{

if (isOpen)

return;

this.smoothScrollTo(0, 0);

isOpen = true;

}

/**

* 关闭菜单

*/

public void closeMenu()

{

if (isOpen)

{

this.smoothScrollTo(mMenuWidth, 0);

isOpen = false;

}

}

/**

* 切换菜单状态

*/

public void toggle()

{

if (isOpen)

{

closeMenu();

} else

{

openMenu();

}

}

@Override

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

{

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

float scale = l * 1.0f / mMenuWidth;

float leftScale = 1 - 0.3f * scale;

float rightScale = 0.8f + scale * 0.2f;

ViewHelper.setScaleX(mMenu, leftScale);

ViewHelper.setScaleY(mMenu, leftScale);

ViewHelper.setAlpha(mMenu, 0.6f + 0.4f * (1 - scale));

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

ViewHelper.setPivotX(mContent, 0);

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

ViewHelper.setScaleX(mContent, rightScale);

ViewHelper.setScaleY(mContent, rightScale);

}

}

布局文件和资源文件(xml)

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tu = "http://schemas.android.com/apk/res-auto"

android:layout_width="match_parent"

android:layout_height="match_parent">

android:id="@+id/id_menu"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="@mipmap/img_frame_background"

tu:rightPadding="20dp">

android:layout_width="wrap_content"

android:layout_height="fill_parent"

android:orientation="horizontal" >

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:background="@mipmap/qq" >

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:onClick="toggleMenu"

android:text="切换菜单" />

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="#0000" >

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_centerVertical="true"

android:orientation="vertical" >

android:layout_width="match_parent"

android:layout_height="wrap_content" >

android:id="@+id/one"

android:layout_width="50dp"

android:layout_height="50dp"

android:layout_centerVertical="true"

android:layout_marginLeft="20dp"

android:layout_marginTop="20dp"

android:src="@mipmap/img_1" />

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_centerVertical="true"

android:layout_marginLeft="20dp"

android:layout_toRightOf="@id/one"

android:text="第1个Item"

android:textColor="#f0f0f0"

android:textSize="20sp" />

android:layout_width="match_parent"

android:layout_height="wrap_content" >

android:id="@+id/two"

android:layout_width="50dp"

android:layout_height="50dp"

android:layout_centerVertical="true"

android:layout_marginLeft="20dp"

android:layout_marginTop="20dp"

android:src="@mipmap/img_2" />

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_centerVertical="true"

android:layout_marginLeft="20dp"

android:layout_toRightOf="@id/two"

android:text="第2个Item"

android:textColor="#f0f0f0"

android:textSize="20sp" />

android:layout_width="match_parent"

android:layout_height="wrap_content" >

android:id="@+id/three"

android:layout_width="50dp"

android:layout_height="50dp"

android:layout_centerVertical="true"

android:layout_marginLeft="20dp"

android:layout_marginTop="20dp"

android:src="@mipmap/img_3" />

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_centerVertical="true"

android:layout_marginLeft="20dp"

android:layout_toRightOf="@id/three"

android:text="第3个Item"

android:textColor="#f0f0f0"

android:textSize="20sp" />

android:layout_width="match_parent"

android:layout_height="wrap_content" >

android:id="@+id/four"

android:layout_width="50dp"

android:layout_height="50dp"

android:layout_centerVertical="true"

android:layout_marginLeft="20dp"

android:layout_marginTop="20dp"

android:src="@mipmap/img_4" />

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_centerVertical="true"

android:layout_marginLeft="20dp"

android:layout_toRightOf="@id/four"

android:text="第一个Item"

android:textColor="#f0f0f0"

android:textSize="20sp" />

android:layout_width="match_parent"

android:layout_height="wrap_content" >

android:id="@+id/five"

android:layout_width="50dp"

android:layout_height="50dp"

android:layout_centerVertical="true"

android:layout_marginLeft="20dp"

android:layout_marginTop="20dp"

android:src="@mipmap/img_5" />

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_centerVertical="true"

android:layout_marginLeft="20dp"

android:layout_toRightOf="@id/five"

android:text="第5个Item"

android:textColor="#f0f0f0"

android:textSize="20sp" />

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
安卓Android活动社交仿QQ聊天app设计毕业源码案例设计 开发环境: myEclipse/Eclipse/Idea,可以用tomcat的运行包 + Eclipse(手机客户端) + mysql数据库 根据开发的目的和意义,主要有以下几个需求 用户需要进行身份验证(登录,注册) 用户的个人信息管理(修改头像,昵称,性别,签名,手机号,地区。。。) 好友管理 查看天气 社交平台(聊天交友,参加活动,查看附近动态) 活动管理(发布活动,报名参加活动,评论活动) 朋友圈(发布动态,评价动态,查看动态) 模块功能简介 登录注册:用户登陆,注册界面 个人资料:用户修改个人资料 主界面:包含好友列表,好友管理(添加,查找,删除,分组),聊天,运动圈 聊天模块:聊天功能(也可以仿聊天),显示聊天好友,删除聊天记录(删除某个聊天列表), 运动圈:同城活动,发布活动,组织活动,寻找活动,发帖留言 朋友圈:发布动态,评价动态,查看动态 显示天气:附近到某个模块就好,查看天气信息 查找附近:查看附近好友动态,附近活动 -------- 不懂运行,下载完可以私聊问,可远程教学 该资源内项目源码是个人的毕设,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! <项目介绍> 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 --------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值