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

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

概述先看看QQ的侧滑效果分析一下先上原理图(不知道能否表达的清楚==)-首先这里使用了Android的HorizontalScrollView水平滑动布局作为容器,当然我们需要继承它自定义一个侧滑视图

先看看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,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);      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 oldl,int oldt) {    super.onScrollChanged(l,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自定义View 仿QQ侧滑菜单的实现代码所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1144606.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-31
下一篇2022-05-31

发表评论

登录后才能评论

评论列表(0条)

    保存