携手创造,一起生长!这是我参与「日新方案 8 月更文应战」的第5天,点击检查活动详情
前语
继完成自定义TabBar主题色装备完成TabBar主题色定制后,对全体页面做定制化主题色装备更加具有沉浸式作用。因而为了更好体现出主题色装备特色,本次对页面全体做定制化主题色完成做一次介绍。
完成进程
布景沉浸式装备
依据需求描述需求对顶部透出布景做主题切换作用。当频道页面做左右滑动操作时,页面布景也会随之发生改变。原有的框架结构如下所示:
/// 伪代码方式
NestedScrollView(
headerSliverBuilder:(
SliverAppBar(
flexibleSpace:MagicFlexibleSpaceBar()
bottom: TabBar()
)
)
body:TabBarView(
CustomScrollView(
CupertinoSliverRefreshControl()
SliverFixedExtentList()
)
///同上CustomScrollView
....
)
)
假如需求添加布景色覆盖住全局就必须将NestedScrollView
嵌套在布局内部。可采用Stack
方式讲主题布景作为底层布局在全体页面下方呈现出来,此外只需求为BackgroundThemes
组件提供页面滑动监听即可完成主题布景切换的作用。
/// 伪代码方式
Stack(
BackgroundThemes[]//主题切换组件
NestedScrollView(
headerSliverBuilder:(
SliverAppBar(
flexibleSpace:MagicFlexibleSpaceBar()
bottom: TabBar()
)
)
body:TabBarView(
CustomScrollView(
CupertinoSliverRefreshControl()
SliverFixedExtentList()
)
///同上CustomScrollView
....
)
)
)
经过获取到Tab
控制器偏移量得知当时页面下标,经过装备主题布景数组picUrls
得到当时布景图,内部使用Stack
来完成当时和下一个页面布景切换功能(切换进程带有透明度改变使得切换进程更为天然),切换详细完成如下:
Positioned(
top: 0.0,
left: 0.0,
right: 0.0,
/// 监听
child: AnimatedBuilder(
animation: tabController1.animation,
builder: (context, child) {
// 与之前完成TabBar指示器的办法一样
double page = 0;
int realPage = 0;
page = tabController1.index + tabController1.offset ?? 0;
realPage =
tabController1.index + tabController1.offset?.floor() ?? 0;
double opacity = 1 - (page - realPage).abs();
int nextIndex =
realPage + 1 < colors.length ? realPage + 1 : realPage;
String thisPic = picUrls[realPage];
String nextPic = picUrls[
realPage + 1 < picUrls.length ? realPage + 1 : realPage];
List<Widget> childs = List();
//当时页面的布景图片
if (thisPic != null && thisPic != '') {
childs.add(
Opacity(
opacity: opacity,
child: Image.asset(
thisPic,
fit: BoxFit.fitWidth,
alignment: Alignment.topCenter,
),
),
);
}
//下一个页面的布景图片
if (nextPic != null && nextPic != '') {
childs.add(Opacity(
opacity: 1 - opacity,
child: Image.asset(
picUrls[realPage + 1 < picUrls.length
? realPage + 1
: realPage],
fit: BoxFit.fitWidth,
alignment: Alignment.topCenter,
),
));
}
return Stack(
children: childs,
);
}),
),
布景主题完成需求将SliverAppBar
以及内部FlexibleSpaceBar
的布景色设置为Colors.transparent
来透出布景。
上滑顶部栏躲藏以及布景透出
完成布景色主题之后继续完成顶部上滑时底部列表不隐瞒布景。
为处理默许完成是这样的,当做上滑操作时顶部栏可以正常躲藏但上滑列表会将布景色图片隐瞒。这是由于NestedScrollView
以及其内部组件完成有关,上滑联动headerSliverBuilder
组件是悬浮之上和body
会堆叠的。若希望完成不堆叠的作用就需求只对body做滑动操作,因而需求改动点是将NestedScrollView
设置为不可滑动的组件,一起赋值ScrollController
;body
的CustomScrollView
设置本身ScrollController
并且嵌套NotificationListener
来监听滑动,当在body
在指定范围内滑动联动带上NestedScrollView
滑动。实际上该操作便是将NestedScrollView
内部的outScroller
释放掉,让开发自行控制body
滑动操作以此来防止上下组件堆叠。
NestedScrollView(
controller: fatherController,
physics: NeverScrollableScrollPhysics(),
body:TabBarView(
children:[
NotificationListener(
onNotification:(position) {
// 获取到position 和 fatherController 做比较
// 依据滑动情况 对fatherController做移动操作
}
child: CustomScrollView(
controller: scrollController,
physics: NestedClampingScrollPhysics(),
)
)
]
)
)
全体功能展现
详细完成代码看这儿