颤振如何保存可重新订购包装的位置?

Nitneuq

我尝试了可重排序软件包https://pub.dev/packages/reorderables我成功移动了仪表板块,但是当我重新启动应用程序时,我的移动被删除了。

因此,解决方案只能是sharedpref解决方案。但我没有找到如何保存此信息

我试图保存并加载newIndex,但是没有成功,我试图保存并加载List _tiles; 但是sharedpref无法保存列表

这是我的代码示例

List<Widget> _tiles;
  void _onReorder(int oldIndex, int newIndex) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();

    setState(() {

      Widget row = _tiles.removeAt(oldIndex);
      _tiles.insert(newIndex, row);


      //prefs.setListWidget('indexList', _tiles);  not working
    //  prefs.setInt('index', newIndex );  not working


    });
  }


  @override
  void initState() {
    super.initState();

    _tiles = <Widget>[
//my widget1
//my widget2
//my widget3

//my widget4
//my widget5
//my widget6

//my widget7
//my widget8
//my widget9

]
 }


  @override
  Widget build(BuildContext context) {



    return Column(
      crossAxisAlignment: CrossAxisAlignment.center,
      children: <Widget>[
     ReorderableWrap(
     spacing: 0.0,
     runSpacing:0,
     maxMainAxisCount: 3,
     minMainAxisCount: 3,
     padding: const EdgeInsets.all(5),
      children:_tiles,

        onReorder: _onReorder,
        onNoReorder: (int index) {
          //this callback is optional
          debugPrint('${DateTime.now().toString().substring(5, 22)} reorder cancelled. index:$index');
        },
        onReorderStarted: (int index) {
          //this callback is optional
          debugPrint('${DateTime.now().toString().substring(5, 22)} reorder started: index:$index');
        }
    )
    ]
    );
  }
}

编辑:这是小部件1。其他小部件相同

  new Container (
        width: SizeConfig.safeBlockHorizontal * 32,
        height: 160,

        child :
        new Card(
            elevation: 8,
            shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
            color: Colors.white,
            child:
            Ink(

              child: InkResponse(
                  splashFactory: InkRipple.splashFactory,
                  radius: 100,
                  onTap: () {

                  },
                  child:
                  Padding(
                      padding: const EdgeInsets.only(top:10),
                      child:
                      new     Container(

                        padding: const EdgeInsets.all(0),
                        child :

                        new Column(
                          mainAxisAlignment: MainAxisAlignment.start,
                          crossAxisAlignment: CrossAxisAlignment.center,
                          children: <Widget>[

                            new     Container(
                              height:25,

                              child :


                              new Row(
                                  mainAxisAlignment: MainAxisAlignment.center,
                                  crossAxisAlignment: CrossAxisAlignment.center,
                                  children: <Widget>[

                                    Icon(Icons.keyboard_arrow_right, color: Colors.white, size: 15.0),

                                    Text('Planning',textAlign:TextAlign.center, style: TextStyle(
                                        color: Colors.black,
                                        fontWeight: FontWeight.w500,
                                        fontSize: SizeConfig.safeBlockHorizontal * 4),
                                    ),
                                    Icon(Icons.keyboard_arrow_right, color: Colors.grey, size: 15.0),
                                  ]
                              ),
                            ),


                            Padding(
                              padding: const EdgeInsets.all(5),),
                            Icon(Icons.event_available, color:Color(0xffff9a7b), size: 70.0),


                          ],
                        ),
                      ))
              ),
            )),
      )

这是我的设计

在此处输入图片说明

编辑#2

现在,我试图在模型中添加资产,但是我不知道该怎么做

void initState() {
    // default models list
    models = [

      Model(index: 0, new Container (
          width:90,
          height: 90,
          child :new FlareActor("assets/pierre.flr", alignment:Alignment.center, fit:BoxFit.contain, animation:"pierre")
      ), title: 'Coach'),

      Model(index: 1, new Image.asset(
        "assets/cup.png",
        width: 50,
      ), title: 'Victories'),

      Model(index: 2, icon: Icon(Icons.card_giftcard), title: 'Jeux'),
      Model(index: 3, icon: Icon(Icons.wb_sunny), title: 'Sunny'),
      Model(index: 4, icon: Icon(Icons.cloud), title: 'Cloud'),
      Model(index: 5, icon: Icon(Icons.tv), title: 'TV'),
      Model(index: 6, icon: Icon(Icons.place), title: 'Location'),
      Model(index: 8, icon: Icon(Icons.music_note), title: 'Music'),
      // More customization
      Model(
          index: 7,
          icon: Icon(Icons.event_available, color: Color(0xffff9a7b)),
          title: 'Planning'),
    ];
    config();
    super.initState();
  }
