仿QQ6,androidapp开发语言

import android.util.AttributeSet;

import android.util.DisplayMetrics;

import android.view.View;

import android.view.ViewGroup;

import android.view.WindowManager;

import android.widget.HorizontalScrollView;

public class mySlidingMenu extends HorizontalScrollView {

private int mScreenWidth;

private View mMenu;

private View mContent;

private int mMenuWidth;

private int mContentWidth;

private int mScrennHeight;

public mySlidingMenu(Context context) {

this(context,null);

}

public mySlidingMenu(Context context, AttributeSet attrs) {

this(context, attrs,0);

}

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

super(context, attrs, defStyleAttr);

//获取屏幕宽度

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

DisplayMetrics metrics = new DisplayMetrics();

wm.getDefaultDisplay().getMetrics(metrics);

mScreenWidth = metrics.widthPixels;

mScrennHeight = metrics.heightPixels;

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

//初始化宽度、高度

int width = 0;

int height = 0;

//获取子代

ViewGroup ll_child = (ViewGroup) getChildAt(0);

mMenu = ll_child.getChildAt(0);

mContent = ll_child.getChildAt(1);

//设置菜单 内容的宽度

mMenuWidth = mMenu.getLayoutParams().width = mScreenWidth - 400;

mContentWidth = mContent.getLayoutParams().width = mScreenWidth;

//设置自定义组件的宽高

width = mMenuWidth + mContentWidth;

height = mScrennHeight;

setMeasuredDimension(width,height);

}

}

我们发现布局结构的确出来了,但是划不动, 最大的可能就是我们设置宽高的时机不对,通过翻阅资料,我发现我们应该写在布局解析完成这个时间节点

package com.wust.myhorizontalscrollview;

import android.content.Context;

import android.util.AttributeSet;

import android.util.DisplayMetrics;

import android.view.View;

import android.view.ViewGroup;

import android.view.WindowManager;

import android.widget.HorizontalScrollView;

public class mySlidingMenu extends HorizontalScrollView {

private int mScreenWidth;

private View mMenu;

private View mContent;

private int mMenuWidth;

private int mContentWidth;

private int mScrennHeight;

public mySlidingMenu(Context context) {

this(context,null);

}

public mySlidingMenu(Context context, AttributeSet attrs) {

this(context, attrs,0);

}

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

super(context, attrs, defStyleAttr);

//获取屏幕宽度

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

DisplayMetrics metrics = new DisplayMetrics();

wm.getDefaultDisplay().getMetrics(metrics);

mScreenWidth = metrics.widthPixels;

mScrennHeight = metrics.heightPixels;

}

@Override

protected void onFinishInflate() {

super.onFinishInflate();

//获取子代

ViewGroup ll_child = (ViewGroup) getChildAt(0);

mMenu = ll_child.getChildAt(0);

mContent = ll_child.getChildAt(1);

//设置菜单 内容的宽度

mMenuWidth = mMenu.getLayoutParams().width = mScreenWidth - 400;

//设置布局宽度的第二种方法

ViewGroup.LayoutParams contentLayoutParams = mContent.getLayoutParams();

mContentWidth = contentLayoutParams.width = mScreenWidth;

mContent.setLayoutParams(contentLayoutParams);

}

}

这个时候,你就会发现屏幕可以滑动了

第四步:优化

经过上面三步,侧滑菜单我们就做完了,下面所讲是为了优化用户体验

  • 优化一:最初渲染页面的时候,菜单栏是关闭的

在这一步中要注意 关闭菜单的时机,即到底写在那个函数里

package com.wust.myhorizontalscrollview;

import android.content.Context;

import android.util.AttributeSet;

import android.util.DisplayMetrics;

import android.view.View;

import android.view.ViewGroup;

import android.view.WindowManager;

import android.widget.HorizontalScrollView;

public class mySlidingMenu extends HorizontalScrollView {

private int mScreenWidth;

private View mMenu;

private View mContent;

private int mMenuWidth;

private int mContentWidth;

private int mScrennHeight;

public mySlidingMenu(Context context) {

this(context,null);

}

public mySlidingMenu(Context context, AttributeSet attrs) {

this(context, attrs,0);

}

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

super(context, attrs, defStyleAttr);

//获取屏幕宽度

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

DisplayMetrics metrics = new DisplayMetrics();

wm.getDefaultDisplay().getMetrics(metrics);

mScreenWidth = metrics.widthPixels;

mScrennHeight = metrics.heightPixels;

}

@Override

protected void onFinishInflate() {

super.onFinishInflate();

//获取子代

ViewGroup ll_child = (ViewGroup) getChildAt(0);

mMenu = ll_child.getChildAt(0);

mContent = ll_child.getChildAt(1);

//设置菜单 内容的宽度

mMenuWidth = mMenu.getLayoutParams().width = mScreenWidth - 400;

//设置布局宽度的第二种方法

ViewGroup.LayoutParams contentLayoutParams = mContent.getLayoutParams();

mContentWidth = contentLayoutParams.width = mScreenWidth;

mContent.setLayoutParams(contentLayoutParams);

}

@Override

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

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

closeMenu();

}

private void closeMenu(){

smoothScrollTo(mMenuWidth,0);

}

private void openMenu(){

smoothScrollTo(0,0);

}

}

  • 优化二:判断手指抬起时是否超过菜单宽度一半,超过即打开菜单,没有超过即关闭菜单

在这一步中要区别于我们上讲 仿QQ6.0主页面侧滑效果 中的滑动正负观,在这我就不过多赘述,大家自己动手实践就知道了

@Override

public boolean onTouchEvent(MotionEvent ev) {

switch(ev.getAction()){

//自己处理 手指抬起事件 所以 return true

case MotionEvent.ACTION_UP:

{

//就是这里要注意,因为最开始 getScrollX() 的值是 mMenuWidth

if (getScrollX() > mMenuWidth/2){

closeMenu();

}else {

openMenu();

}

return true;

}

}

return super.onTouchEvent(ev);

}

  • 优化三:处理快速滑动手势

在这个里面主要用到了一个类 GestureDetector

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

super(context, attrs, defStyleAttr);

//获取屏幕宽度

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

DisplayMetrics metrics = new DisplayMetrics();

wm.getDefaultDisplay().getMetrics(metrics);

mScreenWidth = metrics.widthPixels;

mScrennHeight = metrics.heightPixels;

//第一步:在构造方法里创建 GestureDetector 类

mGestureDetector = new GestureDetector(context, new myGestureListener());

}

@Override

public boolean onTouchEvent(MotionEvent ev) {

//第二步:在 onTouchEvent 中拦截快速滑动
手势

if (mGestureDetector.onTouchEvent(ev)){

return mGestureDetector.onTouchEvent(ev);

}

switch(ev.getAction()){

//自己处理 手指抬起事件 所以 return true

case MotionEvent.ACTION_UP:

{

//就是这里要注意,因为最开始 getScrollX() 的值是 mMenuWidth

if (getScrollX() > mMenuWidth/2){

closeMenu();

}else {

openMenu();

}

return true;

}

}

return super.onTouchEvent(ev);

}

//第三步:编写 myGestureListener

private class myGestureListener extends GestureDetector.SimpleOnGestureListener {

@Override

public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

System.out.println(“velocityX ->” + velocityX);

if (menuIsOpen){

//菜单打开状态

if (velocityX < -500){

closeMenu();

return true;

}

}else {

//菜单关闭状态

if (velocityX > 500){

openMenu();

return true;

}

}

return false;

}

}

//在下面两个方法中添加了菜单是否打开标志

private void closeMenu(){

smoothScrollTo(mMenuWidth,0);

menuIsOpen = false;

}

private class myGestureListener extends GestureDetector.SimpleOnGestureListener {

@Override

public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

System.out.println(“velocityX ->” + velocityX);

if (menuIsOpen){

//菜单打开状态

if (velocityX < -500){

closeMenu();

return true;

}

}else {

//菜单关闭状态

if (velocityX > 500){

openMenu();

return true;

}

}

return false;

}

}

//在下面两个方法中添加了菜单是否打开标志

private void closeMenu(){

smoothScrollTo(mMenuWidth,0);

menuIsOpen = false;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值