仿QQ5.0侧滑先行版
来源:互联网 发布:首次提出大数据的时间 编辑:程序博客网 时间:2024/05/16 11:21
QQ5.0侧滑效果实现方案有很多方式,今天先来介绍一种简单的方式
先上效果图:
①我们先来分析一下,如果想要滑动效果,哪些控件具有滑动效果呢?于是我们想到了ScrollView, HorizontalScrollView, ListView… 通过对比,我们可以找出HorizontalScrollView最符合我们的效果。使用HorizontalScrollView,在适当的时候隐藏部分HorizontalScrollView的内容即可。因此我的自定义View继承HorizontalScrollView就可以了。
/** SlidingMenu就是我们自定义的View控件 */public class SlidingMenu extends HorizontalScrollView { private ViewGroup mWapper;// SlidingMenu中的LinearLayout private ViewGroup mMenu;// 菜单 private ViewGroup mContent;// 主页面内容 private boolean isFirstMeasure = true;// 是否首次测量 private int mMenuRightPadding = 150;// 菜单右边预留宽度 private int mScreentWidth;// 屏幕宽度 private int mMenuWidth;// 菜单宽度 private boolean isOpen = false;// 是否打开菜单 /** 需要重写构造方法 */ 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); // 获取自定义的属性 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SlidingMenu, defStyleAttr, 0); int count = a.getIndexCount(); for (int i = 0; i < count; i++) { int attr = a.getIndex(i); switch (attr) { case R.styleable.SlidingMenu_rightPadding: mMenuRightPadding = a.getDimensionPixelSize(attr, dp2px(context, mMenuRightPadding)); // 获取到自定义属性rightPadding的值,即菜单预留宽度 break; } } a.recycle();// 需要及时销毁 WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);// 得到窗口管理器 DisplayMetrics outMetrics = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(outMetrics); mScreentWidth = outMetrics.widthPixels;// 获取屏幕的宽度}/** dp转px */public int dp2px(Context context, int i) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, i, context.getResources().getDisplayMetrics()); }使用自定义控件,自定义属性。在values/attr.xml中定义 <?xml version="1.0" encoding="utf-8"?> <resources> <attr name="rightPadding" format="dimension"/> <declare-styleable name="SlidingMenu"> <attr name="rightPadding"/> </declare-styleable> </resources>
②接着定义下我们主页面的布局文件,使用我们自定义的SlidingMenu控件。布局文件中,我们自定义SlidingMenu中用了LinearLayout, LinearLayout中包含了一个左边布局和主页面的布局。
<?xml version="1.0" encoding="utf-8"?><RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:lingchen="http://schemas.android.com/apk/res-auto"//如果需要给自定义控件添加属性,需要在这里定义下命名空间 xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.yitong.myslidingmenu.MainActivity"> <com.yitong.myslidingmenu.view.SlidingMenu android:id="@+id/main_menu" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@mipmap/bg" android:fadingEdge="none" android:overScrollMode="never" lingchen:rightPadding="60dp"//向自定控件传递值 > <LinearLayout android:layout_width="wrap_content" android:layout_height="match_parent" android:orientation="horizontal"> <include layout="@layout/left_menu"/> <LinearLayout android:id="@+id/main_content" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@mipmap/qq" android:orientation="horizontal"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="click" android:text="切换菜单"/> </LinearLayout> </LinearLayout> </com.yitong.myslidingmenu.view.SlidingMenu></RelativeLayout>
③接着,回到我们的SlidingMenu中,重写onMeasure(测量控件),onLayout(重新布局)
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (isFirstMeasure) {// 防止重复测量 mWapper = (ViewGroup) getChildAt(0);//获取第一个孩子,即主页面布局中SlidingMenu包含的LinearLayout mMenu = (ViewGroup) mWapper.getChildAt(0);// 左边布局(菜单布局) mContent = (ViewGroup) mWapper.getChildAt(1);// 主布局 mMenuWidth = mScreentWidth - mMenuRightPadding - mMenuRightPadding;// 菜单布局的宽度 = 屏幕的宽度 - 右边预留的宽度 mMenu.getLayoutParams().width = mMenuWidth;// 设置菜单的宽度 isFirstMeasure = false; } super.onMeasure(widthMeasureSpec, heightMeasureSpec); }@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); // 通过设置偏移量,将menu隐藏 if (changed) { this.scrollTo(mMenuWidth, 0); } }
③此时,我们的自定义SlingMenu,大致已经设计好了,是不是能简单呢。然后我们添加一些效果,当菜单滑出一半多时,让它自定滑出,否则让它关闭。
@Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_UP:// 手指抬起时 int scrollX = getScrollX();// 获取左边隐藏的宽度 if (scrollX > mMenuWidth / 2) { // 关闭menu this.smoothScrollTo(mMenuWidth, 0); isOpen = false; } else { this.smoothScrollTo(0, 0); isOpen = true; } return true; } return super.onTouchEvent(ev); }
④当菜单打开过程中,添加动画效果,重写onScrollChanged方法即可
@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.6 => 0.6+0.4*scale * * 菜单区域: * 位移 * 缩放0.6->1.0 => 0.6+0.4*(1-scale) * 透明度0.6->1.0 => 0.3+0.7*(1-scale) */ float rightScale = (float) (0.6 + 0.4 * scale); float leftScale = (float) (0.6 + 0.4 * (1 - scale)); float leftAphla = (float) (0.2 + 0.7 * (1 - scale)); // 设置内容的缩放中心点 ViewHelper.setPivotX(mContent, 0); ViewHelper.setPivotY(mContent, mContent.getHeight() / 2); // 设置内容缩放 ViewHelper.setScaleX(mContent, rightScale); ViewHelper.setScaleY(mContent, rightScale); // 设置菜单的位移 ViewHelper.setTranslationX(mMenu, mMenuWidth * scale * 0.6f); ViewHelper.setScaleX(mMenu, leftScale); ViewHelper.setScaleY(mMenu, leftScale); ViewHelper.setAlpha(mMenu, leftAphla); }
⑤我们这个控件提供一个方法,这个方法就像一个开关按钮,可以控制打开/关闭菜单
/** * 切换菜单 */ public void toggle() { if (isOpen) { closeMenu(); } else { openMenu(); } }/** * 打开菜单 */private void openMenu() { if (!isOpen) { this.smoothScrollTo(0, 0); isOpen = true; }}/** * 关闭菜单 */private void closeMenu() { if (isOpen) { this.smoothScrollTo(mMenuWidth, 0); isOpen = false; }}
最后完善我们的MainActivity
public class MainActivity extends Activity { private LinearLayout mMainContent; private int mScreenWidth;// 屏幕的宽度 private int mScreenHeight;// 屏幕的高度 private SlidingMenu slidingMenu; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); getScreenSize(); intiView(); } private void intiView() { mMainContent = (LinearLayout)findViewById(R.id.main_content); ViewGroup.LayoutParams params = mMainContent.getLayoutParams(); // 设置主页面的宽高,防止不同手机屏幕大小不一 params.width = mScreenWidth; params.height = mScreenHeight; slidingMenu = (SlidingMenu) findViewById(R.id.main_menu); } public void click(View view) { slidingMenu.toggle(); } public void getScreenSize() { WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); DisplayMetrics outMetrics = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(outMetrics); mScreenWidth = outMetrics.widthPixels; mScreenHeight = outMetrics.heightPixels; }}
===============至此本文档完==================
如果哪里不清楚,可以留言,博主会及时答复。源码下载,博主使用的是as开发的
0 0
- 仿QQ5.0侧滑先行版
- 仿QQ5.0侧滑菜单【AndroidResideMenu】
- 仿QQ5.0侧滑菜单ResideMenu
- 仿QQ5.0侧滑效果
- 高仿qq5.0侧滑效果
- 仿QQ5.0侧滑菜单实现
- 仿QQ5.0的侧滑菜单
- 仿QQ5.0侧滑菜单ResideMenu
- 仿QQ5.0侧滑菜单ResideMenu
- 【案例分享】仿QQ5.0侧滑菜单ResideMenu
- 【Android 案例分享】仿QQ5.0侧滑菜单ResideMenu
- 【Android 案例分享】仿QQ5.0侧滑菜单ResideMenu
- android 实现仿QQ5.0 侧滑菜单
- Android仿QQ5.0侧滑菜单ResideMenu源码分析
- Android仿QQ5.0侧滑菜单ResideMenu源码分析
- Android实现仿QQ5.0的侧滑效果
- Android仿QQ5.0侧滑菜单ResideMenu源码分析
- 【案例分享】仿QQ5.0侧滑菜单ResideMenu
- java学习笔记1
- 替代ByteArrayBuffer 解决missing in SDK23的问题
- 6种单例模式实现
- 22.Generate Parentheses
- viewPaper+Fragment的布局,在初始化时会导致fragment的布局加载和网络请求数据(懒加载)
- 仿QQ5.0侧滑先行版
- 文字上下轮播
- Android的多分辨率适配的处理
- Iterator<Entry<String, HashMap<String, String>>>
- 如何测试Azure虚拟机网络连通性(默认禁Ping)
- HIVE(下)
- struts+spring action应配置为scope="prototype"
- LeetCode Top K Frequent Elements
- ECMAScript 6 学习系列课程 (ES6 常用内置方法的使用)