Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 安卓(android)仿電商app商品詳情頁按鈕浮動效果

安卓(android)仿電商app商品詳情頁按鈕浮動效果

編輯:關於Android編程

1、效果圖如下:

這效果用戶體驗還是很酷炫,今天我們就來講解如何實現這個效果。

2、分析

為了方便理解,作圖分析


如圖所示,整個頁面分為四個部分:

     1、懸浮內容,floatView

     2、頂部內容,headView

     3、中間內容,與懸浮內容相同,middleView

     4、商品詳情展示頁面,detailView

因為頁面內容高度會超出屏幕,所以用Scrollview實現滾動,懸浮viewscrollview同級,都在一個幀布局或者相對布局中。

當y方向的滾動距離小於中間的內容middleView到頂部的距離時,middleView理所當然的會隨這頁面向上滑動而消失,我們顯示懸浮view,從而實現middleView一直卡在頂部的效果。

當y方向滾動距離大於中間的內容middleView容到頂部的距離時,懸浮view隱藏即可。

通過分析,我們發現只要知道scrollview的滾動距離和middleView到頂部的高度即可。至此將復雜的交互特效變成了倆個簡單的api。

3、第一種方法實現

3.1 獲取middleView的到父容器頂部的距離

 tv_title.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
    {
      @Override
      public void onGlobalLayout()
      {
        mTitleTopAndHeight = tv_title.getTop();

        tv_title.getViewTreeObserver().removeGlobalOnLayoutListener(this);
      }
    });

在activity的oncreate()中直接通過view的getTop()方法獲取到view的高度會返回0,這是因為此時view還沒有繪制到界面,所以我們采用上面的方法給view設置監聽獲取,由於可能發生多次繪制,所以最後記得移除監聽事件。

以下代碼同樣可以獲取:

   tv_title.post(new Runnable()
    {
      @Override
      public void run()
      {
        mTitleTopAndHeight = tv_title.getTop();
      }
    });

利用post方法將操作放到隊列中,等系統布局完成後執行隊列中的事件,同樣可以獲取到正確的viewtop值。

3.2 獲取垂直方向滾動距離

Scrollview的父類View中有個內容變化的方法onScrollChanged(),雖然該方法是protect的外部不可調用,但是在內部,當scrollview滾動時就會執行該方法,所以我們自定義一個MyScrollViewonScrollChanged()通過回調將滾動的距離傳遞給外部。

自定義scrollview完整代碼如下:

public class MyScrollView extends ScrollView
{
  private OnScrollListener mOnScrollListener;

  /**
   * 是否用戶手指觸摸滑動
   */
  private boolean mIsTouch = false;

  public MyScrollView(Context context)
  {
    this(context, null);
  }

  public MyScrollView(Context context, AttributeSet attrs)
  {
    this(context, attrs, 0);
  }

  public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr)
  {
    super(context, attrs, defStyleAttr);
  }

  @Override
  protected void onScrollChanged(int l, int t, int oldl, int oldt)
  {
    super.onScrollChanged(l, t, oldl, oldt);

    if (mOnScrollListener != null)
    {
      mOnScrollListener.onScroll(t, mIsTouch ? OnScrollListener.SCROLL_STATE_TOUCH_SCROLL : OnScrollListener.SCROLL_STATE_FLING);
    }
  }

  @Override
  public boolean onTouchEvent(MotionEvent ev)
  {
    switch (ev.getAction())
    {
      case MotionEvent.ACTION_MOVE:
        mIsTouch = true;

        break;
      case MotionEvent.ACTION_UP:
      case MotionEvent.ACTION_CANCEL:
        mIsTouch = false;

        break;
    }

    return super.onTouchEvent(ev);
  }

  public void setOnScrollListener(OnScrollListener onScrollListener)
  {
    mOnScrollListener = onScrollListener;
  }

  public interface OnScrollListener
  {
    /**
     * 用戶手指拖動滾動
     */
    int SCROLL_STATE_TOUCH_SCROLL = 0x0;

    /**
     * 慣性滑行滾動
     */
    int SCROLL_STATE_FLING = 0x1;

    /**
     * 滾動時的回調
     *
     * @param scrollY   Y方向滾動的距離
     * @param scroll_state 當前滾動狀態:自由滾動或者手勢拖動滾動
     */
    void onScroll(int scrollY, int scroll_state);
  }
}

3.3 使用

acitivity中給scrollview設置自定義滾動監聽事件即可

  mScrollView.setOnScrollListener(new MyScrollView.OnScrollListener()
    {
      @Override
      public void onScroll(int scrollY, int state)
      {
        Log.d("onScroll: ", scrollY + "" + "----------- state:" + state);

        if (scrollY <= mTitleTopAndHeight)
        {
          tv_float.setVisibility(View.INVISIBLE);
        } else
        {
          tv_float.setVisibility(View.VISIBLE);
        }
      }
    });

這樣,通過垂直方法的滾動值來控制floatView的顯示隱藏,

    tv_float.setOnTouchListener(new View.OnTouchListener()
    {
      @Override
      public boolean onTouch(View v, MotionEvent event)
      {
        mScrollView.onTouchEvent(event);
        return false;
      }
    });

給懸浮view設置觸摸監聽,將用戶手勢傳遞給scrollView,這樣用戶滑動懸浮view時,內容區域也可以跟隨滾動。

下面是布局代碼

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  >

  <com.example.qike.scrolltitle.MyScrollView
    android:id="@+id/sv_main"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:orientation="vertical">

      <TextView
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:gravity="center"
        android:text="商品圖片"/>

      <TextView
        android:id="@+id/tv_title"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:background="#a3c"
        android:gravity="center"
        android:text="標題view"/>

      <TextView
        android:layout_width="match_parent"
        android:layout_height="600dp"
        android:background="#a2bb"
        android:gravity="center"
        android:text="詳情頁面"/>
    </LinearLayout>
  </com.example.qike.scrolltitle.MyScrollView>

  <TextView
    android:id="@+id/tv_float"
    android:layout_width="match_parent"
    android:layout_height="40dp"
    android:background="#a3c"
    android:gravity="center"
    android:text="標題view"
    android:visibility="invisible"/>

</RelativeLayout>

4、第二種方式

本方法與第一種方式的區別就是獲取滾動位置的方法不同,該方法更簡單一些:

 mScrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener()
    {
      @Override
      public void onScrollChanged()
      {
        int scrollY = mScrollView.getScrollY();
        if (scrollY <= mTitleTopAndHeight)
        {
          tv_float.setVisibility(View.INVISIBLE);
        } else
        {
          tv_float.setVisibility(View.VISIBLE);
        }
      }
    });

可能有讀者要問,既然有這種簡單的方法直接設置監聽,為什麼還介紹第一種方法。細心的你可能已經發現,在第一種方法中,我在自定義的監聽事件中,還回調了代表當前回調狀態的參數statue,因為很多app,在用戶手動拖動滾動跟慣性滾動的處理是不能的。比如淘寶商品詳情頁面,當達到邊界值中間viewtop值時,只有用戶手動拖動一段距離後才會拉出底部的詳情類容,而慣性滑動的話只會停在那裡。

5、總結

以上就是關於安卓實現按鈕隨著上下滾動而懸浮頂在固定位置的方法,希望本文的內容對大家開發Android能有所幫助。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved