簡體   English   中英

如何讓 Flutter GridView 在點擊時改變顏色

[英]How to make Flutter GridView change colors when tapped

我以前問過這個問題,但我沒有得到太多幫助。 我使用 GridView.count 創建了一個 GridView; 但是,我無法獲得一個單獨的容器來更改顏色。 如果我單擊行中的任何容器,整行都會發生變化。 我希望能夠在點擊單個容器時更改它的顏色,並在選中時在容器的右上角顯示復選標記。

(1)我的布局

(2)我想發生的事情的一個例子

我對 Flutter 很陌生,所以我的代碼不是很優化。 我也嘗試過制作列表模型,但我沒有任何運氣。 我附上了我的一部分代碼來展示我到目前為止所做的事情。 任何幫助都會很棒:)

Widget build(BuildContext) {
    double _height = MediaQuery.of(context).size.height;
    final data = ModalRoute.of(context)!.settings;

    String retrieveString;

    if (data.arguments == null) {
      retrieveString = "empty";
    } else {
      retrieveString = data.arguments as String;
    }

    return Scaffold(
      resizeToAvoidBottomInset: false,

      backgroundColor: const Color(0xff31708c),

      body: Padding(
        padding: EdgeInsets.only(
          left: 30,
          right: 30,
          top: _height * 0.2),
          child: Column(
            children: <Widget>[
              Text('Hi $retrieveString! What all would you like to focus on?',
              style: GoogleFonts.montserrat(
                color: Colors.white70,
                fontSize: 19,
                fontWeight: FontWeight.w600
              ),
              textAlign: TextAlign.center,),
              const SizedBox(height: 9),
              Text("You can pick all that apply:",
              style: GoogleFonts.montserrat(
                color: Colors.white70,
                fontSize: 14.5,
                fontWeight: FontWeight.w600
              ),),
              const SizedBox(height: 9,),
                Column(children: [
                GridView.count(
                  primary: true,
                  shrinkWrap: true,
                  padding: const EdgeInsets.all(10),
                  childAspectRatio: 1.15,
                  crossAxisCount: 2,
                  crossAxisSpacing: 25,
                  mainAxisSpacing: 25,
                  children: <Widget>[
                    GestureDetector(
                      onTap: () {
                        setState(() {
                          _ContainerColor = _ContainerColor == Colors.white
                          ? Color(0xffa1d0e6)
                          : Colors.white;
                        });
                      },
                      child: Container(
                        padding: const EdgeInsets.all(8),
                        decoration: BoxDecoration(
                          borderRadius: BorderRadius.circular(15),
                          border: Border.all(
                            color: const Color.fromARGB(255, 20, 83, 106),
                          width: 2.5),
                          color: _ContainerColor
                        ),
                        child: Column(
                          children: [
                            const Align(alignment: Alignment.topCenter,
                            child: Icon(MyFlutterApp.relationships,
                            color: Color(0xff31708c),
                            size: 45,),
                            ),
                            const SizedBox(height: 4,),
                            Text('Maintaining healthy relationships',
                            style: GoogleFonts.montserrat(
                              fontSize: 14,
                              fontWeight: FontWeight.w500,
                              color: const Color(0xff31708c)
                            ),
                            textAlign: TextAlign.center,)
                          ],
                        ),
                      ),
                    ),

我已將您的應用程序創建為測試版本。 您需要做的就是將您的小部件注入//put your widget here!!!!! 部分。 同樣為了現在作為演示進行測試,您可以將代碼粘貼到 dartpad 上並選擇“新建”->“顫振”-> 粘貼代碼: https ://dartpad.dev 在此處輸入圖像描述

import 'package:flutter/material.dart';

const 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,
      ),
      debugShowtappedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: CustomCheckboxGrid(),
        ),
      ),
    );
  }
}

class CustomCheckboxGrid extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _CustomCheckboxGridState();
  }
}

class _CustomCheckboxGridState extends State<CustomCheckboxGrid> {
 
  
 int tapped_index = 0;

List card_names = [
  'Maintaining healthy relationships',
  'Being happier and more content in life',
  'Work life balance',
  'Personal Growth',
  'Stress',
  'Mental health',
];

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: GridView.builder(
      padding: const EdgeInsets.all(16),
      itemCount: card_names.length,
      itemBuilder: (BuildContext context, int index) {
        return buildCard(index);
      },
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
      ),
    ),
  );
}

