怎样实现安卓中侧滑功能

首先本文我是参照鸿洋大师的博客http://blog.csdn.net/lmj623565791/article/details/39257409  来学习,在自己根据

他的介绍实现了qq侧滑功能,这里我简单的做一下介绍并且巩固一下自己的知识。只有自己去敲了才能发现问题。

首先说下思路,这里我主要是通过自定义HorizontalScrollView来实现一个侧滑效果。一般自定义view的话都是在

onMeasure()、onLayout()、ondraw()、onTouchEvent()还有事件分发机制方法里面做文章。这里我们主要

是通过onMeasure()方法里面测量我们添加滑动view的大小,在onLayout()方法里面设置menu view的位置。最后

在touch事件里面处理up时滑动view的位置,可能你会问为什么不在move事件里面处理呢?嘿嘿,这就是我们使  

HorizontalScrollView的优势了,move事件它已经给我们处理好了。最后实现侧滑的重点就是滑动的逻辑问题了,还

有就是实现抽屉式侧滑的属性动画。具体我们就看我一一介绍:


1.我们先来看下布局文件


首先是menu.xml

[java]  view plain  copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="vertical"  
  6.     android:background="#0000"  
  7.     >  
  8.     <LinearLayout  
  9.         android:layout_width="match_parent"  
  10.         android:layout_height="wrap_content"  
  11.         android:layout_centerInParent="true"  
  12.         android:orientation="vertical" >  
  13.   
  14.         <RelativeLayout  
  15.             android:layout_width="fill_parent"  
  16.             android:layout_height="wrap_content" >  
  17.   
  18.             <ImageView  
  19.                 android:id="@+id/id_img1"  
  20.                 android:layout_width="50dp"  
  21.                 android:layout_height="50dp"  
  22.                 android:layout_centerVertical="true"  
  23.                 android:layout_marginLeft="20dp"  
  24.                 android:layout_marginTop="20dp"  
  25.                 android:src="@drawable/img_1" />  
  26.   
  27.             <TextView  
  28.                 android:layout_width="wrap_content"  
  29.                 android:layout_height="wrap_content"  
  30.                 android:layout_centerVertical="true"  
  31.                 android:layout_marginLeft="20dp"  
  32.                 android:layout_toRightOf="@id/id_img1"  
  33.                 android:text="第一个Item"  
  34.                 android:textColor="#ffffff"  
  35.                 android:textSize="20sp" />  
  36.         </RelativeLayout>  
  37.   
  38.         <RelativeLayout  
  39.             android:layout_width="fill_parent"  
  40.             android:layout_height="wrap_content" >  
  41.   
  42.             <ImageView  
  43.                 android:id="@+id/id_img2"  
  44.                 android:layout_width="50dp"  
  45.                 android:layout_height="50dp"  
  46.                 android:layout_centerVertical="true"  
  47.                 android:layout_marginLeft="20dp"  
  48.                 android:layout_marginTop="20dp"  
  49.                 android:src="@drawable/img_2" />  
  50.   
  51.             <TextView  
  52.                 android:layout_width="wrap_content"  
  53.                 android:layout_height="wrap_content"  
  54.                 android:layout_centerVertical="true"  
  55.                 android:layout_marginLeft="20dp"  
  56.                 android:layout_toRightOf="@id/id_img2"  
  57.                 android:text="第二个Item"  
  58.                 android:textColor="#ffffff"  
  59.                 android:textSize="20sp" />  
  60.         </RelativeLayout>  
  61.   
  62.         <RelativeLayout  
  63.             android:layout_width="fill_parent"  
  64.             android:layout_height="wrap_content" >  
  65.   
  66.             <ImageView  
  67.                 android:id="@+id/id_img3"  
  68.                 android:layout_width="50dp"  
  69.                 android:layout_height="50dp"  
  70.                 android:layout_centerVertical="true"  
  71.                 android:layout_marginLeft="20dp"  
  72.                 android:layout_marginTop="20dp"  
  73.                 android:src="@drawable/img_3" />  
  74.   
  75.             <TextView  
  76.                 android:layout_width="wrap_content"  
  77.                 android:layout_height="wrap_content"  
  78.                 android:layout_centerVertical="true"  
  79.                 android:layout_marginLeft="20dp"  
  80.                 android:layout_toRightOf="@id/id_img3"  
  81.                 android:text="第三个Item"  
  82.                 android:textColor="#ffffff"  
  83.                 android:textSize="20sp" />  
  84.         </RelativeLayout>  
  85.   
  86.         <RelativeLayout  
  87.             android:layout_width="fill_parent"  
  88.             android:layout_height="wrap_content" >  
  89.   
  90.             <ImageView  
  91.                 android:id="@+id/id_img4"  
  92.                 android:layout_width="50dp"  
  93.                 android:layout_height="50dp"  
  94.                 android:layout_centerVertical="true"  
  95.                 android:layout_marginLeft="20dp"  
  96.                 android:layout_marginTop="20dp"  
  97.                 android:src="@drawable/img_4" />  
  98.   
  99.             <TextView  
  100.                 android:layout_width="wrap_content"  
  101.                 android:layout_height="wrap_content"  
  102.                 android:layout_centerVertical="true"  
  103.                 android:layout_marginLeft="20dp"  
  104.                 android:layout_toRightOf="@id/id_img4"  
  105.                 android:text="第四个Item"  
  106.                 android:textColor="#ffffff"  
  107.                 android:textSize="20sp" />  
  108.         </RelativeLayout>  
  109.   
  110.         <RelativeLayout  
  111.             android:layout_width="fill_parent"  
  112.             android:layout_height="wrap_content" >  
  113.   
  114.             <ImageView  
  115.                 android:id="@+id/id_img5"  
  116.                 android:layout_width="50dp"  
  117.                 android:layout_height="50dp"  
  118.                 android:layout_centerVertical="true"  
  119.                 android:layout_marginLeft="20dp"  
  120.                 android:layout_marginTop="20dp"  
  121.                 android:src="@drawable/img_5" />  
  122.   
  123.             <TextView  
  124.                 android:layout_width="wrap_content"  
  125.                 android:layout_height="wrap_content"  
  126.                 android:layout_centerVertical="true"  
  127.                 android:layout_marginLeft="20dp"  
  128.                 android:layout_toRightOf="@id/id_img5"  
  129.                 android:text="第五个Item"  
  130.                 android:textColor="#ffffff"  
  131.                 android:textSize="20sp" />  
  132.         </RelativeLayout>  
  133.   
  134.         <RelativeLayout  
  135.             android:layout_width="fill_parent"  
  136.             android:layout_height="wrap_content" >  
  137.   
  138.             <ImageView  
  139.                 android:id="@+id/id_img6"  
  140.                 android:layout_width="50dp"  
  141.                 android:layout_height="50dp"  
  142.                 android:layout_centerVertical="true"  
  143.                 android:layout_marginLeft="20dp"  
  144.                 android:layout_marginTop="20dp"  
  145.                 android:src="@drawable/img_1" />  
  146.   
  147.             <TextView  
  148.                 android:layout_width="wrap_content"  
  149.                 android:layout_height="wrap_content"  
  150.                 android:layout_centerVertical="true"  
  151.                 android:layout_marginLeft="20dp"  
  152.                 android:layout_toRightOf="@id/id_img6"  
  153.                 android:text="第一个Item"  
  154.                 android:textColor="#ffffff"  
  155.                 android:textSize="20sp" />  
  156.         </RelativeLayout>  
  157.     </LinearLayout>  
  158.   
  159. </RelativeLayout>  

接下来就是主布局:
[java]  view plain  copy
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:layout_width="match_parent"  
  3.     android:layout_height="match_parent" >  
  4.   
  5.     <com.example.chulu.newqqmodel.QQHorizontalScrollView  
  6.         android:id="@+id/id_menu"  
  7.         android:layout_width="match_parent"  
  8.         android:layout_height="match_parent"  
  9.         android:background="@drawable/img_frame_background" >  
  10.   
  11.         <LinearLayout  
  12.             android:layout_width="match_parent"  
  13.             android:layout_height="match_parent"  
  14.             android:orientation="horizontal" >  
  15.   
  16.             <include layout="@layout/menu" />  
  17.   
  18.             <LinearLayout  
  19.                 android:layout_width="match_parent"  
  20.                 android:layout_height="match_parent"  
  21.                 android:background="@drawable/qq" >  
  22.   
  23.                 <Button  
  24.                     android:onClick="toggleMenu"  
  25.                     android:layout_width="wrap_content"  
  26.                     android:layout_height="wrap_content"  
  27.                     android:text="切换菜单"  
  28.                     />  
  29.             </LinearLayout>  
  30.         </LinearLayout>  
  31.     </com.example.chulu.newqqmodel.QQHorizontalScrollView>  
  32.   
  33. </RelativeLayout>  


