DevBoi

[Flutter] TabBar 구현 및 위젯 간 데이터 생성자 본문

[Mobile]/[Flutter]

[Flutter] TabBar 구현 및 위젯 간 데이터 생성자

HiSmith 2023. 8. 23. 23:54
반응형

플러터의 데이터 개념은 조금 복잡하다

자바에 익숙한 나로서는, 순차처리나 동기식 처리가 익숙한데,

플러터는 모든 변수에 Nullable한 처리를 해줘야 하고, 위젯간의 데이터를 넘길때도

잘못처리하게 되면, 빈값이 넘어가게 된다.

이는 비동기식으로 값을 추출하는 것 때문에 발생되는게 주로 이유인데, 아래 소스를 보자

 

기존에는 아래와 같이 코딩되어 변수 초기화 시점의 이슈가 많았고, 

 

const Friend(String userId){
this.userId;
}

Friend(userId);

아래 처럼 바꿨다.

class RecommendFriend extends StatefulWidget {
  final String userId;
  RecommendFriend({required this.userId});

  @override
  _RecommendFriendState createState() => _RecommendFriendState(userId);
}



RecommendFriend(userId: userId),

 

이런식으로 해야, 초기화 시점이 생성자 시점과 동일해진다.

사소할 수 있는 문제이지만 확인이 필요하다.

 

다음 Tabbar 구현 이다. 패키지 구조는 아래와 같다.

 

Friend-home은 탭 바가 담긴 화면이다.

import 'package:flutter/material.dart';
import 'package:goodshot/view/friend/screen/my-friend.dart';

import 'screen/recommend-friend.dart';

class FriendHomeTabBarApp extends StatefulWidget {
  final String userId;

  FriendHomeTabBarApp({required this.userId});
  @override
  _FriendHomeTabBar createState() => _FriendHomeTabBar(userId: userId);
}

class _FriendHomeTabBar extends State<FriendHomeTabBarApp> {
  final String userId;
  _FriendHomeTabBar({required this.userId});

  @override
  Widget build(BuildContext context) {

    return DefaultTabController(
      initialIndex: 0,
      length: 2,
      child: Scaffold(
        appBar: AppBar(

          title: const TabBar(
            tabs: <Widget>[
              Tab(
                icon: Text("추천 친구"),
              ),
              Tab(
                icon: Text("나의 친구"),
              ),
            ],
          ),

        ),
        body:  TabBarView(
          children: <Widget>[
            Center(
              child: RecommendFriend(userId: userId),
            ),
            Center(
              child: MyFriend(userId),
            ),

          ],
        ),
      ),
    );
  }
}

탭에는 추천친구와 나의 친구 리스트의 탭으로 나눠서 관리가 되고있다.

각 위젯에 대한 소스는 아래와 같다.

 

My-friend

import 'package:goodshot/http/recommend-friend-httpapi.dart';
import 'package:flutter/material.dart';
import 'package:goodshot/util/const.dart';

import 'package:goodshot/view/friend/screen/friend-search.dart';
import 'package:goodshot/view/friend/widget/recommend-friend-item.dart';

import '../../../http/my-friend-httpapi.dart';
import '../widget/my-friend-item.dart';


class MyFriend extends StatefulWidget {
  final String userId;
  MyFriend({required this.userId});

  @override
  _MyFriendState createState() => _MyFriendState(userId);
}


class _MyFriendState extends State<MyFriend> {
  String userId='';
  _MyFriendState(String userId){
    this.userId =userId;
  }
  @override
  Widget build(BuildContext context) {

    return Scaffold(

      body: Container(
          child:
          FutureBuilder(
              future: getMyFriendList(userId.toString()),
              builder: (context,AsyncSnapshot snapshot){
                if (snapshot.hasData) {
                  return ListView.builder(
                    padding: EdgeInsets.symmetric(horizontal: 20),
                    itemCount: snapshot.data.length,
                    itemBuilder: (BuildContext context, int index) {
                      MyFriendItem item = snapshot.data[index];
                      return MyFriendItem(
                          sourceId: userId,
                          id: item.id,
                          userId: item.userId,
                          thumbnailImageUrl: item.thumbnailImageUrl,
                          nickname: item.nickname,
                          introduce: item.introduce,
                          status: item.status,
                      );
                    },);
                }
                else
                {
                  return Container(
                    child: Center(
                      child: Text("Loading..."),
                    ),
                  );
                }
              }
          )
      ),
    );
  }
}

 

Recommend

import 'package:goodshot/http/recommend-friend-httpapi.dart';
import 'package:flutter/material.dart';
import 'package:goodshot/util/const.dart';

import 'package:goodshot/view/friend/screen/friend-search.dart';
import 'package:goodshot/view/friend/widget/recommend-friend-item.dart';


class RecommendFriend extends StatefulWidget {
  final String userId;
  RecommendFriend({required this.userId});

  @override
  _RecommendFriendState createState() => _RecommendFriendState(userId);
}


class _RecommendFriendState extends State<RecommendFriend> {
  String userId='';
  _RecommendFriendState(String userId){
    this.userId =userId;
  }
  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(

        centerTitle: true,
        actions:[
          IconButton(
            icon: const Icon(
                Icons.search,
                color: Constants.appColor
            ),
            alignment: Alignment.topRight,
            onPressed: (){
              //searchFriendDialog(context);
              showSearch(context: context, delegate:Search(userId)).then((value) => setState((){}));
              //Navigate.pushPageReplacement(context, showSearch(context: context,));
            },
          ),
        ]
      ),
      body: Container(
          child:
          FutureBuilder(
              future: getRecommendFriendList(userId.toString()),
              builder: (context,AsyncSnapshot snapshot){
                if (snapshot.hasData) {
                  return ListView.builder(
                    padding: EdgeInsets.symmetric(horizontal: 20),
                    itemCount: snapshot.data.length,
                    itemBuilder: (BuildContext context, int index) {
                      RecommendFriendItem item = snapshot.data[index];
                      return RecommendFriendItem(
                          sourceId: userId,
                          id: item.id,
                          userId: item.userId,
                          thumbnailImageUrl: item.thumbnailImageUrl,
                          nickname: item.nickname,
                          introduce: item.introduce,
                          status: item.status,
                      );
                    },);
                  // return GridView.builder(
                  //     gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
                  //         maxCrossAxisExtent: 200,
                  //         childAspectRatio: 3 / 2,
                  //         crossAxisSpacing: 20,
                  //         mainAxisSpacing: 20),
                  //     itemCount: snapshot.data.length,
                  //     itemBuilder: (BuildContext context, int index) {
                  //       FriendItem item = snapshot.data[index];
                  //       return FriendItem(id: item.id,userId: item.userId,img: item.userId,nickname: item.nickname);
                  //     },);
                }
                else
                {
                  return Container(
                    child: Center(
                      child: Text("Loading..."),
                    ),
                  );
                }
              }
          )
      ),
    );
  }
}

 

위의 위젯 처럼 구현이 된다.

 

친구 삭제를 하면, 해당 친구의 리스트가 삭제 되고 다시 setState()를 호출하여 새로고침을 하게 해줄 것이다.

간단한 것이고 반복 작업이라, 포스팅은 하지 않을 예정이다.

 

 

대부분 한 위젯에 탭은 거의 있다.

그래서 Home (Tab관리) -> 각 위젯들 패키징을 하고

하단에서 위젯을 관리할 예정이다.

전체적인 패키징은 지금 처럼 도메인 별로 관리를 할 예정이다.

반응형