QQ 5.0侧滑HorizontalScrollView以及自定义ViewGroup

一般侧滑的实现:

自定义的ViewGroup(menu+content)

ouTouchEvent事件改变ViewGroup的LeftMargin。

大于菜单的一半显示,小于则隐藏(使用Scroller或者LeftMargin加Thread)。

新的方法:

继承HorizontalScrollView,由于menu+content一定是大于屏幕的宽度,那么水平滚动条会自动进行拖动,

我们只要做偏移的距离还显示或隐藏menu或content。

1.最简单的侧滑


自定义ViewGroup即HorizontalScrollView。并复写其中的三个主要方法:

1.onMeasure:即决定内部的View的宽和高,以及自己的宽和高;

2.onLayout:决定子View的放置位置;

3.onTouchEvent:判断用户的状态,控制内部View效果。

scrollTo和scrollBy方法:是scrollView的方法,因为view和Canvas是没有边界的。

public void scrollTo(int x, int y)

说明:在当前视图内容偏移至(x , y)坐标处,即显示(可视)区域位于(x , y)坐标处。

public void scrollBy(int x, int y)

说明:在当前视图内容继续偏移(x , y)个单位,显示(可视)区域也跟着偏移(x,y)个单位。显示部分在大的view中也偏移了位置。

onTouchEvent事件类型:

ACTION_DOWN: 表示用户开始触摸.

ACTION_MOVE: 表示用户在移动(手指或者其他)

ACTION_UP:表示用户抬起了手指

ACTION_CANCEL:表示手势被取消了

publicclassSlidingMenuextendsHorizontalScrollView{
   privateLinearLayout mWapper;
   privateViewGroup mMenu;
   privateViewGroup mContent;
   privateint mScreenWidth;
   privateint mMenuWidth;
   privateint mMenuRightPadding =50;//menu与屏幕右侧的间距 、
   privateboolean once =false;

   publicSlidingMenu(Context context,AttributeSet attrs){
   super(context, attrs);
   WindowManager wm =    (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
   DisplayMetrics outMetrics =newDisplayMetrics();
   wm.getDefaultDisplay().getMetrics(outMetrics);
   mScreenWidth = outMetrics.widthPixels;
   //把dp转换为px
   mMenuRightPadding =(int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,50,
   context.getResources().getDisplayMetrics());
}
/*
*设置子view的宽和高,和自己的宽和高(子view确定好之后就确定自己的了)
*/
@Override
protectedvoid onMeasure(int widthMeasureSpec,int heightMeasureSpec){
   super.onMeasure(widthMeasureSpec, heightMeasureSpec);
   if(!once){
   mWapper =(LinearLayout)getChildAt(0);
   mMenu =(ViewGroup)mWapper.getChildAt(0);
   mContent =(ViewGroup)mWapper.getChildAt(1);
   mMenuWidth = mMenu.getLayoutParams().width =     mScreenWidth - mMenuRightPadding;
   mContent.getLayoutParams().width = mScreenWidth;
   //子view宽度决定之后,本身也就决定了
   once =true;
    }
}
/*
*通过设置偏移量,将menu隐藏
*/
@Override
protectedvoid 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
publicboolean onTouchEvent(MotionEvent ev){
     int action = ev.getAction();
     switch(action){
       caseMotionEvent.ACTION_UP:
       int scrollX = getScrollX();//scrollX是隐藏是在左边的宽度
       if(scrollX >= mMenuWidth/2){
       this.smoothScrollTo(mMenuWidth,0);
       }
       else{
         this.smoothScrollTo(0,0);
       }
       returntrue;
      }
      returnsuper.onTouchEvent(ev);
   }
}

接着在XML中使用,要使用完整包名,只能放一个子控件,因为是FrameLayout。

  1. <com.example.kevin.myapplication.SlidingMenu
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <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">
      </LinearLayout>
    </LinearLayout>
    </com.example.kevin.myapplication.SlidingMenu>

1.1自定义属性

自定义属性:允许用户设置菜单离屏幕右侧属性,常用在view和viewGroup。资源所定义的属性发挥作用取决于自定义组件的代码实现。

1.书写XML文件value/attr.xml;

放在values目录下,属性资源文件的根元素是<resources../>,包含两个元素。

attr子元素:定义一个属性值。

declare-styleable:定义一个styleable对象,每个styleable对象就是一组attr属性的集合。

  1. <?xml version="1.0" encoding="utf-8"?>
    <resources>
    <attr name="rightPadding" format="dimension"/>
    <declare-styleable name="SlidingMenu">
    <attr name="rightPadding"/>
    </declare-styleable>
    </resources>

2.在布局文件进行使用,xmlns定义命名空间。

  1. <com.example.kevin.myapplication.SlidingMenu
    android:id="@+id/id_menu"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/img_frame_background"
    my: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="toggleMenu"
    android:text="切换菜单"/>
    </LinearLayout>
    </LinearLayout>
    </com.example.kevin.myapplication.SlidingMenu>

更改menu距离右边距离100dp。

3.在构造方法中(3个参数的构造方法)中获得我们设置的值

接着使用TypeArray。它是一个存放恢复obtainStyledAttributes(AttributeSet, int[], int, int)或 obtainAttributes(AttributeSet, int[])  值的一个

数组容器 。当操作完成以后,一定要调用recycle()方法。

  1. //获取定义的属性
    TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.SlidingMenu);
       int n = a.getIndexCount();//拿到自定义属性个数
       for(int i=0;i<n;i++){
       int attr = a.getIndex(i);
       switch(attr){
          case R.styleable.SlidingMenu_rightPadding:
          mMenuRightPadding = a.getDimensionPixelSize(attr,(int)TypedValue.
          applyDimension(TypedValue.COMPLEX_UNIT_DIP,50,
          context.getResources().getDisplayMetrics()));
          break;
        }
    }
      

2.抽屉式侧滑

菜单仿佛在内容区域以下:当左边content拉出多少,左边menu就设置menuWidth-拉出距离的偏移量。

这里需要设置属性动画(3.0引入的):TranslationX。为了往下兼容必须引入com.nineoldandroids:library:2.4.0这个jar。

选择调用动画的时机可用 onScrollChanged。

  1. /*
    *滚动发生时
    */
    @Override
    protectedvoid onScrollChanged(int l,int t,int oldl,int oldt){
       super.onScrollChanged(l, t, oldl, oldt);
       float scale = l*1.0f/mMenuWidth;//1~0
       //调用属性动画设置anslationX。
       ViewHelper.setTranslationX(mMenu, mMenuWidth * scale);
    }

l相当于就是getScrillX()。

3.QQ式侧滑

区别在于:scale:1~0

1.内容区域缩放1~0.7缩放效果, 0.7+0.3*scale;

2.菜单的偏移量需要修改;

3.菜单的显示有缩放以及透明度0.7~1,1.0 - 0.3*scale。

0.6~1,0.6 + 0.4*(1-scale)。

  1. protectedvoid onScrollChanged(int l,int t,int oldl,int oldt){
        super.onScrollChanged(l, t, oldl, oldt);
        float scale = l*1.0f/mMenuWidth;//1~0
        //调用属性动画设置anslationX。
        ViewHelper.setTranslationX(mMenu, mMenuWidth * scale);
        float rightScale =0.7f+0.3f* scale;
        float leftScale =1.0f- scale *0.3f;
        float leftAlpha =0.6f+0.4f*(1- scale);
        ViewHelper.setScaleX(mMenu, leftScale);
        ViewHelper.setScaleY(mMenu, leftScale);
        ViewHelper.setAlpha(mMenu, leftAlpha);
        // 设置content的缩放的中心点
        ViewHelper.setPivotX(mContent,0);
        ViewHelper.setPivotY(mContent, mContent.getHeight()/2);
        ViewHelper.setScaleX(mContent, rightScale);
        ViewHelper.setScaleY(mContent, rightScale);
    }

慕课网学习笔记:http://www.imooc.com/learn/211

参考:

http://blog.csdn.net/qinjuning/article/details/7247126   scrollTo 以及 scrollBy方法使用说明

http://blog.csdn.net/qinjuning/article/details/7419207    侧滑实现

http://my.oschina.net/banxi/blog/56421                        motionevent

时间: 2024-10-10 16:06:09

QQ 5.0侧滑HorizontalScrollView以及自定义ViewGroup的相关文章

Android 高仿 QQ5.0 侧滑菜单效果 自定义控件来袭【学习鸿洋_视频博客笔记总结】

学习鸿洋博客:http://blog.csdn.net/lmj623565791/article/details/39257409 学习鸿洋视频:慕课网视频 看看Android 高仿 QQ5.0 侧滑菜单效果 自定义控件实现效果: 技术上,继承HorizontalScrollView 加上自定义ViewGroup来实现: 1.onMeasure:决定内部View(子View)的宽和高,以及自己的宽和高 2.onLayout:决定子View的放置位置 3.onTouchEvent[监听动作] 自定

【Android自定义ViewGroup】不一样的轮子,巧用类变量解决冲突,像IOS那样简单的使用侧滑删除,一个控件搞定Android item侧滑删除菜单。

================================================================================== [1 序言] 侧滑删除的轮子网上有很多,最初在github上看过一个,还是ListView时代,那是一个自定义ListView 实现侧滑删除的,当初就觉得这种做法不是最佳,万一我项目里又同时有自定义ListView的需求,会增加复杂度. 写这篇文章之前又通过毒度搜了一下,排名前几的CSDN文章,都是通过自定义ListVIew和Vie

Android自定义ViewGroup打造各种风格的SlidingMenu

看鸿洋大大的QQ5.0侧滑菜单的视频课程,对于侧滑的时的动画效果的实现有了新的认识,似乎打通了任督二脉,目前可以实现任意效果的侧滑菜单了,感谢鸿洋大大!! 鸿洋大大用的是HorizontalScrollView来实现的侧滑菜单功能,HorizontalScrollView的好处是为我们解决了滑动功能,处理了滑动冲突问题,让我们使用起来非常方便,但是滑动和冲突处理都是android中的难点,是我们应该掌握的知识点,掌握了这些,我们可以不依赖于系统的API,随心所欲打造我们想要的效果,因此这篇文章我

彷QQ5.0侧滑菜单(自定义控件--SlideMenu的实现)

一般的侧滑的实现 ViewGroup  Menu + Content onTouchEvent MOVE:ViewGroup的leftMargin UP:根据显示菜单的高度,决定将其隐藏或者显示 1.Scroller 2.LeftMargin + Thread 彷QQ5.0侧滑菜单的实现,使用另外的一种方法,继承HorizontalScrollView 一.自定义ViewGroup 1.构造方法的选择,获得一些需要用到的值 2.onMeasure 计算子View的宽和高,以及设置自己的宽和高 3

Android QQ5.0侧滑菜单

背景 相信大家用过QQ的人,都会知道QQ有这样的一个功能,那就是他的菜单,感觉就像抽屉一样被拉出来的感觉,感觉很拉风啊,酷酷的,如果你有一种想要把它给弄清楚,想明白,这是一个好东西,你要把它变成自己的,那么现在就是你的机会,也在此恭喜你,你终于初步具有一个向中级工程师迈进的门票了,因为你已经跨出第一步了. 一:效果图,走一走,天下我有 二:实现步骤 1.菜单和内容布局的实现 2.自定义viewgroup 3.给注册监听事件,添加动画效果 三:示例源码 ①菜单布局 <?xml version=&quo

(转)ViewDragHelper实现QQ5.0侧滑并处理与ViewPager的滑动冲突

最近在做项目,涉及到类似QQ的页面的滑动.但是却遇到了侧滑和ViewPager冲突的问题,头疼了很长时间,最后在网上发现了这篇博客,转载过来供自己学习参考(写这篇博客的原创作者,因为我发现这篇博客的地方也是别人转载的,所以具体是有哪位大牛完成的我也不得而知.转载文章不能标出原创作者和出处,请见谅) QQ5.0的侧滑效果有多种实现方式, 如http://blog.csdn.net/lmj623565791/article/details/39257409 就是利用HorizontalScrollV

仿QQ5.0侧滑菜单效果

慕课网视频 今天我们来继承 HorizontalScrollView 实现比较炫酷的侧滑菜单效果 继承HorizontalScrollView的好处有两点: 1.不用在写 MOVE 事件 2.不用解决 和 ListView 的冲突 以下是实现步骤: 自定义 ViewGroup,实现它的几个方法 1.onMeasure       决定内部 View (子 View) 的宽和高,以及呢,自己的宽和高 /** * 设置 自己的宽和高 子 View 的宽和高 * * @param widthMeasu

ViewDragHelper实现QQ5.0侧滑并处理与ViewPager的滑动冲突

QQ5.0的侧滑效果有多种实现方式, 如http://blog.csdn.net/lmj623565791/article/details/39257409   就是利用HorizontalScrollView实现的,简单实用; 如http://blog.csdn.net/manoel/article/details/39013095/   通过改造SlidingMenu实现,没有改变原有SlidingMenu功能,屏幕边缘侧滑也可以.... 相对来说ViewDragHelper实现方式最为复杂

【Android】快速开发偷懒必备,一句话搞定所有ViewGroup的Adapter . 支持自定义ViewGroup

转载请标明出处: http://blog.csdn.net/zxt0601/article/details/53576092 本文出自:[张旭童的博客](http://blog.csdn.net/zxt0601) 代码传送门:喜欢的话,随手点个star.多谢 https://github.com/mcxtzhang/all-base-adapter 概述 开发中,经常会用到动态在ScrollView.LinearLayout里addView的事,尤其是ItemView一样时,每次都要写一大堆代码