有没有人在 Android for Flutter 中遇到类似 fadingEdgeLength 的东西,这样当你向上滚动时项目开始淡入屏幕顶部?
下面是我用Widgets搭建的界面。
如果有帮助,这些是我指的属性:
android:fadingEdgeLength="10dp"
android:requiresFadingEdge="水平">
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('CMS Users'),
),
body: ListView.builder(
padding: EdgeInsets.only(top: 20.0, left: 4.0),
itemExtent: 70.0,
itemCount: data == null ? 0 : data.length,
itemBuilder: (BuildContext context, int index) {
return Card(
elevation: 10.0,
child: InkWell(
onTap: () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (BuildContext context) =>
new PeopleDetails("Profile Page", profiles[index]),
));
},
child: ListTile(
leading: CircleAvatar(
child: Text(profiles[index].getInitials()),
backgroundColor: Colors.deepPurple,
radius: 30.0,
),
title: Text(
data[index]["firstname"] + "." + data[index]["lastname"]),
subtitle: Text(
data[index]["email"] + "\n" + data[index]["phonenumber"]),
),
),
);
}),
);
}
}
正如其他人所提到的,您可以将 ListView 放在 ShaderMask 下,但是通过少量的额外参数化您可以获得更好的结果 - 至少如果您想实现我想要的效果。
您可以选择为 LinearGradient 设置 [stops] 列表:
[stops] 列表(如果指定)必须与 [colors] 具有相同的长度。它为每种颜色指定向量从开始到结束的分数,介于 0.0 和 1.0 之间。
加:有混合模式,其中源的颜色通道被忽略,只有不透明度有影响。 BlendMode.dstOut 在下面的例子中也是如此。正如您在屏幕截图中看到的那样,没有具体使用紫色,仅用于矢量的分数。
您可以使用不同的 [blendMode] 设置,其中有很多。
void main() {
runApp(
MaterialApp(
home: Scaffold(
body: FadingListViewWidget(),
),
),
);
}
class FadingListViewWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Container(
height: 320,
child: ShaderMask(
shaderCallback: (Rect rect) {
return LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Colors.purple, Colors.transparent, Colors.transparent, Colors.purple],
stops: [0.0, 0.1, 0.9, 1.0], // 10% purple, 80% transparent, 10% purple
).createShader(rect);
},
blendMode: BlendMode.dstOut,
child: ListView.builder(
itemCount: 100,
itemBuilder: (BuildContext context, int index) {
return Card(
color: Colors.orangeAccent,
child: ListTile(
title: Text('test test test test test test'),
),
);
},
),
),
),
);
}
}
您可以在
ShaderMask
上应用ListView
并使用BlendMode
来获得您想要的东西。
Widget animationsList() {
return Expanded(
child: ShaderMask(
shaderCallback: (Rect bounds) {
return LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: <Color>[Colors.transparent,Colors.red],
).createShader(bounds);
},
child: Container(height: 200.0, width: 200.0, color: Colors.blue,),
blendMode: BlendMode.dstATop,
),
);
我有类似的要求,所以我为此任务创建了一个库。 你可以在这里找到它:fading_edge_scrollview
要使用它,你需要在你的
ScrollController
中添加一个ListView
,然后将这个ListView
作为孩子传递给FadingEdgeScrollView.fromScrollView
构造函数
用Stack包裹Listview,添加Listview作为第一个child,第二个是Positioned Container with LinearGradient。 我的代码示例:
堆栈:
return Stack(
children: <Widget>[
ListView(
scrollDirection: Axis.horizontal,
children: _myListOrderByDate,
),
FadeEndListview(),
],
);
叠加类:
class FadeEndListview extends StatelessWidget {
const FadeEndListview({
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Positioned(
right: 0,
width: 8.0,
height: kYoutubeThumbnailsHeight,
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerRight,
end: Alignment.centerLeft,
stops: [0.0, 1.0],
colors: [
Theme.of(context).scaffoldBackgroundColor,
Theme.of(context).scaffoldBackgroundColor.withOpacity(0.0),
],
),
),
),
);
}
}
它看起来像这样:
尝试使用
Text(
'This is big text, I am using Flutter and trying to fade text',
overflow: TextOverflow.fade,
maxLines: 1,
),
我将 Krisztián Ódor 的答案和 ChatGPT 的结果结合起来,得到一个小部件,当用户滚动浏览内容时,该小部件会淡化 ListView 的内容。当 ListView 在任一侧时,这一侧没有褪色。我这样做是因为在以前的版本中,由于褪色,我的部分内容不可见。该小部件适用于两个滚动方向。要获得更多或更少的褪色,请调整 LinearGradient 中的停止点。
import 'package:flutter/material.dart';
class FadingListView extends StatefulWidget {
const FadingListView({required this.child, super.key});
final ListView child;
@override
State<FadingListView> createState() => _FadingListViewState();
}
class _FadingListViewState extends State<FadingListView> {
double _stopStart = 0;
double _stopEnd = 1;
@override
Widget build(BuildContext context) {
return NotificationListener<ScrollNotification>(
onNotification: (scrollNotification) {
setState(() {
_stopStart = scrollNotification.metrics.pixels / 10;
_stopEnd = (scrollNotification.metrics.maxScrollExtent -
scrollNotification.metrics.pixels) /
10;
_stopStart = _stopStart.clamp(0.0, 1.0);
_stopEnd = _stopEnd.clamp(0.0, 1.0);
});
return true;
},
child: ShaderMask(
shaderCallback: (Rect rect) {
return LinearGradient(
begin: widget.child.scrollDirection == Axis.horizontal
? Alignment.centerLeft
: Alignment.topCenter,
end: widget.child.scrollDirection == Axis.horizontal
? Alignment.centerRight
: Alignment.bottomCenter,
colors: const [
Colors.black,
Colors.transparent,
Colors.transparent,
Colors.black
],
stops: [0.0, 0.05 * _stopStart, 1 - 0.05 * _stopEnd, 1.0],
).createShader(rect);
},
blendMode: BlendMode.dstOut,
child: Padding(
padding: const EdgeInsets.all(1.0),
child: widget.child,
),
),
);
}
}