購買欄懸浮效果實現
阿新 • • 發佈:2019-02-05
在各電商APP的商品詳情頁中,我們經常會看到這種效果。
預設情況下,購買欄顯示在商品圖片下方:當頁面向上滑動,購買欄滑動到螢幕頂部時,會一直固定在螢幕頂部:
今天我們來實現這種顯示效果。
實現思路:
首先,頁面能夠滾動,需要ScrollView的支援。在ScrollView內部,包含一個垂直方向的LinearLayout,商品圖片和購買欄呈垂直線性排列,這些都比較容易想到。難點在於如何把頁面中的購買欄固定住,而頁面還可以繼續滾動。那麼我們就變換一下思維,如果從一開始,在螢幕的頂部就一直存在著一個一模一樣的購買欄,只不過是隱藏狀態,當商品圖片下邊的購買欄滑動到螢幕頂部時,我們將螢幕頂部已有的購買欄顯示出來就好啦。
思路圖:
基於上述思路,我們就有了下面的佈局程式碼:
好了,下面開始用程式碼實現邏輯了。
我們首先要獲取到商品圖片區域的高度,然後監聽ScrollView在垂直方向的滾動距離,當滾動距離大於商品圖片的高度時,就將螢幕頂部的購買欄顯示出來,否則將其隱藏。
監聽滾動,很容易會想到setOnScrollChangeListener(OnScrollChangeListener l)方法。不過,很遺憾的是,ScrollView只有在api level 23以上,才提供了該方法。那麼,在低版本中,我們如何監聽ScrollView的滾動呢?
我們發現,在ScrollView中,有如下方法。
而且,該方法是protected的,那麼我們可以自定義一個View,繼承自ScrollView,然後重寫onScrollChanged()方法,將引數t(垂直方向的滾動距離)回調出去為我們所用。/** * This is called in response to an internal scroll in this view (i.e., the * view scrolled its own contents). This is typically as a result of * {@link #scrollBy(int, int)} or {@link #scrollTo(int, int)} having been * called. * * @param l Current horizontal scroll origin. * @param t Current vertical scroll origin. * @param oldl Previous horizontal scroll origin. * @param oldt Previous vertical scroll origin. */ protected void onScrollChanged(int l, int t, int oldl, int oldt) { // ... }
實現如下。
package net.csdn.blog.ruancoder; import android.content.Context; import android.util.AttributeSet; import android.widget.ScrollView; public class ScrollChangedView extends ScrollView { private OnScrollChangedListener mListener; public void setOnScrollChangedListener(OnScrollChangedListener listener) { this.mListener = listener; } public ScrollChangedView(Context context) { super(context); } public ScrollChangedView(Context context, AttributeSet attrs) { super(context, attrs); } public ScrollChangedView(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 (mListener != null) { // 將ScrollView垂直方向滾動的距離回調出去 mListener.onScrollChanged(t); } } public interface OnScrollChangedListener { void onScrollChanged(int scrollY); } }
然後在Activity中,監聽ScrollChangedView.OnScrollChangedListener,根據scrollY的大小來控制頂部購買欄的顯示或隱藏,就可以實現上述效果。
package net.csdn.blog.ruancoder;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewTreeObserver;
public class MainActivity extends Activity implements ScrollChangedView.OnScrollChangedListener {
private View mFixedBuyBar;// 頂部固定的購買欄
private int mTopViewHeight;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final View topView = findViewById(R.id.top_view);
mFixedBuyBar = findViewById(R.id.fixed_buy_button_bar);
mFixedBuyBar.setVisibility(View.GONE);
final ScrollChangedView scrollView = (ScrollChangedView) findViewById(R.id.scrollview);
scrollView.setOnScrollChangedListener(this);
scrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
// 獲取頂部檢視的高度
mTopViewHeight = topView.getHeight();
scrollView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
}
@Override
public void onScrollChanged(int scrollY) {
if (scrollY > mTopViewHeight) {// 滾動超出頂部檢視的高度,此時顯示頂部固定的購買欄
mFixedBuyBar.setVisibility(View.VISIBLE);
} else {// 否則,隱藏頂部固定的購買欄
mFixedBuyBar.setVisibility(View.GONE);
}
}
}
最後附上完整工程程式碼下載連結:
http://download.csdn.net/detail/ruancoder/9594054