zoukankan      html  css  js  c++  java
  • Android--仿QQ侧滑菜单

    首先还是先看一下效果图吧,这个示例在网上能找到很多,我主要在此是做一个小结和一些代码的分析,当是自己在学习过程中的一个积累,因为网上同样的文章很多,所以也无法探究最初的来源是哪里了。

    我们可以从效果图看出,实际上主界面和菜单是两个图,只是在滑动的过程中,菜单逐渐出现,主界面逐渐消失的过程,能实现这个效果的控件还是比较多的,比如:GirdView、ScrollView等滚动视图控件。在此使用的是HorizontalScrollView。

    我们可以通过查看API来了解HorizontalScrollView的基本信息。HorizontalScrollView用于布局的容器,可以放置让用户使用滚动条查看的视图层次结构,允许视图结构比手机的屏幕大. HorizontalScrollView 是一种 框架布局, 这意味着你可以将包含要滚动的完整内容的子视图放入该容器; 该子视图本身也可以是具有复杂层次结构的布局管理器.一般使用横向的 LinearLayout 作为子视图,使用户可以滚动其中显示的条目. HorizontalScrollView 只支持水平方向的滚动。

    一、自定义一个类,用来继承HorizontalScrollView。

    public class SlidingMenu extends HorizontalScrollView {
    
    	public SlidingMenu(Context context) {
    		super(context, null, 0);
    	}
    
    	public SlidingMenu(Context context, AttributeSet attrs) {
    		super(context, attrs, 0);
    
    	}
    
    	public SlidingMenu(Context context, AttributeSet attrs, int defStyle) {
    		super(context, attrs, defStyle);
    	}
    }

    在完成这个类的创建之后,我们会发现,此处有三个构造方法,所以我们先介绍一下这三个构造方法,对于理解自定义控件也是有帮助的。

    1.只有一个参数的构造方法:一般是在java代码创建视图的时候被调用,如果是从xml填充的视图,就不会调用这个.

    2.有两个参数的构造方法:这个是在xml创建但是没有指定style的时候被调用。

    3.三个参数的构造方法:这个就很容易理解了,是有指定的style的时候被调用。

    二、完成布局文件

    在一开始的时候说过,该效果的时候就是主界面和菜单两个界面平行排列在HorizontalScrollView布局容器中,当有滑动事件发生的时候再慢慢移动一个,从而显示出另外一个。

    所以布局文件的完成就相对比较简单了。

    activity_main.xml:(其中涉及到自定义属性的部分在后面讲解)

    <com.ithaha.SlidingMenu.SlidingMenu xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/id_menu"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:zhy="http://schemas.android.com/apk/res/com.ithaha.SlidingMenu"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:scrollbars="none"
        zhy:rightPadding="100dp" >
    
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="fill_parent"
            android:orientation="horizontal" >
    
            <include layout="@layout/layout_menu" />
    
            <LinearLayout
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:background="@drawable/qq" >
    
                <Button
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:onClick="toggleMenu"
                    android:text="切换菜单" />
            </LinearLayout>
        </LinearLayout>
    
    </com.ithaha.SlidingMenu.SlidingMenu>

    layout_menu.xml:

    这儿就是一些简单的菜单显示了,由于代码过长且无特别之后就不在此贴出,具体的可以参看源码。

    三、完成自定义的类,实现主要功能

    在完成之前两个步骤之后,我们可以先运行程序看一下。运行程序后,发现界面已经是可以左右滑动的了,只是效果太差了(效果图如下),所以我们需要重写一些方法来使界面更加的美观合理了。

              

    从刚才运行的效果图可以看到,界面图片大小和屏幕尺寸有明显的不搭配,所以我们首先需要重写的第一个方法是:

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)

    评估视图及其内容,以决定其宽度和高度.此方法由 measure(int, int) 调用,子类可以重载以提供更精确、更有效率的衡量其内容尺寸的方法

    	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    		/**
    		 * 显示的设置一个宽度
    		 */
    		if (!once) {
    			// 返回指定位置的视图。
    			LinearLayout wrapper = (LinearLayout) getChildAt(0);
    			ViewGroup menu = (ViewGroup) wrapper.getChildAt(0);
    			ViewGroup content = (ViewGroup) wrapper.getChildAt(1);
    
    			// 菜单的宽度 = 屏幕的宽度 - 需要所留出来的边界
    			mMenuWidth = mScreenWidth - mMenuRightPadding;
    			// 菜单宽度的一半
    			mHalfMenuWidth = mMenuWidth / 2;
    			// 重新加载宽度
    			menu.getLayoutParams().width = mMenuWidth;
    			content.getLayoutParams().width = mScreenWidth;
    
    		}
    		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    	}

    由于只是定义了mMenuRightPadding(菜单界面所需要距离右边界的距离),但是没有实际给值,所以现在的程序运行出来,只是两个完整的界面,如果给mMenuRightPadding赋值以后,那么就会有一个较好的效果了。但是由于mMenuRightPadding我们把它设置成为了一个自定义属性,所以在此也就顺便复习一下自定义属性的使用了。

    自定义属性的简单使用:

    1.需要在布局文件中先声明出一个命名空间:xmlns:ithaha="http://schemas.android.com/apk/res/com.ithaha.SlidingMenu"

    xmlns : XML命名空间的缩写,为固定格式。

    ithaha:属性名的前缀。就如我们使用控件自带属性一样,属性名字前面有一个android:

    http://schemas.android.com/apk/res/ : 为固定格式

    com.ithaha.SlidingMenu:所加载属性的包名

    2.在res/values/下新建一个attrs.xml的文件

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <!-- 声明属性集的名称 -->
        <declare-styleable name="SlidingMenu">
            
            <!-- 声明一个属性 name是rightPadding 类型是 dimension-->
            <attr name="rightPadding" format="dimension"/>
            
        </declare-styleable>
    </resources>

    3.在.java文件中加载出属性(见源码)

    4.在布局文件中使用。

    四、最终功能的完善

    完成之前三个步骤之后,能达到一个基本的效果了,但是界面的切换是自己在屏幕上滑动了多少距离,界面就切换多少,使用起来不是很方便,所以我们在此继续改善。

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

    通过判断手指在屏幕上滑动的距离,然后直接将界面进行相应的移动就能达到我们想要的效果了。

    五、源码下载

    点我下载    o(︶︿︶)o

  • 相关阅读:
    Security基础(二):SELinux安全防护、加密与解密应用、扫描与抓包分析
    Security基础(一):Linux基本防护措施、使用sudo分配管理权限、提高SSH服务安全
    勤奋之致,功成之始
    Database基础(七):部署集群基础环境、MySQL-MMM架构部署、MySQL-MMM架构使用
    Database基础(六):实现MySQL读写分离、MySQL性能调优
    Database基础(五):使用binlog日志、XtraBackup备份工具、MySQL AB复制
    Database基础(四):密码恢复及设置、 用户授权及撤销、数据备份与恢复、MySQL管理工具
    Database基础(三):SQL数据导入/导出、 操作表记录、查询及匹配条件
    vue-打包上线
    vue报错-Object(...) is not a function
  • 原文地址:https://www.cnblogs.com/whyalwaysme/p/4415927.html
Copyright © 2011-2022 走看看