Widget buildCard(int index) {
  bool tapped = index == tapped_index;
  String current_name = card_names[index];
  return GestureDetector(
    onTap: () {
      setState(() {
        print("Tapped index: ${index}");
        tapped_index = index;
      });
    },
    child: Stack(
      children: <Widget>[
        Padding(
          padding: const EdgeInsets.all(14),
          child: 
            //put your widget here!!!!!
            //-----------------------------------
            Card(
            color: tapped ? Colors.orange : Colors.white,
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(16),
            ),
            child: Container(
              child: Center(child: Text(current_name)),
            ),
          ),
            //-----------------------------------
        ),
        Positioned(
          top: 14,
          right: 14,
          child: Offstage(
            offstage: !tapped,
            child: Container(
              decoration: BoxDecoration(
                  color: Colors.white,
                  border: Border.all(width: 2),
                  shape: BoxShape.circle),
              child: Icon(
                Icons.check,
                color: Colors.green,
              ),
            ),
          ),
        ),
      ],
    ),
  );
}
}

據我了解,您必須允許用戶進行多選,因為該行

您可以選擇所有適用的:

所以這是一個自定義的有狀態小部件,可以幫助您進行多選,您可以在 gridview 中擁有自己的小部件子級。

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

  @override
  State<CustomPage> createState() => _CustomPageState();
}

class _CustomPageState extends State<CustomPage> {
  String retrieveString = "";
  List selectedIndex = [];
  List dataItems = ['India', 'USA', 'Germany'];

  @override
  Widget build(BuildContext context) {
    double height = MediaQuery.of(context).size.height;
    final data = ModalRoute.of(context)!.settings;

    if (data.arguments == null) {
      retrieveString = "empty";
    } else {
      retrieveString = data.arguments as String;
    }

    return Scaffold(
        resizeToAvoidBottomInset: false,
        backgroundColor: const Color(0xff31708c),
        body: Padding(
            padding: EdgeInsets.only(left: 30, right: 30, top: height * 0.2),
            child: Column(children: <Widget>[
              Text('Hi $retrieveString! What all would you like to focus on?'),
              const SizedBox(height: 10),
              const Text("You can pick all that apply:"),
              const SizedBox(height: 10,),
              Expanded(
                child: GridView.builder(
                  scrollDirection: Axis.vertical,
                  primary: true,
                  shrinkWrap: true,
                  padding: const EdgeInsets.all(10),
                  gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                      childAspectRatio: 1.15,
                      crossAxisCount: 2,
                      crossAxisSpacing: 25,
                      mainAxisSpacing: 25),
                  itemCount: dataItems.length,
                  itemBuilder: (context, index) {
                    return GestureDetector(
                      onTap: () {
                        setState(() {
                          if (selectedIndex.contains(index)) {
                            selectedIndex.remove(index);
                          } else {
                            selectedIndex.add(index);
                          }
                        });
                      },
                      child: Stack(
                        alignment: Alignment.topRight,
                        children: [
                          Container(
                            padding: const EdgeInsets.all(8),
                            decoration: BoxDecoration(
                                borderRadius: BorderRadius.circular(15),
                                border: Border.all(
                                    color:
                                        const Color.fromARGB(255, 20, 83, 106),
                                    width: 2.5),
                                color: selectedIndex.contains(index)
                                    ? const Color(0xffa1d0e6)
                                    : Colors.white),
                            child: Center(
                              child: Text(dataItems[index]),
                            ),
                          ),
                          selectedIndex.contains(index)
                              ? Container(
                                  padding: const EdgeInsets.all(10),
                                  child: const CircleAvatar(
                                    child: Icon(Icons.check_outlined),
                                  ),
                                )
                              : Container()
                        ],
                      ),
                    );
                  },
                ),
              )
            ])));
  }
}

希望它能解決你的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM