как мне изменить цвет отдельного контейнера, когда они являются частью массива?

#flutter #flutter-layout #gesturedetector #animatedcontainer

#flutter #flutter-layout #gesturedetector #animatedcontainer

Вопрос:

Я пытаюсь выделить цвет GestureDetector при его нажатии, я хочу, чтобы был изменен только цвет контейнера, но мой GestureDetector создается из массива, поэтому, когда я меняю его, все меняется.

Как мне достичь своей цели? тексты в массивах не являются фиксированными и будут увеличиваться или уменьшаться.

примерный пример gif с текущим кодом

 import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          home: MyFloat(),
        );
      }
    }
    
    class MyFloat extends StatefulWidget {
      @override
      _MyFloatState createState() => _MyFloatState();
    }
    
    class _MyFloatState extends State<MyFloat> {
      List<BoxShadow> shadow = customShadow;
      Color color = Colors.green;
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: primaryColor,
          body: SafeArea(
            child: Column(
              children: [
                Wrap(
                  children: [
                    ...(["hello", "hi", "hey"]
                        .map(
                          (val) => GestureDetector(
                            onTap: () {
                              setState(() {
                                this.color == Colors.green
                                    ? this.color = Colors.cyan
                                    : this.color = Colors.green;
                              });
                            },
                            child: AnimatedContainer(
                              duration: Duration(milliseconds: 250),
                              height: 100,
                              width: 100,
                              decoration: BoxDecoration(
                                borderRadius: BorderRadius.circular(20),
                                color: this.color == Colors.green
                                    ? Colors.cyan
                                    : Colors.green,
                              ),
                              child: Center(
                                child: Text(val),
                              ),
                            ),
                          ),
                        )
                        .toList())
                  ],
                )
              ],
            ),
          ),
        );
      }
    }
 

Ответ №1:

Вот конечный результат :

 Map<String,Color> stringColorMap = {           /// Map which maps the text string to its corresponding color
  "hello" : Colors.green,
  "hi" : Colors.green,
  "hey" : Colors.green,
};


class MyFloat extends StatefulWidget {
  @override
  _MyFloatState createState() => _MyFloatState();
}

class _MyFloatState extends State<MyFloat> {

  Color color = Colors.green;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: SafeArea(
        child: Column(
          children: [
            Wrap(
              children: [
                ...(["hello", "hi", "hey"]
                    .map(
                      (val){print("Val : $val"); return GestureDetector(
                    onTap: () {
                      setState(() {
                       /* this.color == Colors.green
                            ? this.color = Colors.cyan
                            : this.color = Colors.green; */

                        if(stringColorMap[val] == Colors.green)
                          stringColorMap[val] = Colors.cyan;
                        else
                          stringColorMap[val] = Colors.green;

                      });
                    },
                    child: AnimatedContainer(
                      duration: Duration(milliseconds: 250),
                      height: 100,
                      width: 100,
                      decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(20),
                        color: stringColorMap[val],
                      ),
                      child: Center(
                        child: Text(val),
                      ),
                    ),
                  );}
                )
                    .toList())
              ],
            )
          ],
        ),
      ),
    );
  }
}
 

Изменения сделаны:

  1. Что я сделал, так это добавил карту, которая сопоставляет текстовую строку с соответствующим цветом. (stringColorMap)
  2. Затем переходим к функции onTap виджета, как вы можете видеть, когда пользователь нажимает на кнопку, он проверяет текущий цвет текста и соответствующим образом меняет цвет.
  3. Затем я использовал цвет соответствующего текста в качестве цвета нашего виджета.

Комментарии:

1. да, это хороший подход, извиняюсь за то, что не прояснил мою проблему, тексты в массивах не фиксированы и будут увеличиваться или уменьшаться. в таком случае есть какие-либо предложения?

2. Вы можете соответствующим образом изменить значения в вашей карте. Тогда вместо использования жестко запрограммированного списка строк ([«привет», «привет»,»привет»]) в дочернем параметре Wrap, вы можете использовать значения, присутствующие в самой карте. Тогда список в вашем пользовательском интерфейсе изменится в соответствии с изменениями, внесенными в карту. Создайте функцию, в которой вы будете обновлять stringColorMap и вызывать setState .