NoobN3rd

这个解决方案不是一个很好的解决方案,我不喜欢它,但是它可行:D

I really appreciate it if anyone would refer a better one

Maybe for this project, it's good to use DB instead of SharedPreferences but here I used SharedPreferences.

The question is how to save the order of some widget(each time on reordering, the order of widget changes and we want to save the order of them, after restarting the app the saved order should be fetched).

SharedPreferences can also save a list of string, so what I did here was:

In the beginning, there should be a default list, that contains the initial order of widget's of the app.

Because widgets are somehow the same and only some of their info is different, I decided to define a model and work with models, instead of a whole complicated widget, I mean when I want to remove or change indexes I do it for a list of models rather than a list of widgets.

Here I supposed the model only contains a title, I also defined an index for it, so all I do is that when I reorder the widget, it reorders the list of models, to save the order, I save the index of models in any order they are now,

for example, if the initial order was [0, 1, 2, 3] let's say after reordering it's now [3, 0, 1, 2], I save this order, and for the next boot, I fetch the saved order([3, 0, 1, 2]) and then reorder the default list based on this fetched order.

Another solution would be to change the model's index and then show an ordered list of models based on their index.

Here is the code:

import 'package:flutter/material.dart';
import 'package:reorderables/reorderables.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() => runApp(
      MaterialApp(
        home: Scaffold(
          body: Center(
            child: Page(),
          ),
        ),
      ),
    );

class Page extends StatefulWidget {
  const Page({Key key}) : super(key: key);

  @override
  _PageState createState() => _PageState();
}

class _PageState extends State<Page> {
  SharedPreferences prefs;

  List<Model> models;
  @override
  void initState() {
    // default models list
    models = [
      Model(index: 0, title: 'Item 0'),
      Model(index: 1, title: 'Item 1'),
      Model(index: 2, title: 'Item 2'),
      Model(index: 3, title: 'Item 3'),
    ];
    config();
    super.initState();
  }

  void config() async {
    // Here we reset the default model based on  saved order
    await SharedPreferences.getInstance().then((pref) {
      prefs = pref;
      List<String> lst = pref.getStringList('indexList');

      List<Model> list = [];
      if (lst != null && lst.isNotEmpty) {
        list = lst
            .map(
              (String indx) => models
                  .where((Model item) => int.parse(indx) == item.index)
                  .first,
            )
            .toList();
        models = list;
      }
      setState(() {});
    });
  }

  void _onReorder(int oldIndex, int newIndex) async {
    Model row = models.removeAt(oldIndex);
    models.insert(newIndex, row);
    setState(() {
      prefs.setStringList(
          'indexList', models.map((m) => m.index.toString()).toList());
    });
  }

  @override
  Widget build(BuildContext context) {
    return ReorderableWrap(
        scrollDirection: Axis.vertical,
        direction: Axis.vertical,
        spacing: 0.0,
        runSpacing: 0,
        maxMainAxisCount: 3,
        minMainAxisCount: 3,
        padding: const EdgeInsets.all(5),
        children: models
            .map((m) => Card(
                  child: Container(
                    child: Text('${m.index} - ${m.title}'),
                    padding: EdgeInsets.all(24.0),
                  ),
                ))
            .toList(),
        onReorder: _onReorder,
        onNoReorder: (int index) {
          //this callback is optional
          debugPrint('${DateTime.now().toString().substring(5, 22)} ' +
              'reorder cancelled. index:$index');
        },
        onReorderStarted: (int index) {
          //this callback is optional
          debugPrint('${DateTime.now().toString().substring(5, 22)} ' +
              'reorder started: index:$index');
        });
  }
}

class Model {
  int index;
  String title;

  Model({this.index, this.title});

  @override
  String toString() {
    return '$index : $title';
  }
}

Changes After Edit to the main question:

This version is based on the editing to the main question, I decided to keep the first answer unchanged because it's a more simple version and may help another viewer.

For the new model, as far as I could get, it has an icon, title, and an onTap functionality, I changed the model to have icon and title, but for the onTap, I wrote my own card version that gets a model and onTap functionality, I could add onTap to the model, but I thought it's better for future use or to use in other places, so I separated the onTap from the model, I also chose Icon for the model, it could be IconData (benefit of IconData is that you can choose customization for each icon and etc).

On my Card version (MyCard), I simply used a GestureDetector and Card to simulate the taps and card.

I wrote a FakePage that gets a model and if you Tap on each card it navigates to this page and shows some message based on the received model.

要在中清理先前保存的模型SharedPreferences,您应该注释提取模型顺序的零件,config()并在下次刷新时,再次取消注释。

这是新版本的代码:

import 'package:flutter/material.dart';
import 'package:reorderables/reorderables.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() => runApp(
      MaterialApp(
        home: Scaffold(
          body: Center(
            child: Page(),
          ),
        ),
      ),
    );

class Page extends StatefulWidget {
  const Page({Key key}) : super(key: key);

  @override
  _PageState createState() => _PageState();
}

class _PageState extends State<Page> {
  SharedPreferences prefs;

  List<Model> models;
  @override
  void initState() {
    // default models list
    models = [
      Model(index: 0, icon: Icon(Icons.people), title: 'Coach'),
      Model(index: 1, icon: Icon(Icons.wb_incandescent), title: 'Victories'),
      Model(index: 2, icon: Icon(Icons.card_giftcard), title: 'Jeux'),
      Model(index: 3, icon: Icon(Icons.wb_sunny), title: 'Sunny'),
      Model(index: 4, icon: Icon(Icons.cloud), title: 'Cloud'),
      Model(index: 5, icon: Icon(Icons.tv), title: 'TV'),
      Model(index: 6, icon: Icon(Icons.place), title: 'Location'),
      Model(index: 8, icon: Icon(Icons.music_note), title: 'Music'),
      // More customization
      Model(
          index: 7,
          icon: Icon(Icons.event_available, color: Color(0xffff9a7b)),
          title: 'Planning'),
    ];
    config();
    super.initState();
  }

  void config() async {
    // Here we reset the default model based on  saved order
    await SharedPreferences.getInstance().then((pref) {
      prefs = pref;
      List<String> lst = pref.getStringList('indexList');

      List<Model> list = [];
      if (lst != null && lst.isNotEmpty) {
        list = lst
            .map(
              (String indx) => models
                  .where((Model item) => int.parse(indx) == item.index)
                  .first,
            )
            .toList();
        models = list;
      }
      setState(() {});
    });
  }

  void _onReorder(int oldIndex, int newIndex) async {
    Model row = models.removeAt(oldIndex);
    models.insert(newIndex, row);
    setState(() {
      prefs.setStringList(
          'indexList', models.map((m) => m.index.toString()).toList());
    });
  }

  @override
  Widget build(BuildContext context) {
    return ReorderableWrap(
        spacing: 0.0,
        runSpacing: 0,
        maxMainAxisCount: 3,
        minMainAxisCount: 3,
        padding: const EdgeInsets.all(5),
        children: <Widget>[
          MyCard(
            model: models[0],
            onTap: () => Navigator.of(context).push(
              MaterialPageRoute(
                builder: (BuildContext context) => FakePage(model: models[0]),
              ),
            ),
          ),
          MyCard(
            model: models[1],
            onTap: () => Navigator.of(context).push(
              MaterialPageRoute(
                builder: (BuildContext context) => FakePage(model: models[1]),
              ),
            ),
          ),
          MyCard(
            model: models[2],
            onTap: () => Navigator.of(context).push(
              MaterialPageRoute(
                builder: (BuildContext context) => FakePage(model: models[2]),
              ),
            ),
          ),
          MyCard(
            model: models[3],
            onTap: () => Navigator.of(context).push(
              MaterialPageRoute(
                builder: (BuildContext context) => FakePage(model: models[3]),
              ),
            ),
          ),
          MyCard(
            model: models[4],
            onTap: () => Navigator.of(context).push(
              MaterialPageRoute(
                builder: (BuildContext context) => FakePage(model: models[4]),
              ),
            ),
          ),
          MyCard(
            model: models[5],
            onTap: () => Navigator.of(context).push(
              MaterialPageRoute(
                builder: (BuildContext context) => FakePage(model: models[5]),
              ),
            ),
          ),
          MyCard(
            model: models[6],
            onTap: () => Navigator.of(context).push(
              MaterialPageRoute(
                builder: (BuildContext context) => FakePage(model: models[6]),
              ),
            ),
          ),
          MyCard(
            model: models[7],
            onTap: () => Navigator.of(context).push(
              MaterialPageRoute(
                builder: (BuildContext context) => FakePage(model: models[7]),
              ),
            ),
          ),
          MyCard(
            model: models[8],
            onTap: () => Navigator.of(context).push(
              MaterialPageRoute(
                builder: (BuildContext context) => FakePage(model: models[8]),
              ),
            ),
          ),
        ],
        onReorder: _onReorder,
        onNoReorder: (int index) {
          //this callback is optional
          debugPrint('${DateTime.now().toString().substring(5, 22)} ' +
              'reorder cancelled. index:$index');
        },
        onReorderStarted: (int index) {
          //this callback is optional
          debugPrint('${DateTime.now().toString().substring(5, 22)} ' +
              'reorder started: index:$index');
        });
  }
}

// ---------------------- Model --------------------------
class Model {
  int index;
  String title;
  Icon icon;
  Model({this.index, this.title, this.icon});

  @override
  String toString() {
    return '$index : $title';
  }
}

// ------------------------ MyCard ----------------------------
class MyCard extends StatelessWidget {
  final Model model;
  final void Function() onTap;

  const MyCard({Key key, this.onTap, @required this.model})
      : assert(model != null),
        super(key: key);

  @override
  Widget build(BuildContext context) {
    double width = MediaQuery.of(context).size.width;
    return GestureDetector(
      onTap: onTap,
      child: Card(
        elevation: 8.0,
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
        child: _child(width),
      ),
    );
  }

  Widget _child(double width) {
    return Container(
      width: width / 4,
      height: width / 3,
      margin: EdgeInsets.all(5.0),
      child: Column(
        mainAxisSize: MainAxisSize.max,
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: <Widget>[
          Expanded(
            flex: 3,
            child: Row(
              mainAxisSize: MainAxisSize.max,
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: <Widget>[
                Text(
                  model.title,
                  maxLines: 1,
                  textAlign: TextAlign.center,
                  style: TextStyle(
                    color: Colors.black,
                    fontWeight: FontWeight.w500,
                    fontSize: 15.0,
                  ),
                  overflow: TextOverflow.ellipsis,
                ),
                Icon(
                  Icons.arrow_forward_ios,
                  color: Colors.grey.shade400,
                  size: 15.0,
                ),
              ],
            ),
          ),
          Expanded(
            flex: 5,
            child: Padding(
              padding: EdgeInsets.all(8.0),
              child: FittedBox(
                fit: BoxFit.contain,
                child: model.icon,
              ),
            ),
          ),
        ],
      ),
    );
  }
}

// ----------------------- FAKE PAGE ---------------------------
class FakePage extends StatelessWidget {
  final Model model;
  const FakePage({Key key, this.model}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.deepOrangeAccent,
      ),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.max,
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            Text(
              'You Clicked on Card : ${model.title}',
              style: TextStyle(fontSize: 20.0),
            ),
            Padding(
              padding: EdgeInsets.only(top: 24.0),
              child: Icon(
                model.icon.icon,
                size: 70.0,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

颤振 - 如何在颤振中保存状态选定的单选按钮列表?

来自分类Dev

颤振位置网格元素

来自分类Dev

如何禁用颤振开关

来自分类Dev

颤振中的可滚动列

来自分类Dev

颤振-位置参数过多

来自分类Dev

使用颤振的设备定期位置报告

来自分类Dev

颤振如何从异步功能获取数据

来自分类Dev

颤振-点击/触摸区域如何工作?

来自分类Dev

如何比较颤振中的时间?

来自分类Dev

如何用颤振罗盘找到方向?

来自分类Dev

如何在颤振中断开电话?

来自分类Dev

如何使容器在颤振中垂直居中?

来自分类Dev

颤振,阴影裁剪系统如何工作?

来自分类Dev

如何正确固定颤振中的行距

来自分类Dev

如何在颤振中管理状态?

来自分类Dev

如何在颤振中绘制扇区?

来自分类Dev

颤振力重新格式化输入

来自分类Dev

在颤振中重新创建此布局

来自分类Dev

哪个动画适合颤振中的可扩展容器?

来自分类Dev

颤振:使ListView在底部反弹,并在顶部位置夹紧

来自分类Dev

颤振右上角更改文本位置

来自分类Dev

如何重新包装JPEG?

来自分类Dev

单击颤振附加按钮后,无法重新加载或重新启动

来自分类Dev

颤振如何按az或za排序lisy

来自分类Dev

如何删除ReorderableListView底部的多余间距-颤振?

来自分类Dev

如何在振颤中从List <int>再现音频?

来自分类Dev

如何计算颤振中的字符串列表的总和?

来自分类Dev

颤振如何在按下后执行功能

来自分类Dev

颤振:如何删除gridview单元格的背景?