CoordinatorLayout 에서 toolbar 를 scroll 할 때 좀 더 정교하게 다루는데 사용되는 것이 CollapsingToolbarLayout 인데, 자세한 사항은 ref.1 이나 ref. 2 를 보자.
여하튼 여기서는 CollapsingToolbarLayout 를 이용해서 scroll 해서 화면이 위로 올라갔을 때 최상단에 있던 이미지가 toolbar 에 alpha 가 적용된 상태로 보여지게 할 것이다.
Toolbar 에 alpha 가 적용된 이미지 사용방법
Android template 으로 제공하는 ScrollingActivity 를 기본으로 설명하려 한다. 소스의 변경사항은 아래와 같다.대략적인 사용법은 간단하다. 아래 2가지면 된다.
- xml 변경 : xml 에 기본적으로 app:contentScrim="?attr/colorPrimary" 설정이 되어있는데 이것을 없애자. 그래야 toolbar 의 background 로 image view 의 그림이 설정된다.
- AppBarLayout.OnOffsetChangedListener 추가 : change-listener 를 appbar 에 추가해줘야 한다. 이녀석을 추가해서 toolbar 가 collapsed 되었을 때 alpha 값을 주게 할 수 있다.
xml 변경사항
xml 변경사항의 자세한 부분은 위의 "변경사항 diff" 를 확인하자.<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
...>
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
...>
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:id="@+id/backdrop"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:fitsSystemWindows="true"
app:layout_collapseMode="parallax" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
... />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_scrolling" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
... />
</android.support.design.widget.CoordinatorLayout>
OnOffsetChangedListener
OnOffsetChangedListener 에 대한 source code 는 아래 경로를 참고했다.이녀석을 통해서 toolbar 에 collapsed 됐을 때 toolbar 의 image 를 투명하게 할 수 있다.
public class ScrollingActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
...
loadBackdrop();
}
private void loadBackdrop() {
final CollapsingToolbarLayout collapsingToolbar =
(CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
collapsingToolbar.setTitle("My New Title");
final int myDrawable = R.drawable.cheese_1;
final ImageView iv = (ImageView)findViewById(R.id.backdrop);
if (iv != null) {
iv.setImageResource(myDrawable);
}
AppBarLayout.OnOffsetChangedListener listener = new AppBarLayout.OnOffsetChangedListener() {
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
if(collapsingToolbar.getHeight() + verticalOffset < 2 * ViewCompat.getMinimumHeight(collapsingToolbar)) {
// collapsed
iv.animate().alpha(0.3f).setDuration(600);
} else {
// extended
iv.animate().alpha(1f).setDuration(600); // 1.0f means opaque
}
}
};
final AppBarLayout appbar = (AppBarLayout) findViewById(R.id.appbar);
appbar.addOnOffsetChangedListener(listener);
}
...
}
toolbar(appbar) 의 그림자 없애기
app:elevation="0dp" 로 없앨 수 있다.
<android.support.design.widget.CoordinatorLayout
...>
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
...
app:elevation="0dp">
collapsed toolbar 의 배경 지정하기
추가적으로 collapsed toolbar layout 에 배경(색, 이미지)에 대한 이야기를 해보자.기본적으로 CollapsingToolbarLayout 에 app:contentScrim 를 정해주지 않으면, ImageView 의 그림이 그대로 들어가 있게 된다. 이 배경은 contentScrim 으로 지정해 줄 수 있다.
primary color 로
이 상황에서 collaped 됐을 때 primaryColor 로 바꾸고 싶다면 아래처럼 설정해주면 된다.- app:contentScrim="?attr/colorPrimary"
blurred image 로 배경이미지 넣기
이 방법은 alpha 로 넣는 방법을 발견하기 전에 하던 방법인데, imageView 에서 사용된 image 를 가져다가 blurred image 로 만들어서 그녀석을 collapsed toolbar 의 scrim 으로 설정해 줬다.Blurred image 는 code 로 넣어야 한다. 일단 view 가 호출될 때
onCreate() 에 ImageView 에 사용되는 image 의 drawable 의 blurred 해서
이 녀석을 CollapsingToolbarLayout 의 contentScrim 으로 지정해 주면 된다.
final Drawable d = new BitmapDrawable(getResources(), CreateBlurredImage(cheeseDrawable, 20)); collapsingToolbar.setContentScrim(d);
CreateBlurredImage 는 ref. 1 의 소스를 참고했다.
private Bitmap CreateBlurredImage (int imageId, int radius)
{
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
return BitmapFactory.decodeResource(getResources(), imageId);
}
// Load a clean bitmap and work from that.
Bitmap originalBitmap = BitmapFactory.decodeResource(getResources(), imageId);
// Create another bitmap that will hold the results of the filter.
Bitmap blurredBitmap;
blurredBitmap = Bitmap.createBitmap(originalBitmap);
// Create the Renderscript instance that will do the work.
RenderScript rs = RenderScript.create(this);
// Allocate memory for Renderscript to work with
Allocation input = Allocation.createFromBitmap(
rs, originalBitmap, Allocation.MipmapControl.MIPMAP_FULL, Allocation.USAGE_SCRIPT);
Allocation output = Allocation.createTyped(rs, input.getType());
// Load up an instance of the specific script that we want to use.
ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
script.setInput(input);
// Set the blur radius
script.setRadius(radius);
// Start the ScriptIntrinisicBlur
script.forEach(output);
// Copy the output to the blurred bitmap
output.copyTo(blurredBitmap);
return blurredBitmap;
}
Toolbar(Appbar) 아래에 view 를 고정시킬 경우
이 경우는 scroll 이 되는 view 를 appbar 밖으로 놓고, scroll 되는 녀석이랑 같은 level 로 놓으면 된다.(아래 코드 참조)- CollapsingToolbarLayout with TabLayout : tab layout 을 app bar 아래에 보이게 하는 코드
<android.support.design.widget.CoordinatorLayout ...> <android.support.design.widget.AppBarLayout ...> <android.support.design.widget.CollapsingToolbarLayout ...> ... <android.support.v7.widget.Toolbar ... /> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> <LinearLayout ... android:orientation="vertical"> <TextView ... android:textIsSelectable="true" /> <android.support.v4.widget.NestedScrollView android:id="@+id/nsv_activity" android:layout_width="match_parent" android:layout_height="match_parent" > ... </android.support.v4.widget.NestedScrollView> </LinearLayout> <android.support.design.widget.FloatingActionButton ..."/> </android.support.design.widget.CoordinatorLayout>

궁금한게 있는데요
답글삭제final Drawable d = new BitmapDrawable(getResources(), CreateBlurredImage(cheeseDrawable, 20));
collapsingToolbar.setContentScrim(d); 여기서 cheeseDrawable 이 먼가요?
그냥 drawable 를 변수로 받은 것입니다. 소스를 붙여넣다보니, 그리됐네요 ^^;; 그냥 아무 drawable 이나 대신 사용하시면 될 것입니다.
답글삭제좋은글 감사합니다
답글삭제읽어주셔서 감사합니다
삭제도움이 많이 되었습니다 감사드립니다.
답글삭제네, 저도 읽어주셔서 감사~
삭제