下图是工程目录结构:
MainActivity代码如下:
package com.example.tommy_qq_50; import com.example.tommy_qq_50.view.SlidingMenu; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.Window; public class MainActivity extends Activity { private SlidingMenu menu = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); menu = (SlidingMenu) findViewById(R.id.menu); } public void toggleMenu(View v){ menu.toggle(); } }
通过自定义类SlidingMenu继承自HorizontalScrollView,可以比较方便的实现侧滑的效果。而不是通过自定义ViewGroup来实现,因为这样需要考虑的TouchEvent会更多。
这里有对setTranslationX()函数的详解: http://blog.csdn.net/yanzi1225627/article/details/47850471
以下是自定义HorizontalScrollView的代码。
package com.example.tommy_qq_50.view; import com.example.tommy_qq_50.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 { private LinearLayout mWapper; private ViewGroup mMenu; private ViewGroup mContent; private int mScreenWidth ; private int mMenuWidth; //单位dp,菜单与 private int mMenuRightPadding = 50; private boolean once = false; private boolean isOpen = false; /** * 当使用了自定义属性时,会调用此构造方法 * @param context * @param attrs * @param defStyleAttr */ public SlidingMenu(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); //获取我们定义的属性 TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.SlidingMenu,defStyleAttr,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())); break; default: break; } } a.recycle(); WindowManager wm= (WindowManager) context.getSystemService(context.WINDOW_SERVICE); DisplayMetrics outMetrics = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(outMetrics); mScreenWidth = outMetrics.widthPixels; } /** * 未使用自定义属性时,会调用此构造方法 * @param context * @param attrs */ public SlidingMenu(Context context, AttributeSet attrs) { this(context, attrs,0); } public SlidingMenu(Context context) { this(context,null); } /** * 设置子View的宽和高 * 设置自己的宽和高 */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if(once == false){ mWapper = (LinearLayout) getChildAt(0); mMenu = (ViewGroup) mWapper.getChildAt(0); mContent =(ViewGroup) mWapper.getChildAt(1); mMenuWidth = mMenu.getLayoutParams().width = mScreenWidth - mMenuRightPadding; mContent.getLayoutParams().width = mScreenWidth; once = true; } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } //设置子View放置的位置 //通过设置偏移量,将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); if(changed){ this.scrollTo(mMenuWidth, 0); } } @Override public boolean onTouchEvent(MotionEvent ev) { int action = ev.getAction(); switch (action) { case MotionEvent.ACTION_UP://用户手指抬起时 //隐藏在左边的宽度 int scrollX = (int) getScrollX(); if(scrollX >= mMenuWidth/2){ this.smoothScrollTo(mMenuWidth, 0); isOpen = false; }else { this.smoothScrollTo(0, 0); isOpen = true; } return true; } return super.onTouchEvent(ev); } /** * 打开菜单 */ public void openMenu(){ if(isOpen) return ; else{ this.smoothScrollTo(0, 0); isOpen = true; } } /** * 关闭菜单 */ public void closeMenu(){ if(!isOpen){ return ; }else { this.smoothScrollTo(mMenuWidth, 0); isOpen = false; } } /** * 切换菜单 */ public void toggle(){ if(isOpen){ closeMenu(); }else{ openMenu(); } } @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); float scale = l * 1.0f / mMenuWidth;//1~0 /** * 区别一:内容区域从1.0-0.7 缩放的效果 scale:1.0 - 0.0 0.7 + 0.3 * scale 区别二:菜单的偏移量要修改 区别三:菜单的显示时有缩放,以及透明度变化。 缩放:0.7 - 1.0 1.0 - scale * 0.3 透明度:0.6 - 1.0 0.6 + 0.4 * (1 - scale); */ float rightScale = (0.7f + 0.3f * scale); float leftScale = 1.0f - scale * 0.3f; float leftAlpha = 0.6f + 0.4f * (1 - scale); //调用属性动画,设置TranslationX ViewHelper.setTranslationX(mMenu, mMenuWidth * scale * 0.7f); ViewHelper.setScaleX(mMenu, leftScale); ViewHelper.setScaleY(mMenu, leftScale); ViewHelper.setAlpha(mMenu, leftAlpha); //设置mContent缩放的中心点 ViewHelper.setPivotX(mContent, 0); ViewHelper.setPivotY(mContent, mContent.getHeight()/2); ViewHelper.setScaleX(mContent, rightScale); ViewHelper.setScaleY(mContent, rightScale); } }
工程中一共有两个XML布局文件
1、activity_main.xml
2、left_menu.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:tommy="http://schemas.android.com/apk/res/com.example.tommy_qq_50" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/img_frame_background" > <com.example.tommy_qq_50.view.SlidingMenu android:id="@+id/menu" android:layout_width="match_parent" android:layout_height="match_parent" tommy:rightPadding="50dp" > <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.tommy_qq_50.view.SlidingMenu> </RelativeLayout>
<?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="match_parent" android:layout_height="wrap_content" > <ImageView android:id="@+id/id_img1" android:layout_width="50dp" android:layout_height="50dp" android:layout_marginLeft="20dp" android:layout_marginTop="20dp" android:src="@drawable/img_1" android:layout_centerVertical="true" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20sp" android:textColor="#ffffff" android:text="第一个Item" android:layout_toRightOf="@id/id_img1" android:layout_marginLeft="20dp" android:layout_centerVertical="true" /> </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <ImageView android:id="@+id/id_img2" android:layout_width="50dp" android:layout_height="50dp" android:layout_marginLeft="20dp" android:layout_marginTop="20dp" android:src="@drawable/img_2" android:layout_centerVertical="true" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20sp" android:textColor="#ffffff" android:text="第二个Item" android:layout_toRightOf="@id/id_img2" android:layout_marginLeft="20dp" android:layout_centerVertical="true" /> </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <ImageView android:id="@+id/id_img3" android:layout_width="50dp" android:layout_height="50dp" android:layout_marginLeft="20dp" android:layout_marginTop="20dp" android:src="@drawable/img_3" android:layout_centerVertical="true" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20sp" android:textColor="#ffffff" android:text="第三个Item" android:layout_toRightOf="@id/id_img3" android:layout_marginLeft="20dp" android:layout_centerVertical="true" /> </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <ImageView android:id="@+id/id_img4" android:layout_width="50dp" android:layout_height="50dp" android:layout_marginLeft="20dp" android:layout_marginTop="20dp" android:src="@drawable/img_4" android:layout_centerVertical="true" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20sp" android:textColor="#ffffff" android:text="第四个Item" android:layout_toRightOf="@id/id_img4" android:layout_marginLeft="20dp" android:layout_centerVertical="true" /> </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <ImageView android:id="@+id/id_img5" android:layout_width="50dp" android:layout_height="50dp" android:layout_marginLeft="20dp" android:layout_marginTop="20dp" android:src="@drawable/img_5" android:layout_centerVertical="true" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20sp" android:textColor="#ffffff" android:text="第五个Item" android:layout_toRightOf="@id/id_img5" android:layout_marginLeft="20dp" android:layout_centerVertical="true" /> </RelativeLayout> </LinearLayout> </RelativeLayout>
时间: 2024-11-09 02:10:16