Json 데이터 예시

[
    {
        "uid" : 1,
        "thumbnail": "assets/images/1.jpg",
        "title" : "꼬북좌 이미지1",
        "description" : "남심 '저격'브레이브걸스 유정 근황"
    },
    {
        "uid" : 2,
        "thumbnail": "assets/images/2.jpg",
        "title" : "꼬북좌 이미지2",
        "description" : "브레이브걸스 꼬북좌 유정 사진짤 방출"
    },
    {
        "uid" : 3,
        "thumbnail": "assets/images/3.jpg",
        "title" : "꼬북좌 이미지3",
        "description" : "예상치 못한 인스타에 팬들 반응 난리났다."
    },
    {
        "uid" : 4,
        "thumbnail": "assets/images/4.jpg",
        "title" : "꼬북좌 이미지4",
        "description" : "꼬북좌 인스타 이미지"
    },
    {
        "uid" : 5,
        "thumbnail": "assets/images/5.jpg",
        "title" : "진짜 꼬부기",
        "description" : "진짜 꼬부기 이미지"
    }
]

GetxController를 상속 받아 Json 데이터를 가져오는 컨트롤러

class JsonLoader extends GetxController {
  static JsonLoader get to => Get.find();
  var list = <Map<String, dynamic>>[].obs;
  @override
  void onInit() async {
    super.onInit();
    _loadJsonFile();
  }

  void _loadJsonFile() async {
    if (Get.context != null) {
      String data = await DefaultAssetBundle.of(Get.context!)
          .loadString("assets/json/post.json");
      list(json.decode(data).cast<Map<String, dynamic>>().toList());
    } else {
      Future.delayed(Duration(milliseconds: 200), _loadJsonFile);
    }
  }
}

SingleChildScrollView로 GetX의 Obx로 Json 데이터 리스트 위젯 만들기

SingleChildScrollView(
  child: Obx(
    () => Column(
      children: List.generate(
        JsonLoader.to.list.length,
        (index) {
        // 부모에서 JsonLoader binding
        // 컨트롤러에서 만든 리스트를 post에 저장
          var post = JsonLoader.to.list[index]
              .map<String, String>((key, value) {
            return MapEntry(key.toString(), value.toString());
          });
          return PostWidget(
            uid: post['uid']!,
            thumbnail: post['thumbnail']!,
            title: post['title']!,
            description: post['description']!,
            callBack: () {
            // detail 페이지로 이동시 파라미터로 해당 위젯의 post 넘겨줌
              Get.toNamed('/detail', parameters: post);
            },
          );
        },
      ),
    ),
  ),
)

리스트의 아이템 만들기

typedef PostClickFunction = void Function();

class PostWidget extends StatelessWidget {
  final String uid;
  final String thumbnail;
  final String title;
  final String description;
  final PostClickFunction callBack;

  const PostWidget(
      {required this.uid,
      required this.thumbnail,
      required this.title,
      required this.description,
      required this.callBack});

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: callBack,
      child: Container(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Image.asset(thumbnail),
            Padding(
              padding: const EdgeInsets.only(
                  top: 10, bottom: 20, left: 10, right: 10),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: [
                  Text(
                    title,
                    style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold),
                  ),
                  Text(
                    description,
                    style: TextStyle(
                      fontSize: 12,
                    ),
                  )
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

callback을 통해 디테일 페이지로 이동

리스트 위젯의 callback 부분에 Get.toNamed로 최상단에 지정한 라우팅 주소 넣고, 파라미터로 데이터 넘겨주기

GetxController를 통해 파라미터 받아오기

class TextAnimation extends GetxController {
  Map<String, String?>? post;

  @override
  void onInit() {
    super.onInit();
    _loadData();
  }

  void _loadData() {
    post = Get.parameters;
  }
}

위에서 만든 GetxController 형식의 GetView를 상속받아 파라미터의 데이터 가져오기

class PostDetailView extends GetView<TextAnimation> {
  const PostDetailView();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(controller.post!['title']!),
      ),
      body: Column(
        children: [
          Image.asset(controller.post!['thumbnail']!),
          Column(
            children: [
              Text(
                controller.post!['title']!,
              ),
              Text(
                controller.post!['description']!,
              ),
            ],
          ),
        ],
      ),
    );
  }
}
728x90

+ Recent posts