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 이나 대신 사용하시면 될 것입니다.
답글삭제좋은글 감사합니다
답글삭제읽어주셔서 감사합니다
삭제도움이 많이 되었습니다 감사드립니다.
답글삭제네, 저도 읽어주셔서 감사~
삭제