首先先说一下原理:
首先整个控件是由三个子控件组成,左侧View、滑块、右侧View。
在初始化状态下左侧View是隐藏的,右侧View 的宽度是控件宽度-滑块宽度;
在滑动过程中,会同步的增加左侧视图宽度,减小右侧View宽度,使左右View+滑块宽度跟控件宽度一致;
滑动结束时,右侧控件隐藏,左侧View 的宽度是控件宽度-滑块宽度;
OK,原理就是这样,下面贴代码:
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(),
debugShowCheckedModeBanner: false,
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Color postitiveColor = new Color(0xFFEF0078);
Color negetiveColor = new Color(0xFFFFFFFF);
double percentage = 0.0;
double initial = 0.0;
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
backgroundColor: Colors.white,
elevation: 0.0,
centerTitle: true,
title: Text(
'CUSTOM SLIDER',
style: TextStyle(color: postitiveColor),
),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(
percentage.round().toString() + ' %',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 70.0,
color: postitiveColor,
),
),
GestureDetector(
onPanStart: (DragStartDetails details) {
initial = details.globalPosition.dx;
},
onPanUpdate: (DragUpdateDetails details) {
double distance = details.globalPosition.dx - initial;
double percentageAddition = distance / 100;
print('distance ' + distance.toString());
setState(() {
print('percentage ' +
(percentage + percentageAddition)
.clamp(0.0, 100.0)
.toString());
percentage =
(percentage + percentageAddition).clamp(0.0, 100.0);
});
},
onPanEnd: (DragEndDetails details) {
initial = 0.0;
percentage = 0;
print('onPanEnd ');
print('初始化为0 ');
},
child: CustomSlider(
percentage: this.percentage,
positiveColor: postitiveColor,
negetiveColor: negetiveColor,
),
)
],
),
),
);
}
}
class CustomSlider extends StatelessWidget {
double totalWidth = 200.0;
double totalWidth1 = 160.0;
double percentage;
Color positiveColor;
Color negetiveColor;
CustomSlider({this.percentage, this.positiveColor, this.negetiveColor});
@override
Widget build(BuildContext context) {
print((percentage / 100) * totalWidth);
print((1 - percentage / 100) * totalWidth);
return Container(
width: totalWidth + 4.0,
height: 30.0,
child: Row(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Offstage(
offstage: percentage==0?true:false,
child: Container(
decoration: BoxDecoration(
color: positiveColor,
border: Border.all(
color: Colors.yellow, width: percentage == 0 ? 0 : 1)),
height: 30,
width: (percentage / 100) * totalWidth1,
),
),
Container(
width: 40,
child: Image(
image: AssetImage("assets/images/huakuai_btn.png"),
width: 40,
height: 30,
color: null,
fit: BoxFit.scaleDown,
alignment: Alignment.center,
)),
Offstage(
offstage: percentage==100?true:false,
child:Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
color: Colors.green, width: percentage == 1? 1 : 0)),
height: 30,
width: (1 - percentage / 100) * totalWidth1,
),
)
],
),
);
}
}
滑块图片自行更换,如果想要实现活动后的页面效果,在
onPanEnd: (DragEndDetails details) {
}
中处理。