2016-07-25 428 views
5

我试图做一个类似于在Play商店中搜索片段:如何使AppBarLayout背景透明

Google Play Store

AppBarLayoutCardView在里面,背景设置为透明:

<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,以便它后面的内容背后却隐藏着一个坚实的背景:

Hidden content

我怎样才能让AppBarLayout的背景透明,这样后面的内容是可见的?

+0

你想NestedScrollView滚动AppbarLayout下? – jayeshsolanki93

+0

我希望NestedScrollView的内容紧密地拥抱搜索区域,但现在在搜索区域上方没有内容可见,而在它下面有一条灰色的线将搜索区域与内容分隔开。 编辑:是的,这就是我想要的。 – joharei

+0

尝试在AppbarLayout和NestedScrollView中添加'android:fitsSystemWindows =“true”' – jayeshsolanki93

回答

2

同样的问题发生在我身上,此时它与AppBarLayout的透明度无关。但AppBarLayout推动之下本身的NestedScrollView衰落时的内容。

您可以通过

  1. 移动你的NestedScrollView解决这件事背后的AppBarLayout
  2. 加空格元素,你NestedScrollView与所述AppBar的大小

步骤1可以通过添加这可以容易地实现的onCreate()

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,所以我不得不向我的RecyclerView添加一个带有appBarHeight的空ViewHolder。所以这个片段没有经过测试,但它应该为你做的伎俩:

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

这很好地解决了问题。谢谢!然而,你描述的另一个问题,'snap'行为将'NestedScrollView'内容压下,仍然存在。您是否可以使用此解决方法解决此问题? – joharei

+0

@joharei对不起,但我不太明白你的问题。我描述的问题是,所有的内容都将被绘制在AppBarLayout下方,使得AppBarLayout专属于它占据的空间。因此,可滚动内容显示在AppBar下方。 我所描述的是克服这个缺点的两个步骤。第一步将移动AppBar下面的内容并解决整个问题。第二步只是将可滚动内容恢复正常(并且可能不需要您的实现) –

+0

我可能会误解,请忽略我以前的评论。不过,我的解决方案确实存在问题。如果'NestedScrollView'中的内容比屏幕高,那么当活动加载时,它会出现在“AppBarLayout”后面。当我开始滚动时,一切都表现良好。 – joharei

0

尝试将CardView放入一个尺寸为match_parent的FrameLayout中,以便CardView在其周围有空间。我并不是100%相信它会起作用,但值得尝试。

+0

我其实已经有一个FrameLayout来调整一些填充。不幸的是无法工作。 – joharei

0

我尝试了很多代码,或多或少的给我找你想要的东西。这是一个替代的解决方案,但你需要改变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上的第一个项目添加填充,或者将第一个项目作为透明视图添加填充。