时间:2021-05-20
先看看QQ的侧滑效果
分析一下
先上原理图(不知道能否表达的清楚 ==)
-首先这里使用了 Android 的HorizontalScrollView 水平滑动布局作为容器,当然我们需要继承它自定义一个侧滑视图
- 这个容器里面有一个父布局(一般用LinerLayout,本demo用的是),这个父布局里面有且只有两个子控件(布局),初始状态菜单页的位置在Y轴上存在偏移这样可以就可以形成主页叠在菜单页的上方的视觉效果;然后在滑动的过程程中 逐渐修正偏移,最后菜单页和主页并排排列。原理搞清了实现起来就不是事儿了……
具体实现
布局代码
<fierce_luk.com.sideslipviewdemo2.SideslipView android:id="@+id/my_veiw" android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbars="none" luk:leftPanding="200dp"> <!--如果菜单在左边直接用 LinearLayout--> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <TextView android:id="@+id/image2" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@mipmap/homepage" android:gravity="center" android:tag="0" android:text="菜单" android:textColor="@color/colorAccent" android:textSize="60sp" /> <TextView android:id="@+id/image1" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/color1" android:gravity="center" android:tag="1" android:text="主页面" android:textColor="@color/colorAccent" android:textSize="60sp" /> </FrameLayout> <!--<fragment--> <!--android:name="com.luk.bluetoothapp.fragment.MyBluetoothDevice"--> <!--android:layout_width="match_parent"--> <!--android:layout_height="match_parent"--> <!--android:tag="1" />--> <!--<fragment--> <!--android:name="com.luk.bluetoothapp.fragment.HomeFragment"--> <!--android:layout_width="match_parent"--> <!--android:layout_height="match_parent"--> <!--android:tag="0" />--> </fierce_luk.com.sideslipviewdemo2.SideslipView>自定义的侧滑视图
最核心的部分
public class SideslipView extends HorizontalScrollView { private int mScreenWidth;//屏幕宽度 private int mMenuLeftPadding; private int mBluetoothWidth;//菜单的宽度 private int mHalfMenuWidth; View home; View bluetooth; protected boolean isOpen; protected boolean isFirst = true; public SideslipView(Context context) { // super 改 this this(context, null); } public SideslipView(Context context, AttributeSet attrs) { // super 改 this this(context, attrs, 0); } public SideslipView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); //测量屏幕宽度 WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); DisplayMetrics metrics = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(metrics); mScreenWidth = metrics.widthPixels; // mScreenWidth = context.getResources().getDisplayMetrics().widthPixels; Log.e("TAG", "MyScrollView: mScreenWidth" + mScreenWidth); //获取 自定义的属性值 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyScrollView); int n = a.length(); for (int i = 0; i < n; i++) { int arrt = a.getIndex(i); switch (arrt) { case R.styleable.MyScrollView_leftPanding: mMenuLeftPadding = (int) a.getDimension(R.styleable.MyScrollView_leftPanding, 0); break; default: break; } } Log.e("TAG", "MyScrollView: mMenuLeftPadding" + mMenuLeftPadding); a.recycle(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (isFirst) { //获取子布局 并设置宽度 //如果菜单在左边 用LinearLayout就行// LinearLayout layout = (LinearLayout) this.getChildAt(0); /**此处因为 把侧边拉出页面设置在了右边 所有用 FrameLayout * 不然在设置偏移量时 隐藏的侧边菜单会跑到主页面的上面*/ FrameLayout layout = (FrameLayout) this.getChildAt(0); home = layout.getChildAt(1); bluetooth = layout.getChildAt(0); LayoutParams params = new LayoutParams(mBluetoothWidth, getResources().getDisplayMetrics().heightPixels); params.setMargins(mScreenWidth, 0, 0, 0); bluetooth.setLayoutParams(params); mBluetoothWidth = mScreenWidth - mMenuLeftPadding; home.getLayoutParams().width = mScreenWidth; bluetooth.getLayoutParams().width = mBluetoothWidth; mHalfMenuWidth = mBluetoothWidth / 2; isFirst = 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); //首先隐藏 Bluetooth if (changed) this.scrollTo(0, mBluetoothWidth); } Animation anim; @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_UP: int scrollX = getScrollX(); if (scrollX >= mHalfMenuWidth) { Log.e("TAG", "===="); this.smoothScrollTo(mBluetoothWidth, 0); isOpen = true; } else { this.smoothScrollTo(0, 0); isOpen = false; } //必须消耗事件 return true; } return super.onTouchEvent(ev); //return true; } /** * 打开菜单栏 */ protected void openMenu() { if (isOpen) return; this.smoothScrollTo(mBluetoothWidth, 0); isOpen = true; } /** * 关闭菜单栏 */ protected void closeMenu() { if (!isOpen) return; this.smoothScrollTo(0, 0); isOpen = false; } /** * 按钮切换菜单 */ public void toggleMenu() { if (isOpen) closeMenu(); else openMenu(); } @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt);//此处 l 起始值为零(没有偏移) Log.e("TAG", "l=" + l + " t=" + t); Log.e("TAG", "oldl=" + oldl + " oldt=" + oldt); // scale 在 1 到 0 之间 float scale = l * 1.0f / mBluetoothWidth; /** * 抽屉式侧滑 * scaleLeft 从默认偏移量到偏移量 为零 *实现 * */ float scaleLeft = 0.4f - 0.4f * scale; /**设置 X 轴方向的偏移量**/ ViewHelper.setTranslationX(bluetooth, -(mBluetoothWidth * scaleLeft)); Log.e("TAG", "mBluetoothWidth+" + mBluetoothWidth); Log.e("TAG", "=============" + mBluetoothWidth * scale + "scale" + scale);/**设置缩放时的 轴心点**//**设置 XY轴方向的 缩放动画(从 1 到 0.9)**//* float pivoXY = 1 - 0.4f * scale; ViewHelper.setScaleX(home, pivoXY); ViewHelper.setScaleY(home, pivoXY);*//**设置透明度**//* //从 1 到 0.6; float alpha = 1 - 0.4f * scale; ViewHelper.setAlpha(home, alpha);*/ }}扩展
添加之定义属性 让用户配置菜单距离右边的边距的值;
首先在values文件夹下新建一个attr.xml,写入以下内容:
在布局里设置边距
<fierce_luk.com.sideslipviewdemo2.SideslipView android:id="@+id/my_veiw" android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbars="none" luk:leftPanding="200dp">其他的就不赘述了,看看效果
- 源码下载Demo源码点击下载
总结
以上所述是小编给大家介绍的Android自定义View 仿QQ侧滑菜单的实现代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
自定义布局实现仿qq侧滑部分Android代码,供大家参考,具体内容如下源码DEMO地址:https://github.com/applelili/Imitat
前面已经讲过通过三方开源库SlideMenu来实现这种效果,请参考Android实现网易新闻客户端侧滑菜单(一)今天通过自定义View来实现这种功能。代码如下:
本课程将带领大家通过自定义控件实现QQ5.0侧滑菜单,课程将循序渐进,首先实现最普通的侧滑菜单,然后引入属性动画与拖动菜单效果相结合,最终实现QQ5.0侧滑菜单
一、概述 在App中,经常会出现侧滑菜单,侧滑滑出View等效果,虽然说Android有很多第三方开源库,但是实际上咱们可以自己也写一个自定义的侧滑View控
Android自定义SwipeLayout仿QQ侧滑条目,供大家参考,具体内容如下先看动图看布局文件activity_main.xml