Android CoordinatorLayout实现多列表切换并和头布局联动;
注意:不是双列表联动,是多列表和头布局联动;
大概就是和饿了么店铺首页类似的布局框架吧,头布局显示时,列表RecyclerView或ScrollView和头布局一起滚动,头布局完全隐藏后列表再去滚动,可以多个列表切换;
有空再上图看效果吧;
1、主要的布局文件,注释写的很清楚;
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="222dp">
<!--最为重要的属性就是 app:layout_scrollFlags :设置上半部分滑动的方式
1.scroll 表示CollapsingToolbarLayout可以滚动(不设置的话头部的ImageView将不能折叠)
2.enterAlways 表示底部的滚动控件只要向下滚动,头部就显示出来
3.enterAlwaysCollapsed 表示当底部滚动控件滚动见顶时,头部显示出来
4.exitUntilCollapsed 表示头部折叠到最小高度时(Toolbar的高度),就不再折叠
5.snap 表示在滑动过程中如果停止滑动,则头部会就近折叠(要么恢复原状,要么折叠成一个Toolbar)-->
<!--app:contentScrim="@color/colorWhite" 折叠后的颜色-->
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
app:contentScrim="@color/colorWhite"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
android:layout_height="match_parent">
<!--app:layout_collapseParallaxMultiplier="0.6" 视差效果-->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/banner"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.6"
></RelativeLayout>
<!--app:layout_collapseMode="pin" Toolbar的状态,是否一直显示-->
<android.support.v7.widget.Toolbar
app:layout_collapseMode="pin"
app:contentInsetStart="0dp"
android:layout_width="match_parent"
android:layout_height="48dp">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00ffffff"
android:text="点击开始搜索"
android:textSize="16dp"
android:gravity="center"
android:id="@+id/tv"
></TextView>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<!--app:layout_behavior="@string/appbar_scrolling_view_behavior" 在整体布局的下面-->
<RelativeLayout
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:background="@color/colorWhite"
android:layout_height="match_parent">
<android.support.design.widget.TabLayout
android:id="@+id/tab"
android:layout_width="match_parent"
android:layout_height="46dp">
</android.support.design.widget.TabLayout>
<c.c.b.listortoolbar.NotConflictViewPager
android:id="@+id/vp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/tab"
></c.c.b.listortoolbar.NotConflictViewPager>
</RelativeLayout>
</android.support.design.widget.CoordinatorLayout>
2、该布局中的Activity写法:
public class MainActivity extends AppCompatActivity {
private TabLayout tabLayout;
private NotConflictViewPager vp;
private TextView tv;
private AppBarLayout appbar;
private List<String> datas = Arrays.asList("呢呢","嘿嘿","哈哈");
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tabLayout = (TabLayout)findViewById(R.id.tab);
vp = (NotConflictViewPager)findViewById(R.id.vp);
tv = (TextView) findViewById(R.id.tv);
appbar = (AppBarLayout) findViewById(R.id.appbar);
tabLayout.setupWithViewPager(vp);
vp.setAdapter(new Ap(getSupportFragmentManager()));
appbar.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int i) {
if (i == 0){ //打开
tv.setTextColor(getResources().getColor(R.color.colorWhite));
}else if (Math.abs(i) >= appbar.getTotalScrollRange()){ //折叠
tv.setTextColor(getResources().getColor(R.color.defaultTextview));
}else {
// 中间
}
}
});
}
class Ap extends FragmentStatePagerAdapter{
public Ap(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int i) {
return new cFragment(datas.get(i));
}
@Override
public int getCount() {
return datas.size();
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return datas.get(position);
}
}
}
3、填充ViewPager的Fragment;
R.layout.fragment_c (子条目的layout就不写了,随便一个有内容的布局就行)
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".cFragment">
<android.support.v7.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"></android.support.v7.widget.RecyclerView>
</FrameLayout>
public class cFragment extends Fragment {
public cFragment() {
}
private String title;
@SuppressLint("ValidFragment")
public cFragment(String title) {
this.title = title;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_c, container, false);
initView(v);
return v;
}
private void initView(View view) {
RecyclerView rv = view.findViewById(R.id.rv);
if("嘿嘿".equals(title)){
rv.setLayoutManager(new GridLayoutManager(getActivity(),2));
rv.addItemDecoration(new GridDividerItemDecoration(getActivity())); //分割线,报错删除就行了;
}else {
rv.addItemDecoration(new DividerItemDecoration(getActivity(),1));
rv.setLayoutManager(new LinearLayoutManager(getActivity()));
}
rv.setAdapter(new Ap());
}
class Ap extends RecyclerView.Adapter<Ap.Vh>{
@Override
public Vh onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
return new Vh(LayoutInflater.from(getContext()).inflate(R.layout.item_rv, viewGroup, false));
}
@Override
public void onBindViewHolder(@NonNull Vh vh, int i) {
vh.tv.setText(title);
}
@Override
public int getItemCount() {
return 20;
}
class Vh extends RecyclerView.ViewHolder{
TextView tv;
public Vh(@NonNull View itemView) {
super(itemView);
tv = itemView.findViewById(R.id.tv);
}
}
}
}
列表和ViewPager冲突解决;
public class NotConflictViewPager extends ViewPager {
public NotConflictViewPager(Context context) {
super(context);
}
public NotConflictViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
private float mX;
private float mY;
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction()){
case MotionEvent.ACTION_DOWN:
mX = ev.getX();
mY = ev.getY();
getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_MOVE:
if (Math.abs(mX-ev.getX())> Math.abs(mY-ev.getY())){
getParent().requestDisallowInterceptTouchEvent(true);
}else{
getParent().requestDisallowInterceptTouchEvent(false);
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
getParent().requestDisallowInterceptTouchEvent(false);
break;
}
return super.dispatchTouchEvent(ev);
}
}
Android CoordinatorLayout实现多列表切换并和头布局联动;的更多相关文章
- android 项目学习随笔九(ListView加头布局)
1.缓冲背景色 <ListView android:id="@+id/lv_list" android:layout_width="match_parent&quo ...
- Android BottomSheet:List列表或Grid网格展示(3)
Android BottomSheet:List列表或Grid网格展示(3) BottomSheet可以显示多种样式的底部弹出面板风格,比如常见的List列表样式或者Grid网格样式,以一个例子 ...
- Android学习笔记(23):列表项的容器—AdapterView的子类们
AdapterView的子类的子类ListView.GridView.Spinner.Gallery.AdapterViewFlipper和StackView都是作为容器使用,Adapter负责提供各 ...
- C#:基于WMI查询USB设备信息 及 Android设备厂商VID列表
/* ---------------------------------------------------------- 文件名称:WMIUsbQuery.cs 作者:秦建辉 MSN:splashc ...
- Android禁止横屏竖屏切换
在Android中要让一个程序的界面始终保持一个方向,不随手机方向转动而变化的办法: 只要在AndroidManifest.xml里面配置一下就可以了. 在AndroidManifest.xml的ac ...
- Android之fragment点击切换和滑动切换结合
学了一小段时间的Android,主要接触的是UI设计,打交道最多莫过于fragment了吧.在Android3.0引入了fragment的概念后,几乎在所以的Android的应用中都可以看见其身影,已 ...
- Android 应用内多语言切换
最近公司的 App 里需要用到多语言切换,简单来说,就是如果用户没有选择语言选项时,App 默认跟随系统语言,如果用户在 App 内进行了语言设置,那么就使用用户设置的语言.当然,你会发现,App 的 ...
- 【转】Android 模拟器横屏竖屏切换设置
http://blog.csdn.net/zanfeng/article/details/18355305# Android 模拟器横屏竖屏切换设置时间:2012-07-04 来源:设计与开发 ...
- Android精通:View与ViewGroup,LinearLayout线性布局,RelativeLayout相对布局,ListView列表组件
UI的描述 对于Android应用程序中,所有用户界面元素都是由View和ViewGroup对象构建的.View是绘制在屏幕上能与用户进行交互的一个对象.而对于ViewGroup来说,则是一个用于存放 ...
随机推荐
- 我发起了一个 用 物理服务器 和 .Net 平台 构建云平台 的 .Net 开源项目
大家好 , 我发起了一个 用 物理服务器 和 .Net 平台 构建云平台 的 .Net 开源项目 . 对 , 用 物理服务器 和 .Net 平台 构建 云平台 . 通过 .Net 构建 分布式 计算集 ...
- springMVC--4种映射处理器handlerMapping
根据controller的name名称来映射寻找controller:BeanNameUrlHandlerMapping (默认) 1.1开启该映射:默认是开启的 <bean class=&q ...
- taro 微信小程序原生作用域获取
在 Taro 的页面和组件类中,this 指向的是 Taro页面或组件实例. 但是一般我们需要获取 Taro的页面和组件 所对应的 小程序原生页面和组件实例,这个时候我们可以通过 this.$scop ...
- 在外网访问家里面的电脑 和 DMZ
方法1:使用 MDZ ( demilitarized zone), 中文意思 非武装的区域.我们的家用电脑一般都在 路由器所在的 C类内网(192.X.X.X 的 ip).外网是不能直接访问内网的. ...
- VS2013 未找到与约束。。。
新建项目或打开项目时,VS2013 未找到与约束...问题: 解决方案:控制面板>程序>程序和功能 找到如下选中软件右击修复 即可(修复前需关闭VS2013)
- 设计模式-责任链模式Chain of Responsibility)
一.定义 职责链模式是一种对象的行为模式.在职责链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求的客户端并不知道链 ...
- linux mv命令详解
Linux mv命令 Linux mv命令用来为文件或目录改名.或将文件或目录移入其它位置. 用法: mv [选项]... [-T] 源文件 目标文件 mv [选项]... 源文件... 目录 mv ...
- 升级ambari、HDP版本(ambari 2.1升级到2.4、HDP2.3升级到2.5)
转载自:http://blog.csdn.net/levy_cui/article/details/52461377 官方升级版本说明 http://docs.hortonworks.com/HDPD ...
- redis常用客户端命令
sentinel操作: 1.查询主节点:redis-cli -h 172.16.4.220 -p 46379 SENTINEL get-master-addr-by-name mymaster 2.查 ...
- JavaScript学习总结(二、隐式类型转换、eval())
一.(避免)隐式类型转换 console.log(false == 0); //logs true; console.log(false === 0); //logs false; conso ...