【问题标题】:Change the color of the container when clicked on it in my flutter app在我的颤振应用程序中单击容器时更改容器的颜色
【发布时间】:2020-05-24 22:07:44
【问题描述】:

我通过 API 获取了一些兴趣(数据),并使用未来的构建器作为容器来展示它们。我想在单击它时更改容器的背景颜色。这是我所做的,当我点击一个容器时,它改变了所有容器的背景颜色。

我在容器的颜色中添加了一个if条件来检查它是否被点击

颜色:被点击? Colors.white:颜色(0xFFFFEBE7),

并在单击时将 isClicked 状态设置为 true。

bool isClicked = false;

FutureBuilder(
                      future: GetInterests.getInterests(),
                      builder: (context, snapshot) {
                        final datalist = snapshot.data;
                        if (snapshot.connectionState ==
                            ConnectionState.done) {
                          return Expanded(
                            child: SizedBox(
                              height: 35,
                              child: ListView.builder(
                                scrollDirection: Axis.horizontal,
                                itemBuilder: (context, index) {
                                  return Wrap(
                                    direction: Axis.vertical,
                                    children: <Widget>[
                                      GestureDetector(
                                        onTap: (){
                                          final inte_id =  "${datalist[index]['_id']}";
                                          log(inte_id);
                                          
                                          setState(() {
                                            isClicked = true;
                                          });
                                        },
                                        child: new Container(
                                          margin: EdgeInsets.only(right: 7),
                                          height: 30,
                                          width: MediaQuery.of(context)
                                                  .size
                                                  .width /
                                              5.2,
                                          decoration: BoxDecoration(
                                              color: isClicked? Colors.white : Color(0xFFFFEBE7),
                                              border: Border.all(
                                                  color: Color(0xFFE0E0E0)),
                                              borderRadius:
                                                  BorderRadius.only(
                                                      topLeft:
                                                          Radius.circular(
                                                              50.0),
                                                      topRight:
                                                          Radius.circular(
                                                              50.0),
                                                      bottomRight:
                                                          Radius.circular(
                                                              50.0),
                                                      bottomLeft:
                                                          Radius.circular(
                                                              0.0))),
                                          child: Center(
                                            child: Text(
                                              "${datalist[index]['iname']}",
                                              style: TextStyle(
                                                  fontFamily: 'Montserrat',
                                                  color: Color(0xFFFF5E3A),
                                                  fontSize: 13),
                                            ),
                                          ),
                                        ),
                                      ),
                                    ],
                                  );
                                },
                                itemCount: datalist.length,
                              ),
                            ),
                          );
                        }
                        return Padding(
                          padding: const EdgeInsets.only(left: 140.0),
                          child: Center(
                            child: CircularProgressIndicator(),
                          ),
                        );
                      },
                    )

我能够在属于我单击的容器的控制台中打印兴趣 ID。但不知道如何只改变它的颜色

【问题讨论】:

标签: flutter


【解决方案1】:

虽然公认的答案会起作用,但在某些人看来,使用 ChangeNotifier 和包提供程序的更复杂的架构将产生更松散耦合、更好的代码。

结合以下想法

我专注于架构和数据流。不在小部件布局上以匹配原始问题的屏幕截图。

import 'dart:collection';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:provider/provider.dart';

// Model ---------------------------------------------------

class Interest with ChangeNotifier {
  final String title;
  bool _selected = false;

  Interest({
    @required this.title,
  }) : assert(title != null);

  factory Interest.fromMap(final Map<String, dynamic> map) {
    return Interest(
      title: map['title'],
    );
  }

  bool get selected {
    return this._selected;
  }

  void select() {
    this._selected = true;
    this.notifyListeners();
  }

  void toggleSelect() {
    this._selected = !this._selected;
    this.notifyListeners();
  }
}

class Interests extends ChangeNotifier {
  final List<Interest> _interests = <Interest>[];

  Interests();

  factory Interests.fromList(final List<Map<String, dynamic>> list) {
    final Interests interests = Interests();
    for (final Map<String, dynamic> map in list) {
      interests.add(Interest.fromMap(map));
    }
    return interests;
  }

  int get length {
    return this._interests.length;
  }

  Interest operator [](final int index) {
    return this._interests[index];
  }

  UnmodifiableListView<Interest> get interests {
    return UnmodifiableListView<Interest>(this._interests);
  }

  void add(final Interest interest) {
    this._interests.add(interest);
    this.notifyListeners();
  }

  void selectAll() {
    for (final Interest interest in this._interests) {
      interest.select();
    }
  }
}

// Services ------------------------------------------------

