欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android自定義View 仿QQ側滑菜單的實現(xiàn)代碼

 更新時間:2017年08月31日 08:44:56   作者:Lukang_0513  
這篇文章主要介紹了Android自定義View 仿QQ側滑菜單的實現(xiàn)代碼,非常不錯,具有參考借鑒價值,需要的朋友可以參考下

先看看QQ的側滑效果

這里寫圖片描述

分析一下

先上原理圖(不知道能否表達的清楚 ==)

這里寫圖片描述

-首先這里使用了 Android 的HorizontalScrollView 水平滑動布局作為容器,當然我們需要繼承它自定義一個側滑視圖

- 這個容器里面有一個父布局(一般用LinerLayout,本demo用的是),這個父布局里面有且只有兩個子控件(布局),初始狀態(tài)菜單頁的位置在Y軸上存在偏移這樣可以就可以形成主頁疊在菜單頁的上方的視覺效果;然后在滑動的過程程中 逐漸修正偏移,最后菜單頁和主頁并排排列。原理搞清了實現(xiàn)起來就不是事兒了……

具體實現(xiàn)

布局代碼

<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 從默認偏移量到偏移量 為零
     *實現(xiàn)
     * */
    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,寫入以下內(nèi)容:

<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側滑菜單的實現(xiàn)代碼,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關文章

最新評論