这里的布局还是很好理解的,唯一的亮点我认为就是<include>,关于ui效率可以看下api的file:///D:/adt-bundle-windows-x86_64-20131030/sdk/docs/guide/topics/resources/layout-resource.html 介绍


 2.下面我们就来介绍一下自定义HorizontalScrollView

[java]  view plain  copy
  1. import android.content.Context;  
  2. import android.util.AttributeSet;  
  3. import android.util.DisplayMetrics;  
  4. import android.util.TypedValue;  
  5. import android.view.MotionEvent;  
  6. import android.view.ViewGroup;  
  7. import android.view.WindowManager;  
  8. import android.widget.HorizontalScrollView;  
  9. import android.widget.LinearLayout;  
  10.   
  11. import com.nineoldandroids.view.ViewHelper;  
  12.   
  13. /** 
  14.  * Created by chulu on 2015/2/28. 
  15.  */  
  16. public class QQHorizontalScrollView extends HorizontalScrollView {  
  17.     /** 
  18.      * 横向滚动条里面会有一个linearLayout 
  19.      */  
  20.     private LinearLayout mLinearMatch;  
  21.   
  22.     /** 
  23.      * 屏幕宽度 
  24.      */  
  25.     private int mWindowWidth;  
  26.     private float mMenuViewLeftPadding;  
  27.     private ViewGroup mMenuView;  
  28.     private ViewGroup mContentView;  
  29.     /** 
  30.      * menu的宽度 
  31.      */  
  32.     private int mMenuWidth;  
  33.     /** 
  34.      * 防止测量多次长度 
  35.      */  
  36.     private boolean mFirst;  
  37.     /** 
  38.      * 判断是否处于menu状态 
  39.      */  
  40.     private boolean mIsOpen=false;  
  41.     public QQHorizontalScrollView(Context context, AttributeSet attrs) {  
  42.         super(context, attrs);  
  43.         /** 
  44.          * 得到界面宽度 
  45.          */  
  46.         WindowManager manager= (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);  
  47.         DisplayMetrics metrics = new DisplayMetrics();  
  48.         manager.getDefaultDisplay().getMetrics(metrics);  
  49.         mWindowWidth = metrics.widthPixels;  
  50.         /** 
  51.          * 将dp转化为px像素 
  52.          */  
  53.         mMenuViewLeftPadding = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100, context.getResources().getDisplayMetrics());  
  54.     }  
  55.   
  56.     /** 
  57.      *测量子view的长宽与父view的长宽 
  58.      */  
  59.     @Override  
  60.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  61.         /** 
  62.          * 具体ViewGroup里面子View顺序我们添加的时候就知道了 
  63.          */  
  64.         if(!mFirst){  
  65.             mLinearMatch = (LinearLayout) getChildAt(0);  
  66.             mMenuView = (ViewGroup) mLinearMatch.getChildAt(0);  
  67.             mMenuWidth=mMenuView.getLayoutParams().width = (int) (mWindowWidth - mMenuViewLeftPadding);  
  68.             mContentView = (ViewGroup) mLinearMatch.getChildAt(1);  
  69.             mContentView.getLayoutParams().width =  mWindowWidth;  
  70.             mFirst = true;  
  71.   
  72.         }  
  73.         super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
  74.     }  
  75.   
  76.     @Override  
  77.     protected void onLayout(boolean changed, int l, int t, int r, int b) {  
  78.         super.onLayout(changed, l, t, r, b);  
  79.         if(changed){  
  80.             scrollTo(mMenuWidth,0);  
  81.         }  
  82.     }  
  83.   
  84.     /** 
  85.      * 因为是scrollerView所以这里我们只要判断up状态就行了 
  86.      */  
  87.     @Override  
  88.     public boolean onTouchEvent(MotionEvent ev) {  
  89.         switch (ev.getAction()) {  
  90.             case MotionEvent.ACTION_UP:  
  91.                 if(getScrollX()<mMenuWidth/2){  
  92.                     smoothScrollTo(0,0);//平滑移动  
  93.                     mIsOpen = true;  
  94.                 }else {  
  95.                     smoothScrollTo( mMenuWidth,0);  
  96.                     mIsOpen = false;  
  97.                 }  
  98.                 return true;  
  99.   
  100.         }  
  101.         return super.onTouchEvent(ev);  
  102.     }  
  103.   
  104.     /** 
  105.      * button touch的时候调用这个方法,点击的时候让menu view移动 
  106.      */  
  107.     public void openMenu(){  
  108.         if(mIsOpen){  
  109.             smoothScrollTo(mMenuWidth,0);  
  110.             mIsOpen = false;  
  111.         }else {  
  112.             smoothScrollTo(0,0);  
  113.             mIsOpen = true;  
  114.         }  
  115.     }  
  116.   
  117.     /** 
  118.      * 实现抽屉动画 
  119.      */  
  120.     @Override  
  121.     protected void onScrollChanged(int l, int t, int oldl, int oldt) {  
  122.         super.onScrollChanged(l, t, oldl, oldt);  
  123.         float scale = l * 1.0f / mMenuWidth; // 1 ~ 0  
  124.         float rightScale = 0.7f + 0.3f * scale;  
  125.         float leftScale = 1.0f - scale * 0.3f;  
  126.         float leftAlpha = 0.6f + 0.4f * (1 - scale);  
  127.         /** 
  128.          * 这里主要是考虑兼容问题(属性动画3.0引入),顾这里我直接调用架包实现content view的缩放动画、menu view的透明度渐变动画、menu view的缩放动画 
  129.          * 如果不考虑向下兼容问题,我们可以使用Objectanimator对象来实现动画 
  130.          */  
  131.         // 调用属性动画,设置TranslationX  
  132.         ViewHelper.setTranslationX(mMenuView, mMenuWidth * scale * 0.8f);  
  133.   
  134.         ViewHelper.setScaleX(mMenuView, leftScale);  
  135.         ViewHelper.setScaleY(mMenuView, leftScale);  
  136.         ViewHelper.setAlpha(mMenuView, leftAlpha);  
  137.         // 设置content的缩放的中心点  
  138.         ViewHelper.setPivotX(mContentView, 0);  
  139.         ViewHelper.setPivotY(mContentView, mContentView.getHeight() / 2);  
  140.         ViewHelper.setScaleX(mContentView, rightScale);  
  141.         ViewHelper.setScaleY(mContentView, rightScale);  
  142.     }  
  143. }  
下面说下动画的逻辑:

2.1、首先是内容区域的缩放比例计算:

我们准备让在菜单出现的过程中,让内容区域从1.0~0.8进行变化~~

那么怎么把1.0~0.0转化为1.0~0.8呢,其实很简单了:

float rightScale = 0.8f + scale * 0.2f; (scale 从1到0 )

接下来还有3个动画:

2.2、菜单的缩放比例计算

仔细观察了下QQ,菜单大概缩放变化是0.7~1.0

float leftScale = 1 - 0.3f * scale;

2.3、菜单的透明度比例:

我们设置为0.6~1.0;即:0.6f + 0.4f * (1 - scale)

2.4、菜单的x方向偏移量:

看一下QQ,并非完全从被内容区域覆盖,还是有一点拖出的感觉,所以我们的偏移量这么设置:

tranlateX = mMenuWidth * scale * 0.6f ;


3.最后就是我们的收尾ManActivity了,里面也很简单就是添加了一个点击事件

[java]  view plain  copy
  1. <span style="font-size:18px;">import android.app.Activity;  
  2. import android.support.v7.app.ActionBarActivity;  
  3. import android.os.Bundle;  
  4. import android.view.Menu;  
  5. import android.view.MenuItem;  
  6. import android.view.View;  
  7. import android.view.Window;  
  8. import android.widget.Button;  
  9. import android.widget.ImageButton;  
  10.   
  11.   
  12. public class MainActivity extends Activity {  
  13.     private QQHorizontalScrollView mScrollView;  
  14.     @Override  
  15.     protected void onCreate(Bundle savedInstanceState) {  
  16.         super.onCreate(savedInstanceState);  
  17.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
  18.         setContentView(R.layout.activity_main);  
  19.         mScrollView = (QQHorizontalScrollView) findViewById(R.id.id_menu);  
  20.     }  
  21.   
  22. public void toggleMenu(View view ){  
  23.         mScrollView.openMenu();  
  24. }  
  25.   
  26. }  
  27. </span>  

  最后我发一下效果图,动态图还没baidu~还不会~先发下截图吧ovo

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值