Future<Interests> fetchInterests() async {
  // Some data source that has a list of objects with titles.
  final response = await http.get('https://jsonplaceholder.typicode.com/posts');
  if (response.statusCode == 200) {
    return Interests.fromList(json.decode(response.body).cast<Map<String, dynamic>>());
  } else {
    throw Exception('Failed to load post');
  }
}

// User Interface ------------------------------------------

void main() {
  runApp(InterestsApp());
}

class InterestsApp extends StatelessWidget {
  @override
  Widget build(final BuildContext context) {
    return MaterialApp(
      title: 'Interests App',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: InterestsPage(),
    );
  }
}

class InterestsPage extends StatelessWidget {
  @override
  Widget build(final BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Interests')),
      body: InterestsBody(),
    );
  }
}

class InterestsBody extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _InterestsBodyState();
  }
}

class _InterestsBodyState extends State<InterestsBody> {
  Future<Interests> _futureInterests;

  @override
  void initState() {
    super.initState();
    this._futureInterests = fetchInterests();
  }

  @override
  Widget build(final BuildContext context) {
    return FutureBuilder<Interests>(
      future: this._futureInterests,
      builder: (final BuildContext context, final AsyncSnapshot<Interests> snapshot) {
        if (snapshot.hasData) {
          return ChangeNotifierProvider.value(
            value: snapshot.data,
            child: InterestsList(),
          );
        } else if (snapshot.hasError) {
          return Center(child: Text("${snapshot.error}"));
        }
        return Center(child: CircularProgressIndicator());
      },
    );
  }
}

class InterestsList extends StatelessWidget {
  @override
  Widget build(final BuildContext context) {
    return Consumer<Interests>(
      builder: (final BuildContext context, final Interests interests, final Widget child) {
        return Column(
          children: <Widget>[
            Center(
              child: RaisedButton(
                child: Text("Select All"),
                onPressed: () {
                  interests.selectAll();
                },
              ),
            ),
            Expanded(
              child: ListView.builder(
                itemCount: interests.length,
                itemBuilder: (final BuildContext context, final int index) {
                  return ChangeNotifierProvider<Interest>.value(
                    value: interests[index],
                    child: InterestTile(),
                  );
                },
              ),
            ),
          ],
        );
      },
    );
  }
}

class InterestTile extends StatelessWidget {
  @override
  Widget build(final BuildContext context) {
    return Consumer<Interest>(
      builder: (final BuildContext context, final Interest interest, final Widget child) {
        return ListTile(
          title: Text(interest.title),
          trailing: interest.selected ? Icon(Icons.check) : null,
          onTap: () {
            interest.toggleSelect();
          },
        );
      },
    );
  }
}

【讨论】:

  • 很好的解释。请问将网络调用抽象到存储库中,然后在 ChangeNotifier 子类中调用存储库是否是一种好习惯?
【解决方案2】:

您可以使用变量来存储 selectedIndex 并检查是否选择了 currentIndex 并比较是否选择了 currentIndex 并设置所选小部件的样式。

   import 'package:flutter/material.dart';

final Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: MyWidget(),
        ),
      ),
    );
  }
}


class MyWidget extends StatefulWidget {

  _MyWidgetState createState()=>_MyWidgetState();

}
class _MyWidgetState extends State<MyWidget>{
  List _selectedIndexs=[];
    @override
  Widget build(BuildContext context) {

    return ListView.builder(
      itemCount: 4,
      itemBuilder: (ctx,i){
        final _isSelected=_selectedIndexs.contains(i);
        return GestureDetector(
          onTap:(){
            setState((){
               if(_isSelected){
                 _selectedIndexs.remove(i);                

               }else{
                 _selectedIndexs.add(i);

               }
            });
          },
          child:Container(
          color:_isSelected?Colors.red:null,
          child:ListTile(title:Text("Khadga")),
        ),
        );
      }
    );

}


}

像我在上述情况下所做的那样修改您的列表视图构建器。

【讨论】:

  • 非常感谢你们俩……它成功了……再次感谢你们!!
  • 为我工作谢谢+1!
【解决方案3】:

您也可以使用颤振芯片或ActionChip或ChoiceChip

    class MyThreeOptions extends StatefulWidget {
  @override
  _MyThreeOptionsState createState() => _MyThreeOptionsState();
}

class _MyThreeOptionsState extends State<MyThreeOptions> {
  int? _value = 1;

  @override
  Widget build(BuildContext context) {
    return Wrap(
      children: List<Widget>.generate(
        3,
        (int index) {
          return ChoiceChip(
            label: Text('Item $index'),
            selected: _value == index,
            onSelected: (bool selected) {
              setState(() {
                _value = selected ? index : null;
              });
            },
          );
        },
      ).toList(),
    );
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-02
    • 2020-09-25
    • 1970-01-01
    • 2023-01-19
    • 2019-07-10
    • 1970-01-01
    相关资源
    最近更新 更多