AppBarLayout CollapsingToolbarLayout 的进一步使用
2016-10-28 18:37
459 查看
最近有个项目,虽然暂时停了,但是有效果还是想做一下;一方面是自己好奇,另一方面又怕领导突然一拍脑门,又重新做起来。正好利用到之前说过的AppBarLaout,CollapsingToolbarLayout,所以趁着之前的热乎劲一块搞出来就完了。关于这两个控件的使用请看一下AppBarLayout 介绍和简单实用和 CollapsingToolbarLayout 介绍和简单使用
首先看一下要实现的大概效果:
首先我们分析一下这个效果,应该使用什么控件。这里有折叠效果,肯定会有CollapsingToolbarLayout;而且ToolBar 跟 AppBarLayout 也肯定少不了,要不然使用CollaspingToolbarLayout 就如同鸡肋了。下面的滑动标签使用的是TabLayout,最下面的内容使用的是ViewPager+Fragment。
好。分析完了,布局基本就出来了:
尤其需要我们注意一下的是,我们的TabLayout没有被折叠起来,只是随着被滑动到顶部,所以,我们把它放到了CollapsingToolbarLayout的下面。
我们可以看到我们的布局顶到了状态栏,这是4.4之后才可以用的设置,需要我们注意一下。设置的属性为
然后我们去看一下
接下来我们看一下代码:
这里需要强调一下,Fragment里的列表必须使用RecyclerView,而不能使用ListView,否者列表不能滑动,具体原因有时间我们在探讨。
还有我们的 NestedScrollView 调用了一个setFillViewport这个方法,这个方法会将NestedScrollView里填充内容的高拉伸,用来填充整个Viewport。如果不设置,那我们的Veiwpager则不会显示。其它的代码没有什么难度这里就不在说明了。
现在我们运行一下这些代码,会看到如下效果:
我们可以看到,顶部的Toolbar的顶到了状态栏,这样不太好,我们在Toolbar上给它设置一个
我们在布局引用一下就OK了。
然后我们再看一下效果:
上图是在API 22上的效果,下面的是在API 19 上的效果:
可能大家以为到这里就结束了,当然不会的。有没有人看到标题栏里的
首先我们需要修改Toolbar里文字的透明度,所以我们需要修改一下布局,在Toolbar里放一下TextView:
相较于之前的布局我们只是在Toolbar里添加了一个TextView。不是特别的麻烦。
接下来我们需要去代码动态设置标题文字的透明度,我们知道当我们上滑时的折叠效果是通过CollapsingToolbarLayout 实现的。那我们怎么监听它的折叠呢?我去看了看它的源码,发现它还是使用的AppBarLayout 的
首先看它如何绑定的监听:
其它暂时不再深究了,既然我们知道了它也是使用的AppBarLayout的OffsetChangedListener,那我们也使用它。首先看看这个监听:
我们看一下这个回调方法理由有一个
需要注意的是,在未滑动时verticalOffset为0,在计算时一定要注意。
然后我们看一下效果:
现在基本效果实现了,可能还有一些瑕疵,希望大家给多提建议。
最后源码奉上!!!
首先看一下要实现的大概效果:
首先我们分析一下这个效果,应该使用什么控件。这里有折叠效果,肯定会有CollapsingToolbarLayout;而且ToolBar 跟 AppBarLayout 也肯定少不了,要不然使用CollaspingToolbarLayout 就如同鸡肋了。下面的滑动标签使用的是TabLayout,最下面的内容使用的是ViewPager+Fragment。
好。分析完了,布局基本就出来了:
<?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" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.design.widget.AppBarLayout android:id="@+id/app_bar" android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.design.widget.CollapsingToolbarLayout android:id="@+id/toolbar_layout" android:layout_width="match_parent" android:layout_height="match_parent" app:contentScrim="@color/colorAccent" app:layout_scrollFlags="scroll|exitUntilCollapsed" > <ImageView android:id="@+id/imageView" android:layout_width="match_parent" android:layout_height="260dp" android:background="@drawable/header_bar"/> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:layout_collapseMode="pin" app:navigationIcon="@mipmap/ic_launcher" app:title="标题"/> </android.support.design.widget.CollapsingToolbarLayout> <android.support.design.widget.TabLayout android:id="@+id/tabs" android:layout_width="match_parent" android:layout_height="50dp" android:background="@android:color/white"/> </android.support.design.widget.AppBarLayout> <android.support.v4.widget.NestedScrollView android:id="@+id/nestedScrollView" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="match_parent"/> </android.support.v4.widget.NestedScrollView> </android.support.design.widget.CoordinatorLayout>
尤其需要我们注意一下的是,我们的TabLayout没有被折叠起来,只是随着被滑动到顶部,所以,我们把它放到了CollapsingToolbarLayout的下面。
我们可以看到我们的布局顶到了状态栏,这是4.4之后才可以用的设置,需要我们注意一下。设置的属性为
android:fitsSystemWindows,设置为true时,系统会为顶部的状态栏留出空间;当设置为false时,我们的布局就会占顶到顶部状态栏。还有我们需要设置一下
android:windowTranslucentStatus",这个设置在4.4和5.x之后有一些不同;4.4的设置之后状态栏是渐变的,而5.x之后就是半透明的。但是这个属性是在Android API19 之后出来的,所以我们需要在另创建两个文件夹
vaules-19,
vaules-21,里面创建一个style;因为我创建的style使用
values下的一些东西,所以我们先看一下values下的style文件:
<resources> <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> </style> <style name="AppTheme.NoActionBar"> <item name="android:windowActionBar">false</item> <item name="android:windowNoTitle">true</item> </style> </resources>
然后我们去看一下
vaules-19,
vaules-21下的style文件,它们两个是一样的:
<resources> <style name="AppTheme.NoActionBar"> <item name="android:fitsSystemWindows">false</item> <item name="android:windowTranslucentStatus">true</item> </style> </resources>
接下来我们看一下代码:
public class MainActivity extends AppCompatActivity { private NestedScrollView mNestedScrollView; private TabLayout mTabLayout; private ViewPager mViewPager; private String[] mTitles = {"西游记", "西游记", "西游记"}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mViewPager = (ViewPager) findViewById(R.id.viewPager); mTabLayout = (TabLayout) findViewById(R.id.tabs); mNestedScrollView = (NestedScrollView) findViewById(R.id.nestedScrollView); //设置 NestedScrollView 的内容是否拉伸填充整个视图, //这个设置是必须的,否者我们在里面设置的ViewPager会不可见 mNestedScrollView.setFillViewport(true); mTabLayout.setupWithViewPager(mViewPager); MyAdapter adapter = new MyAdapter(getSupportFragmentManager()); mViewPager.setAdapter(adapter); } private class MyAdapter extends FragmentPagerAdapter { public MyAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { return new MyFragment(); } @Override public int getCount() { return 3; } @Override public CharSequence getPageTitle(int position) { return mTitles[position]; } } public static class MyFragment extends Fragment { @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { String string = getString(R.string.text); List<String> strings = new ArrayList<>(); for (int i = 0; i < 3; i++) { strings.add(string); } RecyclerView recyclerView = new RecyclerView(getActivity()); recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false)); recyclerView.setAdapter(new MyListAdapter(strings)); return recyclerView; } class MyListAdapter extends RecyclerView.Adapter { private List<String> mStrings; public MyListAdapter(List<String> strings) { this.mStrings = strings; } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View convertView = LayoutInflater.from(getActivity()).inflate(R.layout.item, parent, false); return new MyListViewHolder(convertView); } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { MyListViewHolder viewHolder = (MyListViewHolder) holder; viewHolder.mTextView.setText(mStrings.get(position)); } @Override public int getItemCount() { return 3; } } class MyListViewHolder extends RecyclerView.ViewHolder { private TextView mTextView; public MyListViewHolder(View itemView) { super(itemView); mTextView = (TextView) itemView.findViewById(R.id.tv_content); } } } }
这里需要强调一下,Fragment里的列表必须使用RecyclerView,而不能使用ListView,否者列表不能滑动,具体原因有时间我们在探讨。
还有我们的 NestedScrollView 调用了一个setFillViewport这个方法,这个方法会将NestedScrollView里填充内容的高拉伸,用来填充整个Viewport。如果不设置,那我们的Veiwpager则不会显示。其它的代码没有什么难度这里就不在说明了。
现在我们运行一下这些代码,会看到如下效果:
我们可以看到,顶部的Toolbar的顶到了状态栏,这样不太好,我们在Toolbar上给它设置一个
android:layout_marginTop,这个值设置为
25dp(状态栏大概就25dp),为了适配各个API Level ,我们分别在
vaules-19,
vaules-21里创建一个
dimens文件,然后配置一下:
<dimen name="dimen_status_height">25dp</dimen>
我们在布局引用一下就OK了。
然后我们再看一下效果:
上图是在API 22上的效果,下面的是在API 19 上的效果:
可能大家以为到这里就结束了,当然不会的。有没有人看到标题栏里的
标题那两个字随着上滑就感觉特别讨厌呢?是的,有的,我们的产品大人就很讨厌,所以她把标题放到的最上面变成字体颜色渐变。她要求当折叠结束时文字显示,下滑后文字逐渐消失。怎么办呢?我们慢慢来实现。
首先我们需要修改Toolbar里文字的透明度,所以我们需要修改一下布局,在Toolbar里放一下TextView:
<?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" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.design.widget.AppBarLayout android:id="@+id/app_bar" android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.design.widget.CollapsingToolbarLayout android:id="@+id/toolbar_layout" android:layout_width="match_parent" android:layout_height="match_parent" app:contentScrim="@color/colorAccent" app:layout_scrollFlags="scroll|exitUntilCollapsed"> <ImageView android:id="@+id/imageView" android:layout_width="match_parent" android:layout_height="260dp" android:background="@drawable/header_bar"/> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:layout_marginTop="@dimen/dimen_status_height" app:layout_collapseMode="pin" app:navigationIcon="@mipmap/ic_launcher"> <TextView android:id="@+id/tv_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="标题"/> </android.support.v7.widget.Toolbar> </android.support.design.widget.CollapsingToolbarLayout> <android.support.design.widget.TabLayout android:id="@+id/tabs" android:layout_width="match_parent" android:layout_height="50dp" android:background="@android:color/white"/> </android.support.design.widget.AppBarLayout> <android.support.v4.widget.NestedScrollView android:id="@+id/nestedScrollView" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" > <android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="match_parent"/> </android.support.v4.widget.NestedScrollView> </android.support.design.widget.CoordinatorLayout>
相较于之前的布局我们只是在Toolbar里添加了一个TextView。不是特别的麻烦。
接下来我们需要去代码动态设置标题文字的透明度,我们知道当我们上滑时的折叠效果是通过CollapsingToolbarLayout 实现的。那我们怎么监听它的折叠呢?我去看了看它的源码,发现它还是使用的AppBarLayout 的
OffsetUpdateListener。
首先看它如何绑定的监听:
@Override protected void onAttachedToWindow() { super.onAttachedToWindow();、 // Add an OnOffsetChangedListener if possible final ViewParent parent = getParent(); if (parent instanceof AppBarLayout) { // Copy over from the ABL whether we should fit system windows ViewCompat.setFitsSystemWindows(this, ViewCompat.getFitsSystemWindows((View) parent)); if (mOnOffsetChangedListener == null) { mOnOffsetChangedListener = new OffsetUpdateListener(); } //看这里,它还是使用的AppBarLayout的 mOnOffsetChangedListener ((AppBarLayout) parent).addOnOffsetChangedListener(mOnOffsetChangedListener); // We're attached, so lets request an inset dispatch ViewCompat.requestApplyInsets(this); } }
其它暂时不再深究了,既然我们知道了它也是使用的AppBarLayout的OffsetChangedListener,那我们也使用它。首先看看这个监听:
mAppBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() { @Override public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { } });
我们看一下这个回调方法理由有一个
verticalOffset,这个就是我们竖直方向上AppBarLayout偏移量,也可以理解为AppBarLayout移动距离的变化。知道这些我们只要根据这个值,动态的去计算一下 透明度就OK了。我们去代码去计算一下:
mAppBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() { @Override public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { int scrollRangle = appBarLayout.getTotalScrollRange(); //初始verticalOffset为0,不能参与计算。 if (verticalOffset == 0) { mTvTitle.setAlpha(0.0f); } else { //保留一位小数 float alpha = Math.abs(Math.round(1.0f * verticalOffset / scrollRangle) * 10) / 10; mTvTitle.setAlpha(alpha); } } });
需要注意的是,在未滑动时verticalOffset为0,在计算时一定要注意。
然后我们看一下效果:
现在基本效果实现了,可能还有一些瑕疵,希望大家给多提建议。
最后源码奉上!!!
相关文章推荐
- AppBarLayout CollapsingToolbarLayout 的进一步使用
- Android M新控件之AppBarLayout,NavigationView,CoordinatorLayout,CollapsingToolbarLayout的使用
- Android Design AppBarLayout、NavigationView、FloatingActionButton、CollapsingToolbarLayout等控件的使用
- Android 6.0 AppBarLayout+CollapsingToolbarLayout+NestedScrollView简单使用
- 使用AppBarLayout+CollapsingToolbarLayout实现自定义工具栏折叠效果
- Android M新控件之AppBarLayout,NavigationView,CoordinatorLayout,CollapsingToolbarLayout的使用
- Android M新控件之AppBarLayout,NavigationView,CoordinatorLayout,CollapsingToolbarLayout的使用
- Android M新控件之AppBarLayout,NavigationView,CoordinatorLayout,CollapsingToolbarLayout的使用
- Android M新控件之AppBarLayout,NavigationView,CoordinatorLayout,CollapsingToolbarLayout的使用
- 使用AppBarLayout+CollapsingToolbarLayout实现自定义工具栏折叠效果
- Android M新控件之AppBarLayout,NavigationView,CoordinatorLayout,CollapsingToolbarLayout的使用 标签: supportan
- Material Design风格控件之AppbarLayout、CollapsingToolbarLayout 以及Toolbar的使用
- Android M新控件之AppBarLayout,NavigationView,CoordinatorLayout,CollapsingToolbarLayout的使用
- Android M新控件之AppBarLayout,NavigationView,CoordinatorLayout,CollapsingToolbarLayout的使用
- Material Design之CollapsingToolbarLayout使用
- Toolbar 和 CollapsingToolbarLayout一起使用时menu item无点击反应解决办法
- CollapsingToolbarLayout的使用
- android开发(49) android 使用 CollapsingToolbarLayout ,可折叠的顶部导航栏
- Android4.4沉浸状态栏结合CoordinatorLayout,AppBarLayout,CollapsingToolbarLayout等使用详解
- CollapsingToolbarLayout的使用