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来说,则是一个用于存放 ...
随机推荐
- Android 开发 技术大纲
大家好, 下面 是 Android 开发 的 技术大纲, 觉得 画的很好, 所以 转载过来, 这个 技术大纲 出自 “享学课堂” .
- 论 微服务 和 Entity Framework 对 数据 的 割裂
微服务 的 本质 是 面向对象, 微服务 是 面向对象 对 数据中心 发起的挑战, 在 微服务 架构下, “数据为中心” 的 传统架构 被 严重 割裂, 微服务 的 先天矛盾, 是 对象 和 数据 的 ...
- python + opencv + pycharm +语音生成
安装puthon 2.7.14(内置pip) pip install numpy pip install opencv-python 安装opencv 3.3.0 进入opencv example目录 ...
- [转]Java之JMX 详解
一.JMX简介 JMX是一种JAVA的正式规范,它主要目的是让程序有被管理的功能,那么怎么理解所谓的“被管理”呢?试想你开发了一个软件(如WEB网站),它是在24小时不间断运行的,那么你可能会想要“监 ...
- 高阶组件 Higher-order Components (HOC) 知识点
官方介绍地址:https://reactjs.org/docs/higher-order-components.html
- Executor与ExecutorService
ExecutorService 接口继承了 Executor 接口,是 Executor 的子接口. Executor 接口定义了 execute()方法用来接收一个Runnable接口的对象,而 E ...
- JSON C# Class Generator ---由json字符串生成C#实体类的工具
json作为互联网上轻量便捷的数据传输格式,越来越受到重视.但在服务器端编程过程中,我们常常希望能通过智能提示来提高编码效率.JSON C# Class Generator 能将json格式所表示的J ...
- verilog代码 想法验证---与寄存器输出有关
verilog代码 想法验证---与寄存器输出有关 1. module test_mind( input wire clk, input wire reset, input wire i, outpu ...
- VGA原理
VGA原理 1.VGA时序 2.不同的显示标准,有不同的水平段和垂直段 3.像素时钟和帧频的关系 联系目前调试的1080i 50Hz: 像素时钟为148.5MHz, 水平段周期 = 2640 X (1 ...
- CentOS 服务器安全设置 --摘抄自https://www.kafan.cn/edu/8169544.html
一.系统安全记录文件 操作系统内部的记录文件是检测是否有网络入侵的重要线索.如果您的系统是直接连到Internet,您发现有很多人对您的系统做Telnet/FTP登录尝试,可以运行”#more /va ...