溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android中如何使用CoordinatorLayout+AppBarLayout實現(xiàn)拉伸頂部圖片功能

發(fā)布時間:2021-09-27 13:44:05 來源:億速云 閱讀:154 作者:小新 欄目:編程語言

這篇文章主要介紹了Android中如何使用CoordinatorLayout+AppBarLayout實現(xiàn)拉伸頂部圖片功能,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

直接上布局文件代碼

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" android:clipChildren="false" android:clipToPadding="false"> <androidx.coordinatorlayout.widget.CoordinatorLayout  android:layout_width="match_parent"  android:layout_height="match_parent">  <com.google.android.material.appbar.AppBarLayout   android:layout_width="match_parent"   android:layout_height="wrap_content"   app:layout_behavior="com.ce.myscrollimg.AppBarLayoutOverScrollViewBehavior">   <com.google.android.material.appbar.CollapsingToolbarLayout    android:layout_width="match_parent"    android:layout_height="wrap_content"    app:layout_scrollFlags="scroll"    android:clipChildren="false"    android:clipToPadding="false">    <com.ce.myscrollimg.DisInterceptNestedScrollView     android:layout_width="match_parent"     android:layout_height="wrap_content"     android:clipChildren="false"     android:clipToPadding="false"     app:layout_collapseMode="parallax"     app:layout_collapseParallaxMultiplier="0.8">     <LinearLayout      android:layout_width="match_parent"      android:layout_height="wrap_content"      android:orientation="vertical">      <ImageView       android:id="@+id/iv_bg"       android:layout_width="match_parent"       android:layout_height="130dp"       android:src="@mipmap/ic_cover_1"       android:scaleType="centerCrop"/>     </LinearLayout>    </com.ce.myscrollimg.DisInterceptNestedScrollView>    <com.ce.myscrollimg.DisInterceptNestedScrollView     android:layout_width="match_parent"     android:layout_height="wrap_content"     android:tag="middle"     android:layout_marginTop="130dp">     <LinearLayout      android:layout_width="match_parent"      android:layout_height="wrap_content"      android:orientation="vertical">      <View       android:layout_width="match_parent"       android:layout_height="80dp"       android:background="#FFF003"/>      <View       android:layout_width="match_parent"       android:layout_height="80dp"       android:background="#FF3300"/>     </LinearLayout>    </com.ce.myscrollimg.DisInterceptNestedScrollView>    <androidx.appcompat.widget.Toolbar     android:layout_width="match_parent"     android:layout_height="wrap_content"     android:tag="toolbar"     app:layout_collapseMode="pin">    </androidx.appcompat.widget.Toolbar>   </com.google.android.material.appbar.CollapsingToolbarLayout>  </com.google.android.material.appbar.AppBarLayout>  <LinearLayout   android:layout_width="match_parent"   android:layout_height="wrap_content"   android:orientation="vertical"   app:layout_behavior="@string/appbar_scrolling_view_behavior">   <com.google.android.material.tabs.TabLayout    android:id="@+id/toolbar_tab"    android:layout_width="match_parent"    android:layout_height="40dp"    android:layout_gravity="center"    app:tabIndicatorColor="#FFC000"    app:tabIndicatorFullWidth="false"    app:tabIndicatorHeight="0dp"    app:tabMode="scrollable"    android:layout_marginTop="4dp"    android:layout_marginBottom="2dp"    app:tabSelectedTextColor="#FFC000"    app:tabTextColor="#FFFFFF"    app:tabMaxWidth="90dp"    app:tabPaddingEnd="-1dp" />   <com.ce.myscrollimg.NoScrollViewPager    android:id="@+id/vp_content"    android:layout_width="match_parent"    android:layout_height="match_parent" />  </LinearLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout></LinearLayout>

上java代碼

package com.ce.myscrollimg;import androidx.appcompat.app.AppCompatActivity;import androidx.fragment.app.Fragment;import androidx.viewpager.widget.ViewPager;import android.graphics.Typeface;import android.os.Bundle;import android.util.TypedValue;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.LinearLayout;import android.widget.TextView;import com.google.android.material.tabs.TabLayout;import java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity { private TabLayout toolbar_tab; private NoScrollViewPager vp_content; private ViewPagerAdapter vpAdapter; private List<Fragment> listFragment = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);  initView(); } //初始化view private void initView(){  //tab  toolbar_tab = findViewById(R.id.toolbar_tab);  //  vp_content = findViewById(R.id.vp_content);  vpAdapter = new ViewPagerAdapter(getSupportFragmentManager(),listFragment);  vp_content.setAdapter(vpAdapter);  vp_content.setOffscreenPageLimit(2);  toolbar_tab.setupWithViewPager(vp_content);  for(int i=0;i<12;i++){   listFragment.add(CeshiFragment.newInstance("第"+i+"頁"));  }  vpAdapter.notifyDataSetChanged();  for(int i=0;i<listFragment.size();i++){   TabLayout.Tab tab = toolbar_tab.getTabAt(i);   View customView = LayoutInflater.from(this).inflate(R.layout.tab_text, null, false);   TextView textView = customView.findViewById(R.id.tv_custom_tab);//   LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);//   layoutParams.weight = 0;//   textView.setLayoutParams(layoutParams);   if (i == 0) {    textView.setText("推薦");   } else {    textView.setText("第"+i+"頁");   }   if (i == 0) {    textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);    textView.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));    textView.setTextColor(getResources().getColor(R.color.color_FFFFC000));   } else {    textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);    textView.setTextColor(getResources().getColor(R.color._1E1E1E));   }   tab.setCustomView(customView);  }  toolbar_tab.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {   @Override   public void onTabSelected(TabLayout.Tab tab) {    View view = tab.getCustomView();    if (view != null) {     TextView textView = view.findViewById(R.id.tv_custom_tab);     textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);     textView.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));     textView.setTextColor(getResources().getColor(R.color.color_FFFFC000));    }    vp_content.setCurrentItem(tab.getPosition());   }   @Override   public void onTabUnselected(TabLayout.Tab tab) {    View view = tab.getCustomView();    if (view != null) {     TextView textView = view.findViewById(R.id.tv_custom_tab);     if (textView != null) {      textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);      textView.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL));      textView.setTextColor(getResources().getColor(R.color._1E1E1E));     }    }   }   @Override   public void onTabReselected(TabLayout.Tab tab) {   }  }); }}

重點在于設置AppBarLayout的Behavior這里自定義AppBarLayoutOverScrollViewBehavior,下面貼出代碼

package com.ce.myscrollimg;import android.animation.Animator;import android.animation.ValueAnimator;import android.content.Context;import android.util.AttributeSet;import android.view.View;import android.view.ViewGroup;import androidx.appcompat.widget.Toolbar;import androidx.coordinatorlayout.widget.CoordinatorLayout;import androidx.core.view.ViewCompat;import com.google.android.material.appbar.AppBarLayout;/** * Created by gjm on 2017/5/24. * 目前包括的事件: * 圖片放大回彈 * 個人信息布局的top和botoom跟隨圖片位移 * toolbar背景變色 */public class AppBarLayoutOverScrollViewBehavior extends AppBarLayout.Behavior { private static final String TAG = "overScroll"; private static final String TAG_TOOLBAR = "toolbar"; private static final String TAG_MIDDLE = "middle"; private static final float TARGET_HEIGHT = 1500; private View mTargetView; private int mParentHeight; private int mTargetViewHeight; private float mTotalDy; private float mLastScale; private int mLastBottom; private boolean isAnimate; private Toolbar mToolBar; private ViewGroup middleLayout;//個人信息布局 private int mMiddleHeight; private boolean isRecovering = false;//是否正在自動回彈中 private final float MAX_REFRESH_LIMIT = 0.3f;//達到這個下拉臨界值就開始刷新動畫 public AppBarLayoutOverScrollViewBehavior() { } public AppBarLayoutOverScrollViewBehavior(Context context, AttributeSet attrs) {  super(context, attrs); } @Override public boolean onLayoutChild(CoordinatorLayout parent, AppBarLayout abl, int layoutDirection) {  boolean handled = super.onLayoutChild(parent, abl, layoutDirection);  if (mToolBar == null) {   mToolBar = parent.findViewWithTag(TAG_TOOLBAR);  }  if (middleLayout == null) {   middleLayout = (ViewGroup) parent.findViewWithTag(TAG_MIDDLE);  }  // 需要在調(diào)用過super.onLayoutChild()方法之后獲取  if (mTargetView == null) {   mTargetView = parent.findViewById(R.id.iv_bg);   if (mTargetView != null) {    initial(abl);   }  }  abl.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {   @Override   public final void onOffsetChanged(AppBarLayout appBarLayout, int i) {    mToolBar.setAlpha(Float.valueOf(Math.abs(i)) / Float.valueOf(appBarLayout.getTotalScrollRange()));   }  });  return handled; } @Override public boolean onStartNestedScroll(CoordinatorLayout parent, AppBarLayout child, View directTargetChild, View target, int nestedScrollAxes, int x) {  isAnimate = true;  if (target instanceof DisInterceptNestedScrollView) return true;//這個布局就是middleLayout  return super.onStartNestedScroll(parent, child, directTargetChild, target, nestedScrollAxes,x); } @Override public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dx, int dy, int[] consumed, int x) {  if (!isRecovering) {   if (mTargetView != null && ((dy < 0 && child.getBottom() >= mParentHeight)     || (dy > 0 && child.getBottom() > mParentHeight))) {    scale(child, target, dy);    return;   }  }  super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed,x); } @Override public boolean onNestedPreFling(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, float velocityX, float velocityY) {  if (velocityY > 100) {//當y速度>100,就秒彈回   isAnimate = false;  }  return super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY); } @Override public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout abl, View target, int x) {  recovery(abl);  super.onStopNestedScroll(coordinatorLayout, abl, target,x); } private void initial(AppBarLayout abl) {  abl.setClipChildren(false);  mParentHeight = abl.getHeight();  mTargetViewHeight = mTargetView.getHeight();  mMiddleHeight = middleLayout.getHeight(); } private void scale(AppBarLayout abl, View target, int dy) {  mTotalDy += -dy;  mTotalDy = Math.min(mTotalDy, TARGET_HEIGHT);  mLastScale = Math.max(1f, 1f + mTotalDy / TARGET_HEIGHT);  ViewCompat.setScaleX(mTargetView, mLastScale);  ViewCompat.setScaleY(mTargetView, mLastScale);  mLastBottom = mParentHeight + (int) (mTargetViewHeight / 2 * (mLastScale - 1));  abl.setBottom(mLastBottom);  target.setScrollY(0);  middleLayout.setTop(mLastBottom - mMiddleHeight);  middleLayout.setBottom(mLastBottom);  if (onProgressChangeListener != null) {   float progress = Math.min((mLastScale - 1) / MAX_REFRESH_LIMIT, 1);//計算0~1的進度   onProgressChangeListener.onProgressChange(progress, false);  } } public interface onProgressChangeListener {  /**   * 范圍 0~1   *   * @param progress   * @param isRelease 是否是釋放狀態(tài)   */  void onProgressChange(float progress, boolean isRelease); } public void setOnProgressChangeListener(AppBarLayoutOverScrollViewBehavior.onProgressChangeListener onProgressChangeListener) {  this.onProgressChangeListener = onProgressChangeListener; } onProgressChangeListener onProgressChangeListener; private void recovery(final AppBarLayout abl) {  if (isRecovering) return;  if (mTotalDy > 0) {   isRecovering = true;   mTotalDy = 0;   if (isAnimate) {    ValueAnimator anim = ValueAnimator.ofFloat(mLastScale, 1f).setDuration(200);    anim.addUpdateListener(      new ValueAnimator.AnimatorUpdateListener() {       @Override       public void onAnimationUpdate(ValueAnimator animation) {        float value = (float) animation.getAnimatedValue();        ViewCompat.setScaleX(mTargetView, value);        ViewCompat.setScaleY(mTargetView, value);        abl.setBottom((int) (mLastBottom - (mLastBottom - mParentHeight) * animation.getAnimatedFraction()));        middleLayout.setTop((int) (mLastBottom -          (mLastBottom - mParentHeight) * animation.getAnimatedFraction() - mMiddleHeight));        if (onProgressChangeListener != null) {         float progress = Math.min((value - 1) / MAX_REFRESH_LIMIT, 1);//計算0~1的進度         onProgressChangeListener.onProgressChange(progress, true);        }       }      }    );    anim.addListener(new Animator.AnimatorListener() {     @Override     public void onAnimationStart(Animator animation) {     }     @Override     public void onAnimationEnd(Animator animation) {      isRecovering = false;     }     @Override     public void onAnimationCancel(Animator animation) {     }     @Override     public void onAnimationRepeat(Animator animation) {     }    });    anim.start();   } else {    ViewCompat.setScaleX(mTargetView, 1f);    ViewCompat.setScaleY(mTargetView, 1f);    abl.setBottom(mParentHeight);    middleLayout.setTop(mParentHeight - mMiddleHeight);//    middleLayout.setBottom(mParentHeight);    isRecovering = false;    if (onProgressChangeListener != null)     onProgressChangeListener.onProgressChange(0, true);   }  } }}

感謝你能夠認真閱讀完這篇文章,希望小編分享的“Android中如何使用CoordinatorLayout+AppBarLayout實現(xiàn)拉伸頂部圖片功能”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業(yè)資訊頻道,更多相關知識等著你來學習!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI