全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

Android自定义View 仿QQ侧滑菜单的实现代码

先看看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);
/*
    *//**设置缩放时的 轴心点**//*
    //此处轴心为右边界的中点
    ViewHelper.setPivotY(home, mScreenWidth);
    ViewHelper.setPivotX(home, home.getHeight() / 2);
    *//**设置 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,写入以下内容:

<resources>
  <declare-styleable name="MyScrollView">
    <attr name="rightPanding" format="dimension" />
    <attr name="leftPanding" format="dimension" />
  </declare-styleable>
</resources>

在布局里设置边距

 <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侧滑菜单的实现代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!


# android  # 自定义view  # qq  # 侧滑菜单  # Android解决viewpager嵌套滑动冲突并保留侧滑菜单功能  # Android自定义HorizontalScrollView实现qq侧滑菜单  # android RecyclerView侧滑菜单  # 滑动删除  # 长按拖拽  # 下拉刷新上拉加载  # Android自定义ViewGroup(侧滑菜单)详解及简单实例  # Android控件View打造完美的自定义侧滑菜单  # Android使用自定义控件HorizontalScrollView打造史上最简单的侧滑菜单  # 自定义  # 偏移量  # 小编  # 拉出  # 的是  # 在此  # 就不  # 其他的  # 就行  # 跑到  # 给大家  # 点击下载  # 所述  # 给我留言  # 值为  # 感谢大家  # 为零  # 就可以  # 源码下载  # 清了 


相关文章: 如何通过VPS建站实现广告与增值服务盈利?  深圳网站制作案例,网页的相关名词有哪些?  如何在阿里云虚拟主机上快速搭建个人网站?  如何在西部数码注册域名并快速搭建网站?  小自动建站系统:AI智能生成+拖拽模板,多端适配一键搭建  建站之星安装路径如何正确选择及配置?  建站之星如何配置系统实现高效建站?  电商网站制作多少钱一个,电子商务公司的网站制作费用计入什么科目?  如何选择CMS系统实现快速建站与SEO优化?  如何选择建站程序?包含哪些必备功能与类型?  如何基于PHP生成高效IDC网络公司建站源码?  专业型网站制作公司有哪些,我设计专业的,谁给推荐几个设计师兼职类的网站?  定制建站价位费用解析与套餐推荐全攻略  如何用好域名打造高点击率的自主建站?  如何优化Golang Web性能_Golang HTTP服务器性能提升方法  建站之星如何快速更换网站模板?  阿里云网站制作公司,阿里云快速搭建网站好用吗?  微信推文制作网站有哪些,怎么做微信推文,急?  已有域名如何免费搭建网站?  网站app免费制作软件,能免费看各大网站视频的手机app?  网站插件制作软件免费下载,网页视频怎么下到本地插件?  深圳防火门网站制作公司,深圳中天明防火门怎么编码?  如何自己制作一个网站链接,如何制作一个企业网站,建设网站的基本步骤有哪些?  胶州企业网站制作公司,青岛石头网络科技有限公司怎么样?  专业网站制作服务公司,有哪些网站可以免费发布招聘信息?  网站制作公司,橙子建站是合法的吗?  如何在云主机快速搭建网站站点?  如何通过万网虚拟主机快速搭建网站?  关于BootStrap modal 在IOS9中不能弹出的解决方法(IOS 9 bootstrap modal ios 9 noticework)  广州顶尖建站服务:企业官网建设与SEO优化一体化方案  相亲简历制作网站推荐大全,新相亲大会主持人小萍萍资料?  免费网站制作模板下载,除了易企秀之外还有什么H5平台可以制作H5长页面,最好是免费的?  建站上传速度慢?如何优化加速网站加载效率?  安云自助建站系统如何快速提升SEO排名?  品牌网站制作公司有哪些,买正品品牌一般去哪个网站买?  寿县云建站:智能SEO优化与多行业模板快速上线指南  头像制作网站在线观看,除了站酷,还有哪些比较好的设计网站?  想学网站制作怎么学,建立一个网站要花费多少?  云南网站制作公司有哪些,云南最好的招聘网站是哪个?  开源网站制作软件,开源网站什么意思?  如何通过建站之星自助学习解决操作问题?  建站org新手必看:2024最新搭建流程与模板选择技巧  北京的网站制作公司有哪些,哪个视频网站最好?  大连企业网站制作公司,大连2025企业社保缴费网上缴费流程?  如何在建站之星网店版论坛获取技术支持?  黑客如何利用漏洞与弱口令入侵网站服务器?  香港服务器如何优化才能显著提升网站加载速度?  建站之星代理商如何保障技术支持与售后服务?  东莞市网站制作公司有哪些,东莞找工作用什么网站好?  如何快速搭建高效服务器建站系统? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。