flutter_clean_architecture_V3

jju·2024년 1월 21일
0
List<Photo> _photos = [];

V2에서 home_screen에서 Photo를 담는 부분이 포함되어 ui와 분리가 되지 않은 상태였습니다.

최대한 screen(UI)와 model 및 controller를 분리화 시켜야 합니다.

변경 예)

InheritedWidget 은 불변값만 받을 수 있으므로, StreamController을 이용

class PhotoProvider extends InheritedWidget {
  final PixabayApi api;
  final _photoScreamController = StreamController<List<Photo>>()..add([]); //기존 photo를 담아주는 데이터를 없에고 controller로 대체합니다. 최초에는 데이터가 없으므로 circulr가 보이는데 add를 추가하여 빈 값을 출력하게 합니다.
  Stream<List<Photo>> get photoStream => _photoScreamController.stream;

   PhotoProvider({Key? key, required this.api, required Widget child})
      : super(key: key, child: child);

  static PhotoProvider of(BuildContext context){ //위젯트리의 정보를 가지고 있는 객체
    final PhotoProvider? result = context.dependOnInheritedWidgetOfExactType<PhotoProvider>(); // 가장 가까운 PhotoProvider를 찾아서 return
    assert(result != null,'No PixabayApi found in context'); //null 이면 문구가 나옵니다. 널이 아니다라는 검증
    return result!;
  }

  Future<void> fetch(String query) async {
    final result = await api.fetch(query);
    _photoScreamController.add(result);
  }

  @override //이전 상태와 현재 상태가 다른지 확인하는 위젯
  bool updateShouldNotify(PhotoProvider oldWidget) {
    return oldWidget.api != api;
  }
}

변경 예)
기존

 Expanded(
            child: GridView.builder(
              padding: EdgeInsets.all(16.0),
              shrinkWrap: true,
              itemCount: _photos.length,
              gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 2,
                crossAxisSpacing: 16,
                mainAxisSpacing: 16, //간격조절
              ),
              itemBuilder: (context, index) {
                final photo = _photos[index];
                return PhotoWidget(photo: photo);
              },
            ),
          )
        ],
      ),
    );
  }
}

변경
값이 변경된 값을 적용하기 위해 StreamBuilder를 감싸줍니다.
snapshot을 검증을 통하는데 최초에는 검색 하지 않은 이상 로딩표시가 발생합니다. PhotoProvider 에 add 위젯에 빈 리스트값을 보여줍니다.

          StreamBuilder<List<Photo>>(
            stream: photoProvider.photoStream,
            builder: (context, snapshot) {
              if (!snapshot.hasData){
                return const CircularProgressIndicator();
              }
              final photos = snapshot.data!;
              return Expanded(
                child: GridView.builder(
                  padding: EdgeInsets.all(16.0),
                  shrinkWrap: true,
                  itemCount: photos.length,
                  gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: 2,
                    crossAxisSpacing: 16,
                    mainAxisSpacing: 16, //간격조절
                  ),
                  itemBuilder: (context, index) {
                    final photo = photos[index];
                    return PhotoWidget(photo: photo);
                  },
                ),
              );
            }
          )
        ],
      ),

StreamBuilder를 이용하면서 리스트에 있는 업데이트 되는 값을 가져오게 되면, 코드가 길어지게 되고 준비 과정이 InheritedWidget 포함해서 많아지게 되는 이슈가 있습니다.
그렇기 때문에 상태관리 패키지를 이용해야 합니다.

profile
한결

0개의 댓글

관련 채용 정보