因为一个外包项目需要实现左右Listview的联动,比较类似于 饿了嘛商品页面的那种形式,左侧ListView点击后可以让右侧跳转至对应分类,右侧滚动时,左侧也会选择到对应的分类。
网上找了一段时间没有找到比较满意的适配空安全的版本,所以自己写了一个比较粗糙的。源码放在了:https://github.com/NeverOvO/flutterlinkagerollinglist
请参考源码后根据自己项目的实际需要来修改。理论上左右2个ListView可以放下任何形式的Widget。项目无任何依赖。
核心源码
//修改这里的数据会更改一页高度
const double leftItemHeight = 45; // 左边一个item的高度
const double rightItemTitleHeight = 38; // 右边一个标题的高度
const int leftWidgetFlex = 3; // 左边组件占据空间的比例
const int rightWidgetFlex = 9; // 右边组件占据空间的比例
const int rightGridViewCrossAxisCount = 3; //右侧GirdView一排数量,这里测试时为3
上述代码放在头部,来控制后面的代码中的部分高度和比例,修改这里会对计算右侧一页的高度产生影响
//右侧ListView的监听
_rightListController.addListener((){
//滚动超过右侧Listview的项目长度时,将左侧选中最后一项,这一个判断不添加的话,左侧ListView选择不到最后一项
if(_rightOffSetStepList.last <= _rightListController.offset){
setState(() {
_indexLeft = _rightOffSetStepList.length -1;
});
}else{
for(int i = 0; i < _rightOffSetStepList.length ; i++){
if(_rightOffSetStepList[i] > _rightListController.offset + 0.1){
setState(() {
_indexLeft = (i - 1 < 0 ? 0 : ( i - 1) );
});
break;
}
}
}
});
上述代码为右侧ListView的监听部分,用这里来控制左侧ListView的选中项目
//计算右侧的一页高度
void _calculation(){
//这个数组用来计算单独一个List的页面高度
List rightListStep = [];
_rightOffSetStepList.clear();
_rightGridItemHight = (MediaQuery.of(context).size.width - 20) * rightWidgetFlex / (leftWidgetFlex + rightWidgetFlex) / rightGridViewCrossAxisCount ;
rightListStep.add((_rightGridItemHight * ( (ll[0] ~/ rightGridViewCrossAxisCount) + (ll[0] % rightGridViewCrossAxisCount == 0 ? 0 : 1)) + rightItemTitleHeight));
for(int i =1; i<_left.length ; i++){
rightListStep.add((_rightGridItemHight * ( (ll[i] ~/ rightGridViewCrossAxisCount) + (ll[i] % rightGridViewCrossAxisCount == 0 ? 0 : 1)) + rightItemTitleHeight));
}
_lastGridHeight = (MediaQuery.of(context).size.height - MediaQuery.of(context).padding.top - kBottomNavigationBarHeight) - rightListStep.last;
for(int i =0;i< rightListStep.length ; i++){
double _off = 0.0;
for(int j = 0; j < i ; j++){
_off += rightListStep[j];
}
_rightOffSetStepList.add(_off);
}
}
上述代码为计算右侧ListView一页高度的核心代码。其中 rightListStep数组为计算一个分类的高度,为单独计算。
_rightOffSetStepList 在后续循环会使用rightListStep中的代码进行累加,这里实现的是点击左右ListView分类标题的时候,需要右侧跳转的高度,点击跳转的代码为:
_rightListController.animateTo(_rightOffSetStepList[index], duration: const Duration(milliseconds: 500), curve: Curves.easeIn);
_lastGridHeight为最后一项中SizedBox需要填充的高度,以避免最后一项不能被滑动上去的尴尬。
演示:
Comments NOTHING