CollapsingToolbarLayout作用是提供了一個可以折疊的Toolbar,它繼承至FrameLayout,給它設置layout_scrollFlags就可以實現(xiàn)折疊效果!
- 效果展示:

20170209104448181.gif
- 引入相對使用的庫
compile 'com.android.support:appcompat-v7:23.3.0'
compile 'com.android.support:design:23.3.0'
compile 'com.android.support:support-v4:23.3.0'
compile 'com.jakewharton:butterknife:7.0.1'
//沉浸狀態(tài)欄
compile 'com.jaeger.statusbaruitl:library:1.1.1'
//glide圖片加載
compile 'jp.wasabeef:glide-transformations:2.0.1'
- 首先查看布局:
<?xml version="1.0" encoding="utf-8"?>
<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/coordinator_Layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="cn.hnshangyu.coordinatorlayout.MainActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsingToolbarLayout"
android:layout_width="match_parent"
android:layout_height="300dp"
app:collapsedTitleTextAppearance="@style/ToolBarTitleText"
app:contentScrim="#46a8ba"
app:expandedTitleMarginEnd="48dp"
app:expandedTitleMarginStart="48dp"
app:expandedTitleTextAppearance="@style/transparentText"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<!--設置layout_scrollFlags保證CollapsingToolbarLayout能滾動-->
<!--app:layout_scrollFlags="scroll|exitUntilCollapsed"-->
<LinearLayout
android:id="@+id/head_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_collapseMode="pin"
app:layout_collapseParallaxMultiplier="0.7">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:padding="20dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="黃曉果"
android:textColor="#ffffff"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:lineSpacingMultiplier="1.3"
android:text="我很喜歡你,像你媽打你,沒有道理;\n像放出的屁,身不由己。"
android:textColor="#ffffff"
android:textSize="13sp"
android:textStyle="bold" />
</LinearLayout>
<ImageView
android:id="@+id/head_iv"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:scaleType="centerCrop" />
</RelativeLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="40dp"
android:ellipsize="end"
android:lineSpacingMultiplier="1.3"
android:maxLines="2"
android:text="萌逼的臉是來親的,帥逼的臉是用來看的,逗逼的臉是用來笑的,傻逼的臉是用來哭的,偏偏就你的臉是用來踢的。"
android:textColor="#ffffff"
android:textSize="12sp" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:padding="20dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="40dp"
android:ellipsize="end"
android:lineSpacingMultiplier="1.3"
android:maxLines="2"
android:text="今天的你對我愛搭不理,\n明天的我還來找你。"
android:textColor="#ffffff"
android:textSize="12sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="@drawable/setting_bg"
android:paddingBottom="3dp"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:paddingTop="3dp"
android:text="設置"
android:textColor="#ffffff"
android:textSize="12sp" />
</RelativeLayout>
</LinearLayout>
<!--Toolbar放在下面不然會被擋住-->
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
</android.support.design.widget.CollapsingToolbarLayout>
<android.support.design.widget.TabLayout
android:id="@+id/toolbar_tab"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_gravity="bottom"
android:background="#ffffff"
android:fillViewport="false"
app:layout_scrollFlags="scroll"
app:tabIndicatorColor="#0835f8"
app:tabIndicatorHeight="2.0dp"
app:tabSelectedTextColor="#0835f8"
app:tabTextColor="#151515">
<!--指示器顏色-->
<!-- app:tabIndicatorColor="#0835f8"-->
<!--tab條目中字體顏色-->
<!--app:tabSelectedTextColor="#0835f8"-->
<android.support.design.widget.TabItem
android:layout_width="match_parent"
android:layout_height="match_parent"
android:icon="@drawable/tab_selector" />
<!--布局選擇器-->
<!--android:icon="@drawable/tab_selector"-->
<android.support.design.widget.TabItem
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="頭條" />
<android.support.design.widget.TabItem
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="社交" />
<android.support.design.widget.TabItem
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="直播" />
<android.support.design.widget.TabItem
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="約嗎" />
</android.support.design.widget.TabLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:id="@+id/nsv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:scrollbars="none"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.v4.view.ViewPager
android:id="@+id/main_vp_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.v4.widget.NestedScrollView>
<!--在CoordinatorLayout中只要是能滑動控件的都需要設置layout_behavior-->
<!--app:layout_behavior="@string/appbar_scrolling_view_behavior"-->
</android.support.design.widget.CoordinatorLayout>
內部特殊的屬性都有相對注釋:
我們在CollapsingToolbarLayout中設置了一個LinearLayout和一個Toolbar。
并把這個CollapsingToolbarLayout放到AppBarLayout中作為一個整體。
1、在CollapsingToolbarLayout中:
我們設置了layout_scrollFlags:關于它的值我這里再說一下:
scroll - 想滾動就必須設置這個。
enterAlways - 實現(xiàn)quick return效果, 當向下移動時,立即顯示View(比如Toolbar)。
exitUntilCollapsed - 向上滾動時收縮View,但可以固定Toolbar一直在上面。
enterAlwaysCollapsed - 當你的View已經(jīng)設置minHeight屬性又使用此標志時,
你的View只能以最小高度進入,只有當滾動視圖到達頂部時才擴大到完整高度。
其中還設置了一些屬性,簡要說明一下:
contentScrim - 設置當完全CollapsingToolbarLayout折疊(收縮)后的背景顏色。
expandedTitleMarginStart - 設置擴張時候(還沒有收縮時)title向左填充的距離。
layout_collapseMode (折疊模式) - 有兩個值:
pin - 設置為這個模式時,當CollapsingToolbarLayout完全收縮后,Toolbar還可以保留在屏幕上。
parallax - 設置為這個模式時,在內容滾動時,CollapsingToolbarLayout中的View(比如ImageView)也可以同時滾動,
實現(xiàn)視差滾動效果,通常和layout_collapseParallaxMultiplier(設置視差因子)搭配使用。
layout_collapseParallaxMultiplier(視差因子) - 設置視差滾動因子,值為:0~1。
- 這里使用到了部分樣式:
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="transparentText" parent="TextAppearance.AppCompat.Small">
<item name="android:textColor">#00000000</item>
</style>
<style name="ToolBarTitleText" parent="TextAppearance.AppCompat.Medium">
<item name="android:textColor">#ffffffff</item>
<item name="android:textSize">16sp</item>
<item name="android:textStyle">bold</item>
</style>
- 然后就是MainActivity中的代碼設置了:
package cn.hnshangyu.coordinatorlayout;
import android.annotation.TargetApi;
import android.os.Build;
import android.os.Bundle;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.CollapsingToolbarLayout;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.NestedScrollView;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.SimpleTarget;
import com.jaeger.library.StatusBarUtil;
import butterknife.Bind;
import butterknife.ButterKnife;
import cn.hnshangyu.coordinatorlayout.adapter.ViewPagerAdapter;
import jp.wasabeef.glide.transformations.BlurTransformation;
import jp.wasabeef.glide.transformations.RoundedCornersTransformation;
public class MainActivity extends AppCompatActivity {
/**
* ScrollView上半部分
*/
@Bind(R.id.toolbar)
Toolbar toolbar;
/**
* 頭像
*/
@Bind(R.id.head_iv)
ImageView headIv;
/**
* CollapsingToolbarLayout內部顯示內容部分
*/
@Bind(R.id.head_layout)
LinearLayout headLayout;
/**
* tab分類條目
*/
@Bind(R.id.toolbar_tab)
TabLayout toolbarTab;
@Bind(R.id.app_bar_layout)
AppBarLayout appBarLayout;
/**
* 折疊部分
*/
@Bind(R.id.collapsingToolbarLayout)
CollapsingToolbarLayout collapsingToolbarLayout;
/**
* ViewPager
*/
@Bind(R.id.main_vp_container)
ViewPager mViewPager;
/**
* ScrollView
*/
@Bind(R.id.nsv)
NestedScrollView nsv;
/**
* 整個布局
*/
@Bind(R.id.coordinator_Layout)
CoordinatorLayout coordinatorLayout;
private ViewPagerAdapter myPagerAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
//用toolBar替換ActionBar
setToolBarReplaceActionBar();
//把title設置到CollapsingToolbarLayout上
setTitleToCollapsingToolbarLayout();
// 給viewpager設置適配器
setViewPagerAdapter();
//tablayout和viewpager建立聯(lián)系
setTabBindViewPager();
//設置毛玻璃效果和沉浸狀態(tài)欄
loadBlurAndSetStatusBar();
//設置頭像
Glide.with(this).load(R.mipmap.bg).bitmapTransform(new RoundedCornersTransformation(this,
90, 0)).into(headIv);
}
/**
* 用toolBar替換ActionBar
*/
private void setToolBarReplaceActionBar() {
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity.this, "返回", Toast.LENGTH_LONG).show();
// onBackPressed();//結束程序
}
});
}
/**
* 使用CollapsingToolbarLayout必須把title設置到CollapsingToolbarLayout上,
* 設置到Toolbar上則不會顯示
*/
private void setTitleToCollapsingToolbarLayout() {
appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
if (verticalOffset <= -headLayout.getHeight() / 2) {
collapsingToolbarLayout.setTitle("黃曉果");
//使用下面兩個CollapsingToolbarLayout的方法設置展開透明->折疊時你想要的顏色
collapsingToolbarLayout.setExpandedTitleColor(getResources().getColor(android.R.color.transparent));
collapsingToolbarLayout.setCollapsedTitleTextColor(getResources().getColor(R.color.colorAccent));
} else {
collapsingToolbarLayout.setTitle("");
}
}
});
}
/**
* 給viewpager設置適配器
*/
private void setViewPagerAdapter() {
myPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager(), this);
mViewPager.setAdapter(myPagerAdapter);
}
/**
* tablayout和viewpager建立聯(lián)系
*/
private void setTabBindViewPager() {
//tablayout和viewpager建立聯(lián)系方式一:tab與viewpager之間的相互綁定
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener
(toolbarTab));
toolbarTab.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener
(mViewPager));
//tablayout和viewpager建立聯(lián)系方式二: 使用此方法Tablayout中的TabItem設置icon無效
// (android:icon="@drawable/tab_selector" )只能使用 android:text="分享"
// toolbarTab.setupWithViewPager(mViewPager);
}
/**
* 設置毛玻璃效果和沉浸狀態(tài)欄
*/
private void loadBlurAndSetStatusBar() {
//目的是讓狀態(tài)欄半透明
// StatusBarUtil.setTranslucent(MainActivity.this, StatusBarUtil.DEFAULT_STATUS_BAR_ALPHA);
//目的是讓狀態(tài)欄全透明
StatusBarUtil.setTransparent(MainActivity.this);
Glide.with(this).load(R.mipmap.bg).bitmapTransform(new BlurTransformation(this, 100))
.into(new SimpleTarget<GlideDrawable>() {
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
public void onResourceReady(GlideDrawable resource, GlideAnimation<? super
GlideDrawable> glideAnimation) {
headLayout.setBackground(resource);
coordinatorLayout.setBackground(resource);
}
});
Glide.with(this).load(R.mipmap.bg).bitmapTransform(new BlurTransformation(this, 100))
.into(new SimpleTarget<GlideDrawable>() {
@Override
public void onResourceReady(GlideDrawable resource, GlideAnimation<? super
GlideDrawable> glideAnimation) {
collapsingToolbarLayout.setContentScrim(resource);
}
});
}
//在ActionBar設置條目
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
String msg = "";
switch (item.getItemId()) {
case R.id.webview:
msg += "博客跳轉";
break;
case R.id.weibo:
msg += "微博跳轉";
break;
case R.id.action_settings:
msg += "設置";
break;
}
if (!msg.equals("")) {
Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
}
return super.onOptionsItemSelected(item);
}
}
代碼內部有詳細注釋
【注】:使用CollapsingToolbarLayout時必須把title設置到CollapsingToolbarLayout上,設置到Toolbar上不會顯示。
即:
mCollapsingToolbarLayout.setTitle(" ");
該變title的字體顏色:
擴張時候的title顏色:mCollapsingToolbarLayout.setExpandedTitleColor();
收縮后在Toolbar上顯示時的title的顏色:mCollapsingToolbarLayout.setCollapsedTitleTextColor();
這個顏色的過度變化其實CollapsingToolbarLayout已經(jīng)幫我們做好,它會自動的過度
- ViewPagerAdapter:
package cn.hnshangyu.coordinatorlayout.adapter;
import android.content.Context;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import cn.hnshangyu.coordinatorlayout.fragment.PageFragment;
public class ViewPagerAdapter extends FragmentPagerAdapter {
final int PAGE_COUNT = 5;
private String tabTitles[] = new String[]{"", "頭條", "社交", "直播", "約嗎"};
private Context context;
public ViewPagerAdapter(FragmentManager fm, Context context) {
super(fm);
this.context = context;
}
@Override
public Fragment getItem(int position) {
return PageFragment.newInstance(position + 1);
}
@Override
public int getCount() {
return PAGE_COUNT;
}
@Override
public CharSequence getPageTitle(int position) {
return tabTitles[position];
}
}
- PageFragment:
package cn.hnshangyu.coordinatorlayout.fragment;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;
import butterknife.Bind;
import butterknife.ButterKnife;
import cn.hnshangyu.coordinatorlayout.R;
import cn.hnshangyu.coordinatorlayout.adapter.MyAdapter;
public class PageFragment extends Fragment {
public static final String ARG_PAGE = "PAGE_NUM";
@Bind(R.id.recyclerView)
RecyclerView recyclerView;
private int mPage;
public static PageFragment newInstance(int page) {
Bundle args = new Bundle();
args.putInt(ARG_PAGE, page);
PageFragment pageFragment = new PageFragment();
pageFragment.setArguments(args);
return pageFragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPage = getArguments().getInt(ARG_PAGE);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_page, null);
ButterKnife.bind(this, view);
// 創(chuàng)建一個線性布局管理器
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
// 設置布局管理器
recyclerView.setLayoutManager(layoutManager);
List<String> list = new ArrayList<String>();
for (int i = 0; i < 100; i++) {
list.add("黃曉果" + i);
}
recyclerView.setAdapter(new MyAdapter(list));
return view;
}
@Override
public void onDestroyView() {
super.onDestroyView();
ButterKnife.unbind(this);
}
}
- MyAdapter:
package cn.hnshangyu.coordinatorlayout.adapter;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.List;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
// 數(shù)據(jù)集
private List<String> mDataset;
public MyAdapter(List<String> dataset) {
super();
mDataset = dataset;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
// 創(chuàng)建一個View,簡單起見直接使用系統(tǒng)提供的布局,就是一個TextView
View view = View.inflate(viewGroup.getContext(), android.R.layout.simple_list_item_1, null);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int i) {
// 綁定數(shù)據(jù)到ViewHolder上
holder.mTextView.setText(mDataset.get(i));
}
@Override
public int getItemCount() {
return mDataset.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
public TextView mTextView;
public ViewHolder(View itemView) {
super(itemView);
mTextView = (TextView) itemView;
}
}
}
- menu_main:
<?xml version="1.0" encoding="utf-8"?>
<menu 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"
tools:context=".MainActivity">
<item
android:id="@+id/webview"
android:icon="@mipmap/icon_blog"
android:orderInCategory="80"
android:title="web"
app:showAsAction="ifRoom" />
<item
android:id="@+id/weibo"
android:icon="@mipmap/icon_weibo"
android:orderInCategory="90"
android:title="weibo"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:title="設置"
app:showAsAction="never" />
</menu>
-
問題一:
異常信息:
Caused by: java.lang.IllegalStateException: This Activity already has an action bar supplied by the window decor. Do not request Window.FEATURE_SUPPORT_ACTION_BAR and set windowActionBar to false in your theme to use a Toolbar instead.
問題原因:
當在activity中調用了setSupportActionBar(toolbar);

