吉新鹏近况,杭州到上海汽车,清风精品影视论坛
viewpager,scrollview 嵌套viewpager滑动冲突解决
自定义 behavior - 完美仿 qq 浏览器首页,美团商家详情页
coordinatorlayout是在 google io/15 大会发布的,遵循material 风格,包含在 support library中,结合appbarlayout, collapsingtoolbarlayout等 可 产生各种炫酷的效果
coordinatorlayout is intended for two primary use cases:
as a top-level application decor or chrome layout
as a container for a specific interaction with one or more child views
简单来说就是
动态图
它是继承与linearlayout的,默认 的 方向 是vertical
类型 | 说明 |
---|---|
int scroll_flag_enter_always | when entering (scrolling on screen) the view will scroll on any downwards scroll event, regardless of whether the scrolling view is also scrolling. |
int scroll_flag_enter_always_collapsed | an additional flag for 'enteralways' which modifies the returning view to only initially scroll back to it's collapsed height. |
int scroll_flag_exit_until_collapsed | when exiting (scrolling off screen) the view will be scrolled until it is 'collapsed'. |
int scroll_flag_scroll | the view will be scroll in direct relation to scroll events. |
int scroll_flag_snap | upon a scroll ending, if the view is only partially visible then it will be snapped and scrolled to it's closest edge. |
类型 | 说明 |
---|---|
int scroll_flag_enter_always | w((entering) / (scrolling on screen))下拉的时候,这个view也会跟着滑出。 |
int scroll_flag_enter_always_collapsed | 另一种enteralways,但是只显示折叠后的高度。 |
int scroll_flag_exit_until_collapsed | ((exiting) / (scrolling off screen))上拉的时候,这个view会跟着滑动直到折叠。 |
int scroll_flag_scroll | 这个view将会响应scroll事件 |
int scroll_flag_snap | 在scroll滑动事件结束以前 ,如果这个view部分可见,那么这个view会停在最接近当前view的位置 |
我们可以通过两种 方法设置这个flag
setscrollflags(int)
app:layout_scrollflags="scroll|enteralways"
appbarlayout必须作为coordinatorlayout的直接子view,否则它的大部分功能将不会生效,如layout_scrollflags等。
<android.support.design.widget.coordinatorlayout android:id="@+id/main_content" 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/appbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/themeoverlay.appcompat.dark.actionbar"> <android.support.v7.widget.toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionbarsize" android:background="?attr/colorprimary" app:layout_scrollflags="scroll|enteralways" app:popuptheme="@style/themeoverlay.appcompat.light"/> . </android.support.design.widget.appbarlayout> <android.support.v7.widget.recyclerview android:id="@+id/recyclerview" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"/> <android.support.design.widget.floatingactionbutton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="end|bottom" android:layout_margin="15dp" android:src="@drawable/add_2"/> </android.support.design.widget.coordinatorlayout>
从图中我们可以知道 layout_scrollflags="scroll|enteralways,
前面已经说到layout_scrollflags=scroll的时候,这个view会 跟着 滚动 事件响应,
layout_scrollflags=“enteralways”的时候 这个view会响应下拉事件
所以呈现出来的结果应该是我们在上拉的时候toolbar 会隐藏,下拉的时候toolbar会出来
那如果当我们的toolbar 等于 app:layout_scrollflags="scroll|snap"的时候 ,
layout_scrollflags=scroll的时候,这个view会 跟着 滚动 事件响应,
layout_scrollflags=“snap”的时候 在scroll滑动事件结束以前 ,如果这个view部分可见,那么这个view会停在最接近当前view的位置。
综上呈现的效果如下,代码见toolbarsamplesnar的布局文件
<android.support.design.widget.coordinatorlayout android:id="@+id/main_content" 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:layout_width="match_parent" android:layout_height="250dp"> <imageview android:layout_width="match_parent" android:layout_height="200dp" android:background="?attr/colorprimary" android:scaletype="fitxy" android:src="@drawable/tangyan" app:layout_scrollflags="scroll|enteralways"/> <android.support.design.widget.tablayout android:id="@+id/tabs" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignparentbottom="true" android:background="?attr/colorprimary" app:tabindicatorcolor="@color/coloraccent" app:tabindicatorheight="4dp" app:tabselectedtextcolor="#000" app:tabtextcolor="#fff"/> </android.support.design.widget.appbarlayout> <android.support.v4.view.viewpager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"/> <android.support.design.widget.floatingactionbutton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="end|bottom" android:layout_margin="15dp" android:src="@drawable/add_2"/> </android.support.design.widget.coordinatorlayout>
其实相对于前 一个例子,只是把 摆放recyclerview 的位置替换成viewpager而已,为了有页面导航器的效果,再使用 tablayout而已,而tablayout 在我们滑动的时候最终会停靠在 最顶部,是因为我们没有设置其layout_scrollflags,即tablayout是静态的
运行以后,即可看到以下的结果
代码注释 里面已经解释地很清楚了 ,这里我就不解释了
public class viewpagersample extends appcompatactivity { viewpager mviewpager; list<fragment> mfragments; string[] mtitles = new string[]{ "主页", "微博", "相册" }; private tablayout mtablayout; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_third); // 第一步,初始化viewpager和tablayout mviewpager = (viewpager) findviewbyid(r.id.viewpager); mtablayout = (tablayout) findviewbyid(r.id.tabs); setupviewpager(); } private void setupviewpager() { mfragments = new arraylist<>(); for (int i = 0; i < mtitles.length; i++) { listfragment listfragment = listfragment.newinstance(mtitles[i]); mfragments.add(listfragment); } // 第二步:为viewpager设置适配器 basefragmentadapter adapter = new basefragmentadapter(getsupportfragmentmanager(), mfragments, mtitles); mviewpager.setadapter(adapter); // 第三步:将viewpager与tablelayout 绑定在一起 mtablayout.setupwithviewpager(mviewpager); } }
如果我们想更改indicator的相关样式,我们可以在布局文件里面使用
<android.support.design.widget.tablayout android:id="@+id/tabs" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignparentbottom="true" android:background="?attr/colorprimary" app:tabindicatorcolor="@color/coloraccent" app:tabindicatorheight="4dp" app:tabselectedtextcolor="#000" app:tabtextcolor="#fff"/>
如果你不想使用google 帮我们 封装好的控件的话,你也可以自己自定义一个控件,你可以参考我的这一篇博客
在看例子结合viewpager的视觉特差之前 ,我们需要先了解collapsingtoolbarlayout这个控件
collapsingtoolbarlayout继承与framelayout,官网地址,请自备梯子。
简单来说 ,collapsingtoolbarlayout是工具栏的包装器,它通常作为appbarlayout的孩子。主要实现以下功能
下面我们一起来看一下几个常量
常量 | 解释说明 |
---|---|
int collapse_mode_off | the view will act as normal with no collapsing behavior.(这个 view将会 呈现正常的结果,不会表现出折叠效果) |
int collapse_mode_parallax | the view will scroll in a parallax fashion. see setparallaxmultiplier(float) to change the multiplier used.(在滑动的时候这个view 会呈现 出 视觉特差效果 ) |
int collapse_mode_pin | the view will pin in place until it reaches the bottom of the collapsingtoolbarlayout.(当这个view到达 collapsingtoolbarlayout的底部的时候,这个view 将会被放置,即代替整个collapsingtoolbarlayout) |
我们有两种方法可以设置这个常量,
方法一:在代码中使用这个方法
setcollapsemode(int collapsemode)
方法 二:在布局文件中使用自定义属性
app:layout_collapsemode="pin"
到此 ,collapsingtoolbarlayout的一些重要属性已经讲解完毕,下面我们一起来看一下我们是怎样结合viewpager实现视差效果的
<?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:background="@android:color/background_light" android:fitssystemwindows="true" > <android.support.design.widget.appbarlayout android:id="@+id/main.appbar" android:layout_width="match_parent" android:layout_height="300dp" android:fitssystemwindows="true" android:theme="@style/themeoverlay.appcompat.dark.actionbar" > <android.support.design.widget.collapsingtoolbarlayout android:id="@+id/main.collapsing" android:layout_width="match_parent" android:layout_height="250dp" android:fitssystemwindows="true" app:contentscrim="?attr/colorprimary" app:expandedtitlemarginend="64dp" app:expandedtitlemarginstart="48dp" app:layout_scrollflags="scroll|exituntilcollapsed" > <imageview android:id="@+id/main.backdrop" android:layout_width="match_parent" android:layout_height="match_parent" android:fitssystemwindows="true" android:scaletype="centercrop" android:src="@drawable/tangyan" app:layout_collapsemode="parallax" /> <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" /> </android.support.design.widget.collapsingtoolbarlayout> <android.support.design.widget.tablayout android:id="@+id/tabs" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignparentbottom="true" android:background="?attr/colorprimary" app:tabindicatorcolor="@color/coloraccent" app:tabindicatorheight="4dp" app:tabselectedtextcolor="#000" app:tabtextcolor="#fff"/> </android.support.design.widget.appbarlayout> <android.support.v4.view.viewpager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"> </android.support.v4.view.viewpager> <android.support.design.widget.floatingactionbutton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="end|bottom" android:layout_margin="15dp" android:src="@drawable/add_2"/> </android.support.design.widget.coordinatorlayout>
结构图如图片所示,先说明collapsingtoolbarlayout的变化
collapsingtoolbarlayout里面 包含imageview 和toolbar,imageview的app:layout_collapsemode="parallax",表示视差效果,toolbar的 app:layout_collapsemode="pin",当这个toobar到达 collapsingtoolbarlayout的底部的时候,会代替整个collapsingtoolbarlayout显示
接着说明tablayout的变化
从前面的描述我们已经知道当 没有指定app:layout_scrollflags的时候,最终tablayout会静止,不会随着滑动的 时候消失不见
如果我们仅仅 改变collapsingtoolbarlayout的app:layout_scrollflags="scroll|exituntilcollapsed|snap"的时候,其它代码不变,运行以后,我们将可以看到如下效果图
这篇博客主要讲解了coordinatorlayout,appbarlayout,collapsingtoolbarlayout的一些相关属性。
coordinatorlayout的相关用法还有很多,有兴趣 了解的请自行阅读: 官方文档地址
coordinatorlayout这个控件真的很强大,使用它可以实现各种炫酷的效果,简化了开发者的许多工作,有能力的话可以去研究一下源码 ,看是怎样实现的?
参考文章:
源码下载地址:https://github.com/gdutxiaoxu/coordinatorlayoutexample.git
欢迎大家关注我的微信公众号号 stormjun949(徐公码字),即可关注。 目前专注于 android 开发,主要分享 android开发相关知识和一些相关的优秀文章,包括个人总结,职场经验等。
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
Android Manifest中meta-data扩展元素数据的配置与获取方式
Android实现获取meta-data和build.gradle的值
Android获取清单文件中的meta-data,解决碰到数值为null的问题
解决webview 第二次调用loadUrl页面不刷新的问题
解决Android WebView拦截url,视频播放加载失败的问题
Android webview加载https链接错误或无响应的解决
网友评论