Flutter 是不是有上下文操作栏,用于从列表视图中选择多个项目

Posted

技术标签:

【中文标题】Flutter 是不是有上下文操作栏,用于从列表视图中选择多个项目【英文标题】:Does flutter have a contextual action bar for selecting multiple item from a list viewFlutter 是否有上下文操作栏,用于从列表视图中选择多个项目 【发布时间】:2019-02-02 18:26:14 【问题描述】:

您好,我正在做一个项目,我需要从列表视图中选择多个项目。我尝试了下面的代码,但问题是,如果我选择一个项目,然后我向上滚动并向下滚动到应该更改该项目的颜色变成白色。如果有解决这些问题的包,请帮助我。欢迎任何帮助或代码。

class MyHomePage extends StatefulWidget 
@override
_MyHomePageState createState() => new _MyHomePageState();
class _MyHomePageState extends State<MyHomePage> 
bool longPressFlag = false;
List<int> indexList = new List();
void longPress() 
setState(() 
  if (indexList.isEmpty) 
    longPressFlag = false;
   else 
    longPressFlag = true;
  
);
@override
Widget build(BuildContext context) 
return new Scaffold(
  body: new ListView.builder(
    itemCount: 3,
    itemBuilder: (context, index) 
      return new CustomWidget(
        index: index,
        longPressEnabled: longPressFlag,
        callback: () 
          if (indexList.contains(index)) 
            indexList.remove(index);
           else 
            indexList.add(index);
          
    longPress();
        ,
      );
      ,),
);
class CustomWidget extends StatefulWidget 
final int index;
final bool longPressEnabled;
final VoidCallback callback;
const CustomWidget(Key key, this.index, this.longPressEnabled,    this.callback) : super(key: key);
@override
_CustomWidgetState createState() => new _CustomWidgetState();

class _CustomWidgetState extends State<CustomWidget> 
bool selected = false;
@override
Widget build(BuildContext context) 
return new GestureDetector(
  onLongPress: () 
    setState(() 
      selected = !selected;
    );
    widget.callback();
  ,
  onTap: () 
    if (widget.longPressEnabled) 
      setState(() 
        selected = !selected;
      );
      widget.callback();
    
  ,
  child: new Container(
    margin: new EdgeInsets.all(5.0),
    child: new ListTile(
      title: new Text("Title $widget.index"),
      subtitle: new Text("Description $widget.index"),
    ),
    decoration: selected? new BoxDecoration(color: Colors.black38, border: new Border.all(color: Colors.black)): new BoxDecoration(),
  ),
);

【问题讨论】:

【参考方案1】:

你应该在你的列表数据中而不是在你的小部件中保持“选择”状态。

类似的东西:

import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:playground/feature_discovery.dart';

void main() 
  timeDilation = 1.0;
  runApp(MaterialApp(home: MyHomePage()));


class MyHomePage extends StatefulWidget 
  @override
  _MyHomePageState createState() => new _MyHomePageState();


class _MyHomePageState extends State<MyHomePage> 
  bool longPressFlag = false;
  List<Element> indexList = new List();
  int selectedCount = 0;
  void longPress() 
    setState(() 
      if (indexList.isEmpty) 
        longPressFlag = false;
       else 
        longPressFlag = true;
      
    );
  

  @override
  Widget build(BuildContext context) 
    for (var i = 0; i < 50; i++) 
      indexList.add(Element(isSelected: false));
    

return new Scaffold(
  appBar: AppBar(
    title: Text("Title"),
    actions: <Widget>[
      Padding(
        padding: const EdgeInsets.only( right: 15.0),
        child: Center(child: Text("$selectedCount")),
      ),
    ],
  ),
  body: new ListView.builder(
    itemCount: 50,
    itemBuilder: (context, index) 
      return new CustomWidget(
        isSelected: indexList[index].isSelected,
        index: index,
        longPressEnabled: longPressFlag,
        callback: () 
          onElementSelected(index);
          if (indexList.contains(index)) 
            indexList.remove(index);
           else 
            indexList.add(Element());
          
          longPress();
        ,
      );
    ,
  ),
);

onElementSelected(int index) 
    setState(() 
      if(indexList[index].isSelected)
        selectedCount--;
      else
        selectedCount++;
      indexList[index].isSelected = !indexList[index].isSelected;
    );
  


class CustomWidget extends StatefulWidget 
  final int index;
  final bool longPressEnabled;
  final VoidCallback callback;
  final bool isSelected;
  const CustomWidget(
      Key key,
      this.index,
      this.longPressEnabled,
      this.callback,
      this.isSelected)
      : super(key: key);
  @override
  _CustomWidgetState createState() => new _CustomWidgetState();


class _CustomWidgetState extends State<CustomWidget> 
  @override
  Widget build(BuildContext context) 
    return new GestureDetector(
      onLongPress: () 
        widget.callback();
      ,
      onTap: () 
        if (widget.longPressEnabled) 
          widget.callback();
        
      ,
      child: new Container(
        margin: new EdgeInsets.all(5.0),
        child: new ListTile(
          title: new Text("Title $widget.index"),
          subtitle: new Text("Description $widget.index"),
        ),
        decoration: widget.isSelected
            ? new BoxDecoration(
                color: Colors.black38,
                border: new Border.all(color: Colors.black))
            : new BoxDecoration(),
      ),
    );
  


class Element 
  Element(this.isSelected);
  bool isSelected;

【讨论】:

谢谢你帮了我很多,让我继续前进。你能给我一些关于如何在应用栏标题中显示所选项目计数的提示吗? 如果它是正确的答案,你应该把它标记为它。 你能告诉我如何获取所选项目的索引 我编辑了回复并添加了您要求的计数器。 谢谢它对我有很大帮助..还有一个问题我如何跟踪所选项目,以便可以完成删除所选项目之类的操作。

以上是关于Flutter 是不是有上下文操作栏,用于从列表视图中选择多个项目的主要内容,如果未能解决你的问题,请参考以下文章

如何在 List 小部件 Flutter 中无上下文导航

Flutter:是不是可以在 main.dart 中实现一次快餐栏,例如,当连接状态发生变化时,用于所有屏幕

自定义进度栏的操作方法

选中列表视图上的复选框时,为啥不激活上下文操作栏?

如何在 Flutter 中实现应用栏操作文本而不是操作图标?

带有上下文操作栏的自定义列表视图上的选定项目