20170209111040427.png
同時,AndroidManifest.xml 對應的Activity標簽的android:theme為:
android:theme="@style/AppTheme" >

20170209111137016.png
且,style資源文件中的parent為
parent="Theme.AppCompat.Light.DarkActionBar

20170209111203412.png
就會報這個異常。
問題分析:
Using Theme.AppCompat.Light tells Android that you want the framework to provide an ActionBar for you. However, you are creating your own ActionBar (a Toolbar), so you are giving the framework mixed signals as to where you want the ActionBar to come from.
解決方法:
1、在style配置文件中加上
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
或者,將parent改為
parent="Theme.AppCompat.Light.NoActionBar"
2、在AndroidManifest.xml 對應的Activity標簽的android:theme引用該style中的修改的主題
- 問題二:
問題:
當成功運行程序后如果在6.0及以上的機子上運行會出現(xiàn)頂部狀態(tài)欄顯示系統(tǒng)顏色,這里是 coordinatorLayout.setBackground(resource);這行代碼無效的情況
解決方式:
將編譯版本,修改到23且 compile 'com.jaeger.statusbaruitl:library:1.1.1'版本為1.1.1,如果設置為現(xiàn)在最高版本1.3.5會出現(xiàn),編譯不通過!
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "cn.hnshangyu.coordinatorlayout"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0"
renderscriptTargetApi 19
renderscriptSupportModeEnabled true
}
Demo下載地址:http://download.csdn.net/download/huangxiaoguo1/9750621
好了,到這里就結束了,歡迎各位指教.......