本课程将带领大家通过自定义控件实现QQ5.0侧滑菜单,课程将循序渐进,首先实现最普通的侧滑菜单,然后引入属性动画与拖动菜单效果相结合,最终实现QQ5.0侧滑菜单效果。通过本课程大家会对侧滑菜单有更深层次的了解,通过自定义控件和属性动画打造千变万化的侧滑菜单效果
效果图如下所示:
package com.example; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.view.View; public class MainActivity extends ActionBarActivity { private SlidingMenu mMenu; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mMenu = (SlidingMenu) findViewById(R.id.id_menu); } public void toggleMenu(View view) { mMenu.toggle(); } } package com.example; import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Rect; import android.util.DisplayMetrics; import android.view.View; import android.view.WindowManager; /** * Created by tuhao-pc on 2015/12/28. * 获取屏幕相关的辅助类 */ public class ScreenUtils { private ScreenUtils() { } /** *获取屏幕的高度 * @param context * @return */ public static int getScreenWidth(Context context){ WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); DisplayMetrics outMetrics = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(outMetrics); return outMetrics.widthPixels; } /** * 获取屏幕的高度 * @param context * @return */ public static int getScreenHeight(Context context){ WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); DisplayMetrics outMetrics = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(outMetrics); return outMetrics.heightPixels; } /** * 获取手机状态栏的状态 * @param context * @return */ public static int getStatusHeight(Context context){ int statusHeight = -1; Class<&#63;> clazz = null; try { clazz = Class.forName("com.android.internal.R$dimen"); Object object = clazz.newInstance(); int height = Integer.parseInt(clazz.getField("status_bar_height").get(object).toString()); statusHeight = context.getResources().getDimensionPixelSize(height); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return statusHeight; } /** * 获取当前屏幕截图,包含状态栏 * * @param activity * @return */ public static Bitmap snapShotWithStatusBar(Activity activity) { View view = activity.getWindow().getDecorView(); view.setDrawingCacheEnabled(true); view.buildDrawingCache(); Bitmap bmp = view.getDrawingCache(); int width = getScreenWidth(activity); int height = getScreenHeight(activity); Bitmap bp = null; bp = Bitmap.createBitmap(bmp, 0, 0, width, height); view.destroyDrawingCache(); return bp; } /** * 获取当前屏幕截图,不包含状态栏 * * @param activity * @return */ public static Bitmap snapShotWithoutStatusBar(Activity activity) { View view = activity.getWindow().getDecorView(); view.setDrawingCacheEnabled(true); view.buildDrawingCache(); Bitmap bmp = view.getDrawingCache(); Rect frame = new Rect(); activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame); int statusBarHeight = frame.top; int width = getScreenWidth(activity); int height = getScreenHeight(activity); Bitmap bp = null; bp = Bitmap.createBitmap(bmp, 0, statusBarHeight, width, height - statusBarHeight); view.destroyDrawingCache(); return bp; } } package com.example; import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet; import android.util.TypedValue; import android.view.MotionEvent; import android.view.ViewGroup; import android.widget.HorizontalScrollView; import android.widget.LinearLayout; import com.nineoldandroids.view.ViewHelper; /** * Created by tuhao-pc on 2015/12/28. */ public class SlidingMenu extends HorizontalScrollView{ private int mScreenWidth; private int mMenuRightPadding; private int mMenuWidth; private int mHalfMenuWidth; private boolean isOpen; private boolean once; private ViewGroup mMenu; private ViewGroup mContent; public SlidingMenu(Context context) { this(context,null); } public SlidingMenu(Context context, AttributeSet attrs) { this(context, attrs, 0); } public SlidingMenu(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mScreenWidth = ScreenUtils.getScreenWidth(context); TypedArray a = context.getTheme().obtainStyledAttributes(attrs,R.styleable.SlidingMenu,defStyleAttr,0); int count = a.getIndexCount(); for(int i = 0;imHalfMenuWidth){ 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; this.smoothScrollTo(0, 0); isOpen = true; } /** * 关闭菜单 */ public void closeMenu() { if (isOpen) { 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; float leftScale = 1 - 0.3f * scale; float rightScale = 0.8f + scale * 0.2f; ViewHelper.setScaleX(mMenu, leftScale); ViewHelper.setScaleY(mMenu, leftScale); ViewHelper.setAlpha(mMenu, 0.6f + 0.4f * (1 - scale)); ViewHelper.setTranslationX(mMenu, mMenuWidth * scale * 0.7f); ViewHelper.setPivotX(mContent, 0); ViewHelper.setPivotY(mContent, mContent.getHeight() / 2); ViewHelper.setScaleX(mContent, rightScale); ViewHelper.setScaleY(mContent, rightScale); } }
布局文件和资源文件(xml)
<&#63;xml version="1.0" encoding="utf-8"&#63;><&#63;xml version="1.0" encoding="utf-8"&#63;>