簡體   English   中英

如何使AppBarLayout背景透明化

[英]How to make AppBarLayout background transparent

我正在嘗試制作類似於Play商店中的搜索片段:

Google Play商店

我的AppBarLayout有一個CardView ,背景設置為透明:

<android.support.design.widget.CoordinatorLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/transparent"
        android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
        app:elevation="0dp">

        <!-- CardView -->

    </android.support.design.widget.AppBarLayout>

    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <!-- Main content -->

    </android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>

但正如您所看到的, CardView背后有一個堅實的背景,以便隱藏它背后的內容:

隱藏的內容

如何使AppBarLayout的背景透明,以便后面的內容可見?

同樣的問題發生在我身上,此時它與AppBarLayout的透明度AppBarLayout 但是當淡入時, AppBarLayout會將AppBarLayout的內容推NestedScrollView自身下方。

你可以解決這個問題

  1. 移動你的NestedScrollView起來,后面AppBarLayout
  2. 使用AppBar的大小向NestedScrollView添加一個空格元素

通過將此添加到onCreate()可以輕松實現步驟1

mNestedScroll.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        mNestedScroll.getViewTreeObserver().removeOnGlobalLayoutListener(this);

        final int appBarHeight = mAppBar.getHeight();
        mNestedScroll.setTranslationY(-appBarHeight);
        mNestedScroll.getLayoutParams().height = mNestedScroll.getHeight() + appBarHeight;
    }
});

對於第2步 ,你需要與appBar的高度間隔您添加一個空的觀點NestedScrollView 注意:我在我的方法中使用了RecyclerView而不是NestedScrollView ,所以我不得不將帶有appBarHeight的空ViewHolder添加到我的RecyclerView中。 所以這段代碼沒有經過測試,但它應該為你做的訣竅:

<View
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"/>

嘗試將CardView放入具有match_parent維度的FrameLayout中,以便CardView具有圍繞它的空間。 我不是百分之百地確信它會起作用,但值得嘗試。

我嘗試了很多代碼來給我或多或少的東西。 這是一個替代解決方案,但您需要將AppBarLayout更改為一個簡單的視圖...看看:

<android.support.design.widget.CoordinatorLayout 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:id="@+id/annonce.main.coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="RtlHardcoded">

<android.support.v7.widget.RecyclerView
    android:id="@+id/rv"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

<!-- here you put your search bar, can be any view !-->
<android.support.v7.widget.CardView
    android:id="@+id/searchbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:cardElevation="4dp"
    app:cardUseCompatPadding="true"
    app:layout_behavior="[package].RecyclerSearchBehavior">

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:hint="Pesquise aqui"
        android:minHeight="58dp"/>

</android.support.v7.widget.CardView>

注意:這是在CoordinatorLayout中。 創建一個行為,該行為是您使用的搜索欄的類型:

public class RecyclerSearchBehavior extends CoordinatorLayout.Behavior<CardView> {
//Initial height and location
private int mViewHeight;
private int[] mViewStartLocation;


public RecyclerSearchBehavior(Context context, AttributeSet attrs) {
}

@Override
public boolean layoutDependsOn(CoordinatorLayout parent, final CardView child, View dependency) {
    //the first function called. The initial variables settings.
    //getting height 
    mViewHeight = child.getHeight();
    //getting location on screen
    mViewStartLocation = new int[2];
    child.getLocationOnScreen(mViewStartLocation);
    //if the dependecy is your recycler
    if (dependency instanceof RecyclerView)
        //add scroll listener
        ((RecyclerView) dependency).addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
            }
            //here the magic happens
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                //animate function
                animate(child, dy);
            }
        });
    return dependency instanceof RecyclerView;
}

private void animate(CardView child, int dy) {
    //the initial position of your search bar is 0, because it is on top, so...
    if (child.getY() <= 0)
        //dy is an integer that shows you if user scrolls up or down
        if (dy >= 0) {
            //move to top is a negative value, so *-1
            //if that is < than height, scrools up
            if ((child.getY() * -1) <= (mViewHeight))
                child.setTranslationY(child.getY() - dy * 0.1f);
        } else {
            //if the position of search bar is < than zero, scrolls down
            if (child.getY() < 0)
                child.setTranslationY(child.getY() - dy * 0.1f);
            //else, put the view on 0y
            else child.setY(0);
        }
    //else, put the view on 0y again. this function is called after any user                    
    //touches... so everything happens fast and with numbers different than 
    //1 
    else child.setY(0);
}

}

並做了。 您的“搜索欄”就在這里。

這里唯一的問題是,你需要在Recycler上的第一個項目中添加填充,或者在第一個項目中添加透明視圖。

另一種選擇是向NestedScrollView (或任何使用appbar_scrolling_view_behavior視圖)添加負上邊距,並為其直接子項添加相同的正上邊距(或填充):

<androidx.core.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    android:layout_marginTop="-100dp" >

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingTop="100dp" >

        ...

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.core.widget.NestedScrollView>

<com.google.android.material.appbar.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@null" >

    <com.google.android.material.appbar.CollapsingToolbarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_scrollFlags="scroll|exitUntilCollapsed" >

        ...

    </com.google.android.material.appbar.CollapsingToolbarLayout>

</com.google.android.material.appbar.AppBarLayout>

請注意,為了使這種方法起作用, AppBarLayout應該放在布局文件中的NestedScrollView下面。 如果NestedScrollView淡化邊緣產生視覺偽像,請將android:overScrollMode="never"到其參數中。 因為它在使用elevation時也要小心,當在錯誤的位置使用時(比如,當應用於整個AppBarLayout ),也可能產生視覺偽像。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM