为什么复选框和开关在ListView中无法正常工作? [英] Why do checkboxes and switches not work properly in ListView?

查看:50
本文介绍了为什么复选框和开关在ListView中无法正常工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用CheckboxlistTiles制作一个应作为白名单使用的页面,但是由于某些原因,点击该复选框后不会改变.我尝试将调试打印放在onChanged内,它会执行,但复选框始终保持不变.当仅使用带尾部复选框的ListTile以及使用开关时,也会发生这种情况,只是只能通过滑动而不是轻击来触发该开关.没有错误信息.扑打医生没有任何异常回报,扑打干净也无济于事.

I tried making a page that should function as a whitelist, with CheckboxlistTiles, but for some reason the checkbox just doesn't change when tapped. i tried putting a debugprint inside the onChanged, and it executes, but the checkbox always stays the same. This also happens when using just a ListTile with a trailing checkbox and when using a switch, except that the switch can only be triggered by swiping, but not tapping. there is no error message. Flutter doctor returns nothing out of the ordinary, and flutter clean doesn't help.

此代码是for循环的一部分,因此whitelistBooleans [i]和whitelistCards列表是ListView的子级.

this code is part of a for loop, hence the whitelistBooleans[i], the whitelistCards list is the ListView's child.

这是完整的代码

import 'package:flutter/material.dart';

import 'package:shared_preferences/shared_preferences.dart';
import 'package:device_apps/device_apps.dart';

void main() => runApp(MaterialApp(
      home: MainPage(),
    ));

class MainPage extends StatefulWidget {
  @override
  _MainPageState createState() => _MainPageState();
}

class _MainPageState extends State<MainPage> with WidgetsBindingObserver {
  void didChangeAppLifecycleState(AppLifecycleState state) {
    whitelistedApps = new List();
    if (state == AppLifecycleState.paused) {
      for (var i = 0; i < whitelistBooleans.length; i++) {
        debugPrint(i.toString());
        if (whitelistBooleans[i] == true) {
          whitelistedApps.add(apps[i]);
        }
      }
      for (var i = 0; i < whitelistedApps.length; i++) {
        whitelistedAppNames[i] = whitelistedApps[i].appName;
      }
      savePrefs(harshnessValue, isOn, whitelistedAppNames);
    }
    if (state == AppLifecycleState.resumed) {}
  }

  static savePrefs(final prefsHarshnessValue, final prefsIsOn,
      final prefsWhitelistedAppNames) async {
    final prefs = await SharedPreferences.getInstance();
    prefs.setDouble('harshnessValue key', prefsHarshnessValue);
    prefs.setBool('isOn key', prefsIsOn);
    prefs.setStringList('whitelistedAppNames key', prefsWhitelistedAppNames);
  }

  static void loadPrefs() async {
    final prefs = await SharedPreferences.getInstance();
    final prefsHarshnessValue = prefs.getDouble('harshnessValue key') ?? 0;
    harshnessValue = prefsHarshnessValue;
    final prefsIsOn = prefs.getBool('isOn key') ?? true;
    isOn = prefsIsOn;
    final prefsWhitelistedAppNames =
        prefs.getStringList('whitelistedAppNames key') ?? null;
    whitelistedAppNames = prefsWhitelistedAppNames;
  }

  static bool isOn = true;
  static double harshnessValue = 0;
  static int harshnessLevel;
  static getHarshnessLevel() {
    harshnessLevel = (harshnessValue * 3).round();
  }

  static List<String> whitelistedAppNames = new List();
  bool rac = false;
  static List apps = new List();
  static List whitelistedApps = new List();
  static List<Widget> whitelistCards = new List();
  static List<bool> whitelistBooleans = new List();
  void initWhitelist() async {
    apps = await DeviceApps.getInstalledApplications(includeAppIcons: true);
    whitelistBooleans = new List(apps.length);
    for (var i = 0; i < apps.length; i++) {
      if (whitelistedAppNames.contains(apps[i].appName)) {
        whitelistBooleans[i] = true;
      } else {
        whitelistBooleans[i] = false;
      }


        setState(() {
          whitelistCards.add(
            Card(
              child: CheckboxListTile(
                value: whitelistBooleans[i],
                secondary: Image.memory(apps[i].icon),
                title: Text(apps[i].appName),
                onChanged: (bool value) {
                  setState(() {
                    whitelistBooleans[i] = value;
                  });
                },
              ),
            ),
          );
        });
    }
  }

  @override
  void initState() {
    WidgetsBinding.instance.addObserver(this);
    loadPrefs();
    getHarshnessLevel();
    super.initState();
  }

  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  Widget build(BuildContext context) {
    initWhitelist();
    return Scaffold(
      body: SafeArea(
        child: Column(
          children: <Widget>[
            Switch(
              value: isOn,
              onChanged: (value) {
                setState(() {
                  isOn = value;
                });
              },
            ),
            Slider(
              divisions: 3,
              onChanged: (newRating) {
                setState(() {
                  harshnessValue = newRating;
                });
                getHarshnessLevel();
              },
              value: harshnessValue,
            ),
            RaisedButton(
              child: Text('whitelist'),
              onPressed: () {
                Navigator.push(
                    context,
                    MaterialPageRoute(
                        builder: (context) => Whitelist()));
              },
            ),
          ],
        ),
      ),
    );
  }
}

class Whitelist extends StatefulWidget {
  @override
  _WhitelistState createState() => _WhitelistState();
}

class _WhitelistState extends State<Whitelist> {
  @override
  void initState() {
    super.initState();
  }

  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView(
        children: _MainPageState.whitelistCards,
      ),
    );
  }
}

推荐答案

pskink在评论中说,使用ListView.builder可以解决此问题.

Using ListView.builder fixes this, as pskink said in the comments.

这篇关于为什么复选框和开关在ListView中无法正常工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