关闭

QQ侧滑效果的实现与思考

标签: 布局appqqqq侧滑
178人阅读 评论(0) 收藏 举报
分类:

看到很多APP都用到的侧滑效果,由于自己也是自学的初学者,就在网上找了学习资料学习了一下,代码基本上都来自慕课网,在此整理记录一下,方便以后查看,也希望对别人有点帮助!

1.首先写布局文件,侧滑效果其实是在一个activity里添加了2个布局文件(我个人是这么理解的),就像是一张A4纸被横向拉伸了一样。只是我们只能看到一张A4纸张的大小!
1.1侧滑菜单的布局

<?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" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:orientation="vertical"
         >

        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" >

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_marginLeft="10dp"
                android:layout_toRightOf="@+id/ig_01"
                android:text="第一行"
                android:textSize="30sp" />

            <ImageView
                android:id="@+id/ig_01"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_alignParentLeft="true"
                android:layout_alignParentTop="true"
                android:layout_marginLeft="20dp"
                android:src="@drawable/img_1" />
        </RelativeLayout>
         <RelativeLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" >

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_marginLeft="10dp"
                android:layout_toRightOf="@+id/ig_02"
                android:text="第一行"
                android:textSize="30sp" />

            <ImageView
                android:id="@+id/ig_02"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_alignParentLeft="true"
                android:layout_alignParentTop="true"
                android:layout_marginLeft="20dp"
                android:src="@drawable/img_1" />
        </RelativeLayout>


    </LinearLayout>

</RelativeLayout>

效果:这里写图片描述
1.2主布局,这里当然需要写一个继承HorizontalScrollView的自定义布局文件,
注意第一个LinearLayout的宽度是包裹内容,我自己的理解是要包含2个布局肯定不能是匹配了

RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:lly="http://schemas.android.com/apk/res/com.example.qqtest"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.example.SlidingMenu.SlidingMeny
        android:id="@+id/id_menu"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/img_frame_background"
        lly:rightPadding="100dp" >

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:orientation="horizontal" >

            <include layout="@layout/left_menu" />

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@drawable/qq" >

                <Button
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:onClick="toggle"
                    android:text="菜单" />
            </LinearLayout>
        </LinearLayout>
    </com.example.SlidingMenu.SlidingMeny>

</RelativeLayout>

效果图:这里写图片描述

1.3 自定义布局文件,由于也是自学,我的注释也写的很详细了

package com.example.SlidingMenu;

import com.example.qqtest.R;
import com.nineoldandroids.view.ViewHelper;

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

public class SlidingMeny extends HorizontalScrollView {
    private LinearLayout mWapper; // 布局
    private ViewGroup mMenu;// 菜单布局
    private ViewGroup mContent;// 主内容
    private int mMenuWidth;// 菜单宽度
    private int mContentWidth;// 内容宽度
    private int mScreenWidth;// 屏幕宽度
    private int mPaddingRight = 50;// 菜单距离右边距离
    boolean once;// 只获取一次屏幕宽度的标示符
    boolean isopen;// 菜单是否打开标示符(默认值是false)

    /**
     * 设置子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);
            // menu的宽度
            mMenuWidth = mMenu.getLayoutParams().width = mScreenWidth - mPaddingRight;
            // content的宽度
            mContentWidth = mContent.getLayoutParams().width = mScreenWidth;
            once = true;
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    /**
     * 没有使用自定义属性的时候调用(第二步)
     * 
     * @param context
     */
    public SlidingMeny(Context context) {
        this(context, null);
    }

    public SlidingMeny(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    /**
     * 有自定义的属性时候调用(第三步),并且去values去自定义属性
     * 
     * @param context
     * @param attrs
     * @param defStyleAttr
     */

    public SlidingMeny(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        // 获取定义属性
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.slidingM, defStyleAttr, 0);
        // 获取自定义属性的数量
        int n = array.getIndexCount();
        // 遍历自定义属性
        for (int i = 0; i < n; i++) {
            int attr = array.getIndex(i);
            switch (attr) {
            case R.styleable.slidingM_rightPadding:
                // 如果没有写值 就使用默认值50dp,此方法能是把dp转换为像素
                mPaddingRight = array.getDimensionPixelSize(attr, (int) TypedValue
                        .applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, context.getResources().getDisplayMetrics()));
                break;
            }
        }
        // 用完要释放掉
        array.recycle();
        // 获取屏幕宽度
        WindowManager wm = (WindowManager) context.getSystemService(context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(outMetrics);
        mScreenWidth = outMetrics.widthPixels;

    }

    /**
     * 通过设置偏移量,将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) {
        int action = ev.getAction();
        switch (action) {
        case MotionEvent.ACTION_UP:// 用户手指抬起时候
            int scollX = getScrollX();// 获取X轴滑动的距离
            if (scollX >= mMenuWidth / 2) {// X轴距离大于左侧菜单宽度的二分之一就滑动界面
                this.smoothScrollTo(mMenuWidth, 0);// 滑动的距离和动画
                isopen = false;// 并将菜单表示符号置为false

            } else {
                this.smoothScrollTo(0, 0);// 小于二分之一就不滑动界面,返回到原来的
                isopen = true;
            }
            return true;
        }
        return super.onTouchEvent(ev);
    }

    /**
     * 抽屉式效果(第六步)
     */
    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        float scall = l * 1.0f / mMenuWidth;// 缩放比例(可以自己写出自己想要的效果)
        float rightScale = (float) (0.7 + 0.3 * scall);// 右侧缩放
        float leftScale = (float) (1.0 - 0.3 * scall);// 左侧缩放
        float leftAlpha = (float) (1 - 0.4 * scall);// 透明度
        // menu的缩放点以及缩放动画 此时要导入第三方的包,兼容3.0一下。nineoldandroids-2.4.0.jar
        ViewHelper.setPivotX(mMenu, leftScale);// 设置缩放点
        ViewHelper.setPivotY(mMenu, leftScale);
        ViewHelper.setTranslationX(mMenu, mMenuWidth * scall * 0.7f);// 设置缩放动画
        ViewHelper.setAlpha(mMenu, leftAlpha);
        // content 设置缩放的中心点在左边框的中心以及缩放的比例
        ViewHelper.setPivotX(mContent, 0);
        ViewHelper.setPivotY(mContent, mContent.getHeight() / 2);
        ViewHelper.setScaleX(mContent, rightScale);
        ViewHelper.setScaleY(mContent, rightScale);

    }

    /**
     * 打开菜单
     */
    public void openMenu() {
        if (isopen)
            return;
        this.smoothScrollTo(0, 0);
        isopen = true;
    }

    /**
     * 关闭菜单
     */
    public void closeMenu() {
        if (!isopen)
            return;
        this.smoothScrollTo(mMenuWidth, 0);
        isopen = false;
    }

    /**
     * 切换菜单
     */
    public void toggle() {
        if (isopen) {
            closeMenu();
        } else {
            openMenu();
        }
    }

}

1.4 最后在MainActivity里调用,这里只需要注意此处要在主activity里面的自定义布局添加id

package com.example.qqtest;

import com.example.SlidingMenu.SlidingMeny;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;

public class MainActivity extends Activity {

    private SlidingMeny meny;// 获取自定义布局的ID

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);
        meny = (SlidingMeny) findViewById(R.id.id_menu);
    }

    public void toggle(View view) {
        meny.toggle();// 调用开关
    }
}

这个包百度一下就可以找到!
nineoldandroids-2.4.0.jar

1.4自定义属性,在values里新建

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="slidingM">
        <attr name="rightPadding" format="dimension"></attr>
    </declare-styleable>

</resources>
0
0
查看评论

iOS开发总结之仿qq侧滑功能

iOS开发总结之仿qq侧滑功能 前言:本人现在一个人单挑两个app,此项目开发中使用到了手势来实现仿qq的侧滑功能,由于源代码保密,所以这里记录思路 1.效果
  • sunnyboy9
  • sunnyboy9
  • 2016-04-15 00:28
  • 923

DrawerLayout实现侧滑仿QQ界面

简介可以说drawerLayout是因为第三方控件如MenuDrawer等的出现之后,google借鉴而出现的产物。 drawerLayout分为侧边菜单和主内容区两部分,侧边菜单可以根据手势展开与隐藏(drawerLayout自身特性), 主内容区的内容可以随着菜单的点击而变化(这需要使用者自...
  • qq_22348309
  • qq_22348309
  • 2017-02-09 16:35
  • 293

自定义view系列(5)--99.99%实现QQ侧滑删除效果

首先声明本文是基于GitHub上"baoyongzhang"的SwipeMenuListView修改而来, 该项目地址:https://github.com/baoyongzhang/SwipeMenuListView 可以说这个侧滑删除效果是我见过效果最好且比较灵活的项目,...
  • qiang_xi
  • qiang_xi
  • 2016-09-07 16:04
  • 3913

【IOS】仿QQ侧滑菜单

QQSlideMenu利用了Runtime自定义控制器POP手势动画,只要手指在屏幕边缘滑动,当前的控制器的视图就会跟随你的手指移动,当用户松手后,系统会判断手指拖动出来的大小来决定是否要执行控制器的Pop操作。
  • zz2043191420
  • zz2043191420
  • 2015-08-03 14:26
  • 807

仿QQ侧滑效果ViewDragHelper

Google在其support库中为我们提供了DrawerLayout和SlidingPaneLayout两个布局来帮助我们开发侧边栏滑动的效果 ,在这两个布局背后有一个功能强大的ViewDragHelper类,通过ViewDragHelper基本可以实现各种不同的滑动,拖放的需求,是解决各种滑动问...
  • wei_chong_chong
  • wei_chong_chong
  • 2016-03-05 11:00
  • 867

android手把手教你实现QQ侧滑菜单效果

侧滑菜单功能非常常见,借鉴学习了之后,自己总结记录一下 下面实现一种最简单的侧滑菜单,后面再修改代码实现不同的侧滑菜单效果 首先是第一种效果 第一种效果是继承ViewGroup,需要我们自己来测量、滑动处理等。 首先讲解一下思路: 1、继承GroupView重写构造方法 a、我们需要重写三个构造...
  • asd2603934
  • asd2603934
  • 2016-02-22 17:50
  • 1044

简单实现界面的侧滑效果(Swift)仿QQ侧滑效果

废话不多说,看效果图 侧滑.gif viewController // // ViewController.swift // MGSlideViewDemo // // Created by ming on 16/6/5. // Copyright © 2016年...
  • qq_30513483
  • qq_30513483
  • 2016-06-07 17:20
  • 1437

使用DrawerLayout制作仿QQ6.0双侧滑菜单

上面是效果图。 相关实现的源码和文章网上已经很多了,比较流行的做法分别是使用 FrameLayout, HorizontalScrollView或者是DrawerLayout 其实要实现QQ 6.X版本侧滑效果最好的方案是使用HorizontalScrollView,因为左侧菜单的透视效果在Draw...
  • dasa2015
  • dasa2015
  • 2016-11-14 12:07
  • 683

Android使用DrawerLayout仿qq6.6版本侧滑效果

一讲到侧滑菜单,我相信大家都会想到一个开源控件SlidingMenu,在google还没有出来DrawerLayout的时候几乎都是使用Slidingmenu来实现侧滑效果,可以说是效果很不错,自从google出了Drawerlayout以后很多公司就使用了Drawerlayout比如 滴滴打车等等...
  • u014741977
  • u014741977
  • 2016-12-29 14:46
  • 3494

仿QQ6.0主页面侧滑效果

1.概述  最近一直都在带实习生做项目,发现自己好久没有写博客了,这几天更新会比较频繁,今天玩QQ的时候发现QQ主页菜单滑动效果早就变了,实在忍不住晚上就来实现一下了!   2.实现   2.1. 实现的方式多种多样   2.1.1 自定义ViewGroup ,处理其onTouch事件   ...
  • z240336124
  • z240336124
  • 2016-11-02 01:31
  • 22362
    个人资料
    • 访问:11852次
    • 积分:294
    • 等级:
    • 排名:千里之外
    • 原创:15篇
    • 转载:10篇
    • 译文:0篇
    • 评论:2条
    最新评论