本文实现 AndroidQQ5.0 侧滑效果,现在 QQ8.8 已经不用这种效果了,但是现在最新的酷狗使用的是这种效果。
向右侧滑或点击切换菜单时的效果:
实现原理:
其实是使用一个水平布局的 ScrollView 来放一个线性布局,通过监听屏幕的滑动事件来决定是否显示线性布局里面的侧边栏。
代码:
(一)布局文件 activity_my.xml(二)左边控件的布局文件 left_menu.xml
其实上面两个布局文件是可以写在一起的,第一个布局文件 include 包含第二个布局文件,但是你也可以把第二个布局文件设计成一个碎片,这样所有的点击事件都是在碎片的类中完成的。
(三)滑动事件处理的自定义 View 的类
- package me.drakeet.qqsliddingmenu;
- 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;
- import com.nineoldandroids.view.ViewHelper;
- /** * 水平的滚动视图,实现侧滑功能 */
- public class QQSliddingMenu extends HorizontalScrollView {
- private LinearLayout mWapper;
- private ViewGroup mMenuViewGroup;
- private ViewGroup mContentViewGroup;
- private int mScreenWidth;
- private int mMenuRightPadding = 50;
- private int mMenuWidth; //侧滑菜单栏的宽度 private boolean mIsOnce = true; private boolean mIsOpen; /** * 构造方法 */ public QQSliddingMenu(Context context) { this(context, null); } public QQSliddingMenu(Context context, AttributeSet attrs) { this(context, attrs, 0); } public QQSliddingMenu(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); DisplayMetrics displayMetrics = new DisplayMetrics(); windowManager.getDefaultDisplay().getMetrics(displayMetrics); mScreenWidth = displayMetrics.widthPixels; TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.QQSliddingMenu, defStyleAttr, 0); int n = typedArray.length(); for (int i = 0; i < n; i++) { int attr = typedArray.getIndex(i); switch (attr) { case R.styleable.QQSliddingMenu_rigthtPadding: mMenuRightPadding = typedArray.getDimensionPixelSize( attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, context.getResources().getDisplayMetrics()) ); break; default: break; } } typedArray.recycle(); } /** * 测量布局 */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (mIsOnce) { mWapper = (LinearLayout) getChildAt(0); mMenuViewGroup = (ViewGroup) mWapper.getChildAt(0); mContentViewGroup = (ViewGroup) mWapper.getChildAt(1); mMenuWidth = mMenuViewGroup.getLayoutParams().width = mScreenWidth - mMenuRightPadding; mContentViewGroup.getLayoutParams().width = mScreenWidth; mIsOnce = false; } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void 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 public boolean onTouchEvent(MotionEvent ev) { int action = ev.getAction(); switch (action) { case MotionEvent.ACTION_UP: int scrollX = getScrollX(); if (scrollX >= mMenuWidth / 2) { smoothScrollTo(mMenuWidth, 0); mIsOpen = false; } else { smoothScrollTo(0, 0); mIsOpen = true; } return true; } return super.onTouchEvent(ev); } /** * 打开菜单栏 */ public void openMenu() { if (mIsOpen) return; smoothScrollTo(0, 0); mIsOpen = true; } /** * 关闭菜单栏 */ public void closeMenu() { if (!mIsOpen) return; smoothScrollTo(mMenuWidth, 0); mIsOpen = false; } /** * 切换菜单 */ public void toggleMenu() { if (mIsOpen) 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; // l: 1.0 ~ 0 ViewHelper.setTranslationX(mMenuViewGroup, mMenuWidth * scale * 0.7f); float rightScale = 0.7f + 0.3f * scale; ViewHelper.setPivotX(mContentViewGroup, 0); ViewHelper.setPivotY(mContentViewGroup, mContentViewGroup.getHeight() / 2); ViewHelper.setScaleX(mContentViewGroup, rightScale); ViewHelper.setScaleY(mContentViewGroup, rightScale); float leftScale = 1.0f - 0.3f * scale; ViewHelper.setScaleX(mMenuViewGroup, leftScale); ViewHelper.setScaleY(mMenuViewGroup, leftScale); float leftAlpha = 0.1f + 0.9f * (1 - scale); ViewHelper.setAlpha(mMenuViewGroup, leftAlpha); }}
(四)主方法的类
- package me.drakeet.qqsliddingmenu;
- import android.os.Bundle;
- import android.support.v7.app.AppCompatActivity;
- import android.view.View;
- import android.widget.RelativeLayout;
- import android.widget.TextView;
- /** * 侧边栏的示例 */
- public class MyActivity extends AppCompatActivity implements View.OnClickListener { //侧滑的自定义View对象 private QQSliddingMenu mQQSliddingMenu; TextView text; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); mQQSliddingMenu = (QQSliddingMenu) findViewById(R.id.qqsm); text = (TextView) findViewById(R.id.my_text); initLeftItem(); } /** * 给左边的侧滑条目设置监听事件 */ private void initLeftItem() { RelativeLayout rl1 = (RelativeLayout) findViewById(R.id.left_rl_item1); RelativeLayout rl2 = (RelativeLayout) findViewById(R.id.left_rl_item2); RelativeLayout rl3 = (RelativeLayout) findViewById(R.id.left_rl_item3); RelativeLayout rl4 = (RelativeLayout) findViewById(R.id.left_rl_item4); RelativeLayout rl5 = (RelativeLayout) findViewById(R.id.left_rl_item5); rl1.setOnClickListener(this); rl2.setOnClickListener(this); rl3.setOnClickListener(this); rl4.setOnClickListener(this); rl5.setOnClickListener(this); } /** * 点击切换菜单按钮的监听事件 */ public void toggleMenu(View view) { mQQSliddingMenu.toggleMenu(); } /** * 点击左边的菜单栏的条目的监听事件 */ @Override public void onClick(View v) { switch (v.getId()) { case R.id.left_rl_item1: text.setText("选择了第一个按钮"); break; case R.id.left_rl_item2: text.setText("选择了第二个按钮"); break; case R.id.left_rl_item3: text.setText("选择了第三个按钮"); break; case R.id.left_rl_item4: text.setText("选择了第四个按钮"); break; case R.id.left_rl_item5: text.setText("选择了第五个按钮"); break; } //切换菜单 mQQSliddingMenu.toggleMenu(); }}
到这里一个 QQ5.0 侧拉效果的功能就实现了,其实最主要的就是那个自定义的 View,这个工具类是可以直接拿来使用的。
就爱阅读 www.92to.com 网友整理上传, 为您提供最全的知识大全, 期待您的分享,转载请注明出处。
来源: