转载请注明出处:http://blog.csdn.net/wei_chong_chong/article/details/50839113
谢谢!
以前写过一个QQ侧滑的博客,那个是一般侧滑效果,今天来做一个更牛逼的效果。
首先看一下,
一般效果实现:
ViewGroup Menu+Content
原理:
(自定义一个ViewGroup或LinearLayout或RelativeLayout,左边放一个Menu右边放一个Content),
监听onTouchEvent事件
MOVE:不断改变ViewGroup的leftMargin
UP;根据显示菜单的宽度,决定将其隐藏或者显示
1.Scroller
2.LeftMargin +Thread
见我的另外一篇文章:http://blog.csdn.net/wei_chong_chong/article/details/50807353
今天,用另一种方法实现:继承HorizontalScrollView
自定义ViewGroup(View)
1.onMeasure
决定内部View(子View)的宽和高,以及自己的宽和高
2.onLayout
决定子View的放置位置
3.onTouchEvent
判断手指的动作,按下,抬起等进而决定View的移动效果
更详细的自定义view请参考我的另外一篇博客http://blog.csdn.net/wei_chong_chong/article/details/50814617
没有使用自定义属性时默认调用两个参数的构造方法
整理一下思路:
首先构造方法中获得屏幕宽度,把单位转换为px
2.在onMeasuer()设置子View的宽和高
3.在onLayout()中隐藏菜单
4.在onTouchEvent()中up事件进行处理
现在已经基本上能实现滑动效果了
先把代码贴出来吧:
第一步:创建mMenu菜单布局left_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal"
android:padding="10dp" >
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:src="@drawable/img_1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="第一个item"
android:textColor="#ffffff" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal"
android:padding="10dp" >
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:src="@drawable/img_2" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="第二个item"
android:textColor="#ffffff" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal"
android:padding="10dp" >
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:src="@drawable/img_3" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="第三个item"
android:textColor="#ffffff" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal"
android:padding="10dp" >
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:src="@drawable/img_4" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="第四个item"
android:textColor="#ffffff" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal"
android:padding="10dp" >
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:src="@drawable/img_5" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="第五个item"
android:textColor="#ffffff" />
</LinearLayout>
</LinearLayout>
2.创建自定义布局:
public class SlidingMenu extends HorizontalScrollView{
/**
* 未使用自定义属性时使用
* @param context
* @param attrs
*
*/
//水平滚动条
private LinearLayout mWapper;
//菜单
private ViewGroup mMenu;
//内容区域
private ViewGroup mContent;
//屏幕宽度
private int mScreenWidth;
private int mMenuWidth;
//dp
private int mMenuRightPadding = 50;
private boolean once;
public SlidingMenu(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
//获取屏幕宽度
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
mScreenWidth = outMetrics.widthPixels;
//把dp转换为px
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50,
context.getResources().getDisplayMetrics());
}
/**
* 设置View的宽和高 设置自己的宽和高
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
/**
* 使用once标记使设置宽度的方法只调用一次就行了,没必要多次设置
*/
if(!once){
mWapper = (LinearLayout) getChildAt(0);
//LinearLayout中的第一个元素
mMenu = (ViewGroup) mWapper.getChildAt(0);
//LinearLayout中的第二个元素
mContent = (ViewGroup) mWapper.getChildAt(1);
//设置mMenu的宽度
mMenuWidth = mMenu.getLayoutParams().width = mScreenWidth - mMenuRightPadding;
//设置mContent的宽度
mContent.getLayoutParams().width = mScreenWidth;
once = true;
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
/**
* 设置偏移量,将menu隐藏
*/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// TODO Auto-generated method stub
super.onLayout(changed, l, t, r, b);
//如果发生变化调用,设置偏移量,将menu隐藏
if(changed){
//this.scrollTo(x,y)this是滚动条,x为正值时滚动条向左移动,滚动条向右移动内容区域向左移动
this.scrollTo(mMenuWidth, 0);//y轴不用移动0
}
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
int action = ev.getAction();
//因为HorizontalScrollView能自己控制MOVE和Down的事件,即使不做任何处理,它也能把菜单划出来和隐藏,所以这里只需监听一下UP事件就行
switch (action) {
case MotionEvent.ACTION_UP:
int scrollX = getScrollX();//隐藏左边的宽度,在内容区域左侧多出来的部分(内容部分太大左侧未被屏幕完全显示出来,隐藏在屏幕左边的部分)
if(scrollX >= mMenuWidth/2){
this.smoothScrollTo(mMenuWidth, 0);
//这里使用smoothScrollTo(x,y)方法使有个过渡,因为scrollTo(x,y)是瞬间完成的
}else {
//将内容区域完全显示
this.smoothScrollTo(0, 0);
}
return true;
}
return super.onTouchEvent(ev);
}
}
3.在主布局中引用自定义控件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/img_frame_background"
tools:context="com.example.slidingmenu.MainActivity" >
<com.example.slidingmenu.myview.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.slidingmenu.myview.SlidingMenu>
</RelativeLayout>
下面自定义属性:允许用户设置菜单离屏幕右边的距离
1.书写xml文件定义属性values/attr.xml
2.在布局中使用
引入命名空间,hyman:名称可以随便写
xmlns:hyman="http://schemas.android.com/apk/res/com.example.slidingmenu"
com.example.slidingmenu:这个是当前应用的包名,不是自定义View的包名,这个需要注意
下面我们再加入按钮,效果点击显示和关闭mMenu菜单
加入一个布尔类型的变量,标识当前的状态
//加入boolean类型的变量标识当前的状态(菜单是否打开)
private boolean isOpen;
在下面代码中修改状态
switch (action) {
case MotionEvent.ACTION_UP:
int scrollX = getScrollX();//隐藏左边的宽度,在内容区域左侧多出来的部分(内容部分太大左侧未被屏幕完全显示出来,隐藏在屏幕左边的部分)
if(scrollX >= mMenuWidth/2){
this.smoothScrollTo(mMenuWidth, 0);
//这里使用smoothScrollTo(x,y)方法使有个过渡,因为scrollTo(x,y)是瞬间完成的
isOpen = false;//将状态设置为关闭状态
}else {
//将内容区域完全显示
this.smoothScrollTo(0, 0);
isOpen = true;//将状态设置为打开状态
}
return true;
}
添加方法
/**
* 打开菜单
*/
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();
}
}
修改后的的代码如下:
public class SlidingMenu extends HorizontalScrollView{
/**
* 未使用自定义属性时使用
* @param context
* @param attrs
*
*/
//水平滚动条
private LinearLayout mWapper;
//菜单
private ViewGroup mMenu;
//内容区域
private ViewGroup mContent;
//屏幕宽度
private int mScreenWidth;
private int mMenuWidth;
//dp
private int mMenuRightPadding = 50;
private boolean once;
//加入boolean类型的变量标识当前的状态(菜单是否打开)
private boolean isOpen;
/**
* 当使用了自定义的属性时,会调用此构造方法
* @param context
* @param attrs
* @param defStyle
*/
public SlidingMenu(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
//获取我们定义的属性
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,R.styleable.SlidingMenu, defStyle,0);
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()));//getDimensionPixelSize()第二个参数是默认值50dp
break;
}
}
a.recycle();
//获取屏幕宽度
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
mScreenWidth = outMetrics.widthPixels;
//把dp转换为px
// mMenuRightPadding = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50,
// context.getResources().getDisplayMetrics());
}
/*
* 什么时候调用一个参数的构造方法:在代码里面new传一个上下文就行了
*/
public SlidingMenu(Context context) {
this(context,null);
// TODO Auto-generated constructor stub
}
public SlidingMenu(Context context, AttributeSet attrs) {
this(context,attrs,0);
}
/**
* 设置View的宽和高 设置自己的宽和高
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
/**
* 使用once标记使设置宽度的方法只调用一次就行了,没必要多次设置
*/
if(!once){
mWapper = (LinearLayout) getChildAt(0);
//LinearLayout中的第一个元素
mMenu = (ViewGroup) mWapper.getChildAt(0);
//LinearLayout中的第二个元素
mContent = (ViewGroup) mWapper.getChildAt(1);
//设置mMenu的宽度
mMenuWidth = mMenu.getLayoutParams().width = mScreenWidth - mMenuRightPadding;
//设置mContent的宽度
mContent.getLayoutParams().width = mScreenWidth;
once = true;
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
/**
* 设置偏移量,将menu隐藏
*/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// TODO Auto-generated method stub
super.onLayout(changed, l, t, r, b);
//如果发生变化调用,设置偏移量,将menu隐藏
if(changed){
//this.scrollTo(x,y)this是滚动条,x为正值时滚动条向左移动,滚动条向右移动内容区域向左移动
this.scrollTo(mMenuWidth, 0);//y轴不用移动0
}
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
int action = ev.getAction();
//因为HorizontalScrollView能自己控制MOVE和Down的事件,即使不做任何处理,它也能把菜单划出来和隐藏,所以这里只需监听一下UP事件就行
switch (action) {
case MotionEvent.ACTION_UP:
int scrollX = getScrollX();//隐藏左边的宽度,在内容区域左侧多出来的部分(内容部分太大左侧未被屏幕完全显示出来,隐藏在屏幕左边的部分)
if(scrollX >= mMenuWidth/2){
this.smoothScrollTo(mMenuWidth, 0);
//这里使用smoothScrollTo(x,y)方法使有个过渡,因为scrollTo(x,y)是瞬间完成的
isOpen = false;//将状态设置为关闭状态
}else {
//将内容区域完全显示
this.smoothScrollTo(0, 0);
isOpen = true;//将状态设置为打开状态
}
return true;
}
return super.onTouchEvent(ev);
}
/**
* 打开菜单
*/
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();
}
}
}
另外在主界面中加入一个按钮
在MainActivity中添加按钮点击事件
这些我就不写了
侧滑菜单效果二:抽屉式侧滑:菜单仿佛在在内容区域以下
我们在拉之前,给菜单设置偏移量,向右偏移
没拉时 偏移量是 mMenu - 0
我们拉出来100像素时,向右偏移量是mMenuWidth - 100;
拉出来200时 偏移是mMenuWidth - 200
实现偏移量 属性动画:TraslationX
getScrollX:mMenuWidth ~ 0
调用动画时机
实现方法:
HorizontalScrollView中有一个方法
其中第一个参数l就是getScrollx,变化值mMenu ~ 0,这里正好可以使用
/**
* 滚动条变化时的回调方法
* 参数1.就是getScrollX
* 参数2,3,4是变化的梯度
*/
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
// TODO Auto-generated method stub
super.onScrollChanged(l, t, oldl, oldt);
//调用属性动画,设置TransactionX
ViewHelper.setTranslationX(mMenu, l);
}
//调用属性动画,设置TransactionX
ViewHelper.setTranslationX(mMenu, l);
调用属性动画需要一个导入一个jar包,这个大家都知道吧,可以在我的资源文件中下载
现在我们实现与qq5.0效果还是有一些区别
1.内容区域1.0 ~ 0.7缩放效果
scale :1.0~0.0
0.7 + 0.3 * scale
2. 菜单偏移量需要修改
3.菜单的显示时有缩放,以及透明度变化
缩放:0.7 ~ 1.0
1.0 - scale * 0.3
透明度 :0.6 ~ 1.0
0.6 + 0.4 *(1 - scale)
实现代码:
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
// TODO Auto-generated method stub
super.onScrollChanged(l, t, oldl, oldt);
/**
* 1.内容区域1.0 ~ 0.7缩放效果
scale :1.0~0.0
0.7 + 0.3 * scale
2. 菜单偏移量需要修改
3.菜单的显示时有缩放,以及透明度变化
缩放:0.7 ~ 1.0
1.0 - scale * 0.3
透明度 :0.6 ~ 1.0
0.6 + 0.4 *(1 - scale)
*///调用属性动画,设置TransactionX
float scale = l*1.0f/mMenuWidth;//1 ~ 0
float rightScale = 0.7f+0.3f*scale;
float leftScale = 1.0f - scale * 0.3f;
float leftAlpha = 0.6f + 0.4f * (1 - scale);
//菜单移动,缩放,透明度设置
ViewHelper.setTranslationX(mMenu, l);
ViewHelper.setScaleX(mMenu, leftScale);
ViewHelper.setScaleY(mMenu, leftScale);
ViewHelper.setAlpha(mMenu, leftAlpha);
//内容缩放
ViewHelper.setPivotX(mContent, 0);//设置mContent缩放的中心点
ViewHelper.setPivotY(mContent, mContent.getHeight()/2);
ViewHelper.setScaleX(mContent, rightScale);
ViewHelper.setScaleY(mContent, rightScale);
}
我们观察qq5.0会发现,左边菜单显示的时候是,先显示一大部分,还有一小部分隐藏在左边
所以要实现这样的效果:可以一开始把菜单移动改为0.7 ~ 0
ViewHelper.setTranslationX(mMenu, l * 0.7f);
现在以及实现所有效果了
package com.example.slidingmenu.myview;
import com.example.slidingmenu.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.WindowManager;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
public class SlidingMenu extends HorizontalScrollView{
/**
* 未使用自定义属性时使用
* @param context
* @param attrs
*
*/
//水平滚动条
private LinearLayout mWapper;
//菜单
private ViewGroup mMenu;
//内容区域
private ViewGroup mContent;
//屏幕宽度
private int mScreenWidth;
private int mMenuWidth;
//dp
private int mMenuRightPadding = 50;
private boolean once;
//加入boolean类型的变量标识当前的状态(菜单是否打开)
private boolean isOpen;
/**
* 当使用了自定义的属性时,会调用此构造方法
* @param context
* @param attrs
* @param defStyle
*/
public SlidingMenu(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
//获取我们定义的属性
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,R.styleable.SlidingMenu, defStyle,0);
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()));//getDimensionPixelSize()第二个参数是默认值50dp
break;
}
}
a.recycle();
//获取屏幕宽度
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
mScreenWidth = outMetrics.widthPixels;
//把dp转换为px
// mMenuRightPadding = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50,
// context.getResources().getDisplayMetrics());
}
/*
* 什么时候调用一个参数的构造方法:在代码里面new传一个上下文就行了
*/
public SlidingMenu(Context context) {
this(context,null);
// TODO Auto-generated constructor stub
}
public SlidingMenu(Context context, AttributeSet attrs) {
this(context,attrs,0);
}
/**
* 设置View的宽和高 设置自己的宽和高
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
/**
* 使用once标记使设置宽度的方法只调用一次就行了,没必要多次设置
*/
if(!once){
mWapper = (LinearLayout) getChildAt(0);
//LinearLayout中的第一个元素
mMenu = (ViewGroup) mWapper.getChildAt(0);
//LinearLayout中的第二个元素
mContent = (ViewGroup) mWapper.getChildAt(1);
//设置mMenu的宽度
mMenuWidth = mMenu.getLayoutParams().width = mScreenWidth - mMenuRightPadding;
//设置mContent的宽度
mContent.getLayoutParams().width = mScreenWidth;
once = true;
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
/**
* 设置偏移量,将menu隐藏
*/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// TODO Auto-generated method stub
super.onLayout(changed, l, t, r, b);
//如果发生变化调用,设置偏移量,将menu隐藏
if(changed){
//this.scrollTo(x,y)this是滚动条,x为正值时滚动条向左移动,滚动条向右移动内容区域向左移动
this.scrollTo(mMenuWidth, 0);//y轴不用移动0
}
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
int action = ev.getAction();
//因为HorizontalScrollView能自己控制MOVE和Down的事件,即使不做任何处理,它也能把菜单划出来和隐藏,所以这里只需监听一下UP事件就行
switch (action) {
case MotionEvent.ACTION_UP:
int scrollX = getScrollX();//隐藏左边的宽度,在内容区域左侧多出来的部分(内容部分太大左侧未被屏幕完全显示出来,隐藏在屏幕左边的部分)
if(scrollX >= mMenuWidth/2){
this.smoothScrollTo(mMenuWidth, 0);
//这里使用smoothScrollTo(x,y)方法使有个过渡,因为scrollTo(x,y)是瞬间完成的
isOpen = false;//将状态设置为关闭状态
}else {
//将内容区域完全显示
this.smoothScrollTo(0, 0);
isOpen = true;//将状态设置为打开状态
}
return true;
}
return super.onTouchEvent(ev);
}
/**
* 打开菜单
*/
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.就是getScrollX
* 参数2,3,4是变化的梯度
*/
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
// TODO Auto-generated method stub
super.onScrollChanged(l, t, oldl, oldt);
/**
* 1.内容区域1.0 ~ 0.7缩放效果
scale :1.0~0.0
0.7 + 0.3 * scale
2. 菜单偏移量需要修改
3.菜单的显示时有缩放,以及透明度变化
缩放:0.7 ~ 1.0
1.0 - scale * 0.3
透明度 :0.6 ~ 1.0
0.6 + 0.4 *(1 - scale)
*///调用属性动画,设置TransactionX
float scale = l*1.0f/mMenuWidth;//1 ~ 0
float rightScale = 0.7f+0.3f*scale;
float leftScale = 1.0f - scale * 0.3f;
float leftAlpha = 0.6f + 0.4f * (1 - scale);
//菜单移动,缩放,透明度设置
ViewHelper.setTranslationX(mMenu, l * 0.5f);//等价于 ViewHelper.setTranslationX(mMenu, mMenuWidth * scale * 0.5f);
ViewHelper.setScaleX(mMenu, leftScale);
ViewHelper.setScaleY(mMenu, leftScale);
ViewHelper.setAlpha(mMenu, leftAlpha);
//内容缩放
ViewHelper.setPivotX(mContent, 0);//设置mContent缩放的中心点
ViewHelper.setPivotY(mContent, mContent.getHeight()/2);
ViewHelper.setScaleX(mContent, rightScale);
ViewHelper.setScaleY(mContent, rightScale);
}
}
总结:
一自定义ViewGroup
1.构造方法的选择,获得一些需要用到的值
2.onMeasure 计算子VIew的宽和高,以及设置自己的宽和高
3.onLayout 决定子View布局的位置
[4.onTouchEvent监听用户的触摸事件]不需要监听用户触摸事件时可以不实现
二构造方法
1.一个参数的context ,自己new 对象的时候使用,传入context上下文对象就行
2.两个参数的,context,attr 布局文件中声明(没有自定义属性的)
3.三个参数,context,attr,defStyle(有自定义的属性)
一般自定义ViewGroup时,三个构造方法都要实现,一个参数的构造方法里调用两个参数的构造方法,两个参数的构造方法调用三个参数的构造方法,
三自定义属性
1.attr.xml
2.布局文件 xmlns = "............../当前应用的包名"
3.在三个参数的构造方法中,获得我们自定义属性的值
4.属性动画