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개의 댓글