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

Android實現(xiàn)京東上滑效果

 更新時間:2022年06月22日 09:16:32   作者:qingwangwang  
這篇文章主要為大家詳細(xì)介紹了Android實現(xiàn)京東上滑效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實例為大家分享了Android實現(xiàn)京東上滑效果的具體代碼,供大家參考,具體內(nèi)容如下

前言:

現(xiàn)在很多app首頁的結(jié)構(gòu)都有頭部廣告,上滑固定toolbar及側(cè)滑廣告位等展示,典型的比如招商銀行app,支付寶、哈羅單車、京東、蘇寧金融也有類似的效果。具體如下,左側(cè)為有廣告位存在的情況,右側(cè)無頂部廣告位的樣式:

效果說明:頭部廣告一般在節(jié)假日有活動的時候展示,頁面上滑會有固定標(biāo)題欄展示,靠底部右側(cè)有一個小的廣告位,滑動主屏幕時,廣告位會向右側(cè)收起,屏幕不滾動時,廣告位顯示。本文旨在為實現(xiàn)這種效果提供一種方式,歡迎有其他想法的小伙伴評論交流,接下來將分三塊分別實現(xiàn)頂部廣告位,滑動固定toolbar及側(cè)滑廣告位效果。

頂部廣告位:

分析:有廣告位圖片和沒廣告位圖片的區(qū)別在于下方白色內(nèi)容區(qū)域在圖片下方還是在頂部4個功能項的下方,一種方式:根據(jù)是否有廣告位動態(tài)調(diào)整margin高度;方式二:使用約束布局,根據(jù)情況改變白色區(qū)域內(nèi)容相對誰來布局

實現(xiàn):

這里我們使用第二種方式實現(xiàn):

外層父布局為ConstraintLayout,里面內(nèi)容包含三部分:

1. 底部背景ImageView控件A,有圖片時設(shè)置src,無圖時設(shè)置background;

2. 四個功能選項部分B,即無圖時白色區(qū)域的約束對象;

3. 白色內(nèi)容區(qū)域C,無圖時約束對象為B,有圖時約束對象為A;

<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_header"
android:layout_width="match_parent"
android:layout_height="wrap_content">
?
<ImageView
? ? android:id="@+id/iv_bg_header"
? ? android:layout_width="match_parent"
? ? android:layout_height="300dp"
? ? android:background="@drawable/shape_gradient_yellow"
? ? android:contentDescription="@null"
? ? android:scaleType="fitXY"
? ? app:layout_constraintStart_toStartOf="parent"
? ? app:layout_constraintTop_toTopOf="parent" />
?
<LinearLayout
? ? android:id="@+id/ll_search"
? ? android:layout_width="match_parent"
? ? android:layout_height="wrap_content"
? ? android:layout_marginStart="12dp"
? ? android:layout_marginTop="50dp"
? ? android:layout_marginEnd="12dp"
? ? android:clickable="true"
? ? android:gravity="center_vertical"
? ? android:orientation="horizontal"
? ? app:layout_constraintStart_toStartOf="parent"
? ? app:layout_constraintTop_toTopOf="parent">
?
? ? <EditText
? ? ? ? android:layout_width="0dp"
? ? ? ? android:layout_height="32dp"
? ? ? ? android:layout_weight="1"
? ? ? ? android:background="@drawable/shape_edit_text_stroke_white"
? ? ? ? android:drawableStart="@drawable/vector_search"
? ? ? ? android:drawablePadding="4dp"
? ? ? ? android:drawableTint="@color/color_icon"
? ? ? ? android:hint="請輸入內(nèi)容"
? ? ? ? android:importantForAutofill="no"
? ? ? ? android:paddingStart="8dp"
? ? ? ? android:textColorHint="@color/color_icon"
? ? ? ? android:textSize="14sp"
? ? ? ? tools:ignore="TextFields" />
?
? ? <ImageView
? ? ? ? android:layout_width="wrap_content"
? ? ? ? android:layout_height="wrap_content"
? ? ? ? android:layout_marginStart="12dp"
? ? ? ? android:contentDescription="@null"
? ? ? ? android:src="@drawable/vector_custom_service"
? ? ? ? android:tint="@color/color_icon" />
?
? ? <ImageView
? ? ? ? android:layout_width="wrap_content"
? ? ? ? android:layout_height="wrap_content"
? ? ? ? android:layout_marginStart="12dp"
? ? ? ? android:contentDescription="@null"
? ? ? ? android:src="@drawable/vector_message"
? ? ? ? android:tint="@color/color_icon" />
?
</LinearLayout>
?
<LinearLayout
? ? android:id="@+id/ll_header"
? ? android:layout_width="match_parent"
? ? android:layout_height="wrap_content"
? ? android:clickable="true"
? ? android:orientation="horizontal"
? ? android:paddingTop="20dp"
? ? app:layout_constraintStart_toStartOf="parent"
? ? app:layout_constraintTop_toBottomOf="@id/ll_search">
?
? ? <TextView
? ? ? ? android:layout_width="0dp"
? ? ? ? android:layout_height="wrap_content"
? ? ? ? android:layout_weight="1"
? ? ? ? android:drawableTop="@drawable/vector_code"
? ? ? ? android:drawablePadding="8dp"
? ? ? ? android:gravity="center_horizontal"
? ? ? ? android:text="收/付款"
? ? ? ? android:textColor="@color/color_white" />
?
? ? <TextView
? ? ? ? android:layout_width="0dp"
? ? ? ? android:layout_height="wrap_content"
? ? ? ? android:layout_weight="1"
? ? ? ? android:drawableTop="@drawable/vector_shopping"
? ? ? ? android:drawablePadding="8dp"
? ? ? ? android:gravity="center_horizontal"
? ? ? ? android:text="購物"
? ? ? ? android:textColor="@color/color_white" />
?
? ? <TextView
? ? ? ? android:layout_width="0dp"
? ? ? ? android:layout_height="wrap_content"
? ? ? ? android:layout_weight="1"
? ? ? ? android:drawableTop="@drawable/vector_setting"
? ? ? ? android:drawablePadding="8dp"
? ? ? ? android:gravity="center_horizontal"
? ? ? ? android:text="設(shè)置"
? ? ? ? android:textColor="@color/color_white" />
?
? ? <TextView
? ? ? ? android:layout_width="0dp"
? ? ? ? android:layout_height="wrap_content"
? ? ? ? android:layout_weight="1"
? ? ? ? android:drawableTop="@drawable/vector_function"
? ? ? ? android:drawablePadding="8dp"
? ? ? ? android:gravity="center_horizontal"
? ? ? ? android:text="全部功能"
? ? ? ? android:textColor="@color/color_white" />
?
</LinearLayout>
?
<include
? ? android:id="@+id/ll_services"
? ? layout="@layout/layout_services"
? ? android:layout_width="match_parent"
? ? android:layout_height="wrap_content"
? ? android:layout_marginTop="20dp"
? ? app:layout_constraintStart_toStartOf="parent"
? ? app:layout_constraintTop_toBottomOf="@id/ll_header" />
?
</androidx.constraintlayout.widget.ConstraintLayout>

展示廣告位的情況下

ivBgHeader.setBackgroundResource(0);
ivBgHeader.setImageResource(R.mipmap.ic_ad_banner);
ivBgHeader.setOnClickListener(v -> Toast.makeText(getActivity(), "拍一拍", Toast.LENGTH_SHORT).show());
ConstraintSet c = new ConstraintSet();
c.clone(clHeader);
c.connect(llServices.getId(), ConstraintSet.TOP, ivBgHeader.getId(), ConstraintSet.BOTTOM, Utils.dip2pixel(getActivity(), 20));
c.applyTo(clHeader);

不展示廣告位情況下:

ivBgHeader.setBackgroundResource(R.drawable.shape_gradient_yellow);
ivBgHeader.setImageResource(0);
ivBgHeader.setOnClickListener(null);
ConstraintSet c = new ConstraintSet();
c.clone(clHeader);
c.connect(llServices.getId(), ConstraintSet.TOP, llHeader.getId(), ConstraintSet.BOTTOM, Utils.dip2pixel(getActivity(), 20));
c.applyTo(clHeader);

側(cè)滑廣告位:

分析:首頁的滑動布局為NestedScrollView控件實現(xiàn)的,NestedScrollView并沒有像RecyclerView一樣提供滑動狀態(tài)的監(jiān)聽,所以關(guān)于滑動狀態(tài)需要我們?nèi)ヅ袛啵鼫?zhǔn)確可以說是監(jiān)聽狀態(tài)的改變結(jié)果,而不是監(jiān)聽狀態(tài)的過程,狀態(tài)結(jié)果分兩種:靜止和滑動。NestedScrollView提供了onScrollChanged回調(diào)方法,在內(nèi)部View滑動時會走到這個回調(diào),所以走這個回調(diào)肯定是滑動中狀態(tài),如何判斷靜止?fàn)顟B(tài)呢?通常是使用定時器或是handler發(fā)送消息的方式去監(jiān)聽。

實現(xiàn):

自定義View繼承NestedScrollView,在內(nèi)部將狀態(tài)提供給外部去使用

public class ObservableScrollView extends NestedScrollView {
?
? ? public static final int STATE_IDLE = 1;
? ? public static final int STATE_SCROLL = 2;
?
? ? public int currentState = STATE_IDLE;
? ? private boolean isOnActionDown = false;
?
? ? private ScrollStateChangeListener scrollStateChangeListener;
? ? private Handler mHandler;
? ? private static final int MSG_IS_SCROLL = 1;
?
? ? public ObservableScrollView(@NonNull Context context) {
? ? ? ? this(context, null);
? ? }
?
? ? public ObservableScrollView(@NonNull Context context, @Nullable AttributeSet attrs) {
? ? ? ? this(context, attrs, 0);
? ? }
?
? ? public ObservableScrollView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
? ? ? ? super(context, attrs, defStyleAttr);
? ? ? ? mHandler = new Handler(Looper.getMainLooper()) {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void handleMessage(@NonNull Message msg) {
? ? ? ? ? ? ? ? super.handleMessage(msg);
? ? ? ? ? ? ? ? if (currentState == STATE_SCROLL) {
? ? ? ? ? ? ? ? ? ? currentState = STATE_IDLE;
? ? ? ? ? ? ? ? ? ? if (null != scrollStateChangeListener) {
? ? ? ? ? ? ? ? ? ? ? ? scrollStateChangeListener.onScrollChange(ObservableScrollView.this, currentState);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? };
? ? }
?
? ? @Override
? ? protected void onScrollChanged(int x, int y, int oldX, int oldY) {
? ? ? ? super.onScrollChanged(x, y, oldX, oldY);
? ? ? ? if (isOnActionDown)
? ? ? ? ? ? return;
? ? ? ? mHandler.removeCallbacksAndMessages(null);
? ? ? ? mHandler.sendEmptyMessageDelayed(MSG_IS_SCROLL, 500);
? ? ? ? setStatus();
? ? }
?
? ? private void setStatus() {
? ? ? ? if (currentState == STATE_IDLE) {
? ? ? ? ? ? currentState = STATE_SCROLL;
? ? ? ? ? ? if (null != scrollStateChangeListener) {
? ? ? ? ? ? ? ? scrollStateChangeListener.onScrollChange(this, currentState);
? ? ? ? ? ? }
? ? ? ? }
? ? }
?
? ? @Override
? ? public boolean onTouchEvent(MotionEvent ev) {
? ? ? ? switch (ev.getAction()) {
? ? ? ? ? ? case MotionEvent.ACTION_UP:
? ? ? ? ? ? case MotionEvent.ACTION_CANCEL:
? ? ? ? ? ? ? ? isOnActionDown = false;
? ? ? ? ? ? ? ? mHandler.sendEmptyMessageDelayed(MSG_IS_SCROLL, 500);
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? case MotionEvent.ACTION_DOWN:
? ? ? ? ? ? case MotionEvent.ACTION_MOVE:
? ? ? ? ? ? ? ? mHandler.removeCallbacksAndMessages(null);
? ? ? ? ? ? ? ? setStatus();
? ? ? ? ? ? ? ? isOnActionDown = true;
? ? ? ? ? ? ? ? break;
? ? ? ? }
? ? ? ? return super.onTouchEvent(ev);
? ? }
?
? ? public void addOnScrollChangeListener(ScrollStateChangeListener scrollStateChangeListener) {
? ? ? ? this.scrollStateChangeListener = scrollStateChangeListener;
? ? }
?
? ? public interface ScrollStateChangeListener {
? ? ? ? void onScrollChange(ObservableScrollView view, int newState);
? ? }
?
? ? public void onDestroy() {
? ? ? ? if (null != mHandler) {
? ? ? ? ? ? mHandler.removeCallbacksAndMessages(null);
? ? ? ? }
? ? }
}

外部使用:

scrollView.addOnScrollChangeListener(new ObservableScrollView.ScrollStateChangeListener() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void onScrollChange(ObservableScrollView view, int newState) {
? ? ? ? ? ? ? ? if (newState == STATE_IDLE) {
? ? ? ? ? ? ? ? ? ? ivSideScroll.animate().translationX(0);
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? ivSideScroll.animate().translationX(200);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? });

固定頂部效果:

分析:監(jiān)聽scrollView滑動變化量,分別在上滑和下滑時做固定內(nèi)容部分的透明度值變化

實現(xiàn):

scrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
? ? ? ? ? ? ? ? // 向上滑動,超過100像素則透明度開始由0 -> 1?
? ? ? ? ? ? ? ? if (scrollY - oldScrollY > 0) {
? ? ? ? ? ? ? ? ? ? float alpha = Math.min(1, (scrollY - 100) / 50f);
? ? ? ? ? ? ? ? ? ? llFixedHeader.setAlpha(alpha);
? ? ? ? ? ? ? ? }
?
? ? ? ? ? ? ? ? // 向下滑動,小于100像素則透明度開始 1 -> 0
? ? ? ? ? ? ? ? if (scrollY - oldScrollY < 0) {
? ? ? ? ? ? ? ? ? ? float alpha = Math.max(0, (scrollY - 100) / 50f);
? ? ? ? ? ? ? ? ? ? llFixedHeader.setAlpha(alpha);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? });

最終實現(xiàn)效果:

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論