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

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

 更新時間:2016年08月16日 17:10:30   作者:卜可  
很多電商類app的商品詳情頁(其他app也有類似效果,比如qq音樂)都有這么一個效果:當(dāng)用戶向上滑動頁面內(nèi)容超過一定距離后,中間的標(biāo)題欄會卡在頂部,往下拉回到固定高度后又會消失。那么如何實(shí)現(xiàn)這個效果呢?跟著小編一起來學(xué)習(xí)學(xué)習(xí)。

1、效果圖如下:

這效果用戶體驗(yàn)還是很酷炫,今天我們就來講解如何實(shí)現(xiàn)這個效果。

2、分析

為了方便理解,作圖分析


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

     1、懸浮內(nèi)容,floatView

     2、頂部內(nèi)容,headView

     3、中間內(nèi)容,與懸浮內(nèi)容相同,middleView

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

因?yàn)轫撁鎯?nèi)容高度會超出屏幕,所以用Scrollview實(shí)現(xiàn)滾動,懸浮viewscrollview同級,都在一個幀布局或者相對布局中。

當(dāng)y方向的滾動距離小于中間的內(nèi)容middleView到頂部的距離時,middleView理所當(dāng)然的會隨這頁面向上滑動而消失,我們顯示懸浮view,從而實(shí)現(xiàn)middleView一直卡在頂部的效果。

當(dāng)y方向滾動距離大于中間的內(nèi)容middleView容到頂部的距離時,懸浮view隱藏即可。

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

3、第一種方法實(shí)現(xiàn)

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,這是因?yàn)榇藭rview還沒有繪制到界面,所以我們采用上面的方法給view設(shè)置監(jiān)聽獲取,由于可能發(fā)生多次繪制,所以最后記得移除監(jiān)聽事件。

以下代碼同樣可以獲?。?/strong>

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

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

3.2 獲取垂直方向滾動距離

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

自定義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;

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

3.3 使用

acitivity中給scrollview設(shè)置自定義滾動監(jiān)聽事件即可

  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設(shè)置觸摸監(jiān)聽,將用戶手勢傳遞給scrollView,這樣用戶滑動懸浮view時,內(nèi)容區(qū)域也可以跟隨滾動。

下面是布局代碼

<?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="標(biāo)題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="標(biāo)題view"
    android:visibility="invisible"/>

</RelativeLayout>

4、第二種方式

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

 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);
        }
      }
    });

可能有讀者要問,既然有這種簡單的方法直接設(shè)置監(jiān)聽,為什么還介紹第一種方法。細(xì)心的你可能已經(jīng)發(fā)現(xiàn),在第一種方法中,我在自定義的監(jiān)聽事件中,還回調(diào)了代表當(dāng)前回調(diào)狀態(tài)的參數(shù)statue,因?yàn)楹芏郺pp,在用戶手動拖動滾動跟慣性滾動的處理是不能的。比如淘寶商品詳情頁面,當(dāng)達(dá)到邊界值中間viewtop值時,只有用戶手動拖動一段距離后才會拉出底部的詳情類容,而慣性滑動的話只會停在那里。

5、總結(jié)

以上就是關(guān)于安卓實(shí)現(xiàn)按鈕隨著上下滾動而懸浮頂在固定位置的方法,希望本文的內(nèi)容對大家開發(fā)Android能有所幫助。

相關(guān)文章

最新評論