마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

뷰페이지 프래그먼트 구현 질문좀 드리겠습니다.

0 추천

부스트코스에서 프로젝트 진행중에 있습니다. 영화 어플 관련된것 같구요.

현재 구현중인 부분은 영화목록을 보여주는 기능인데 뷰페이저로 구성을하고 영화 목록은 프래그먼트로

구현을 합니다.

예시 사진입니다.

 

이런 식으로 영화 목록페이지가 구성됩니다. 

보시다시피 영화 이미지, 제목 이런것만 다르지 UI는 똑같습니다. 그래서 효율적으로 하기위해

프래그먼트 액티비티를 여러개 생성하지않고 하나만 만들어 데이터만 바꿔주는 식으로 구성을 했습니다.

이 부분(데이터를 어떻게 보내고 설정하는지)을 다른분들은 어떻게 했나 궁금해서 보고 있는데

이해가 잘가지 않는부분이 있어 질문드립니다.

1. 프레그먼트 생성하는 caller(=activity class) 쪽에서 Bundle을 생성하시고 원하는 데이터를 담아서 fragment.setArgument(bundle); 메소드를 호출해서 프레그먼트 내부로 전달합니다.

@NonNull
private MovieListPage createMovieListPage(int index, @NonNull MovieDto movieDto) {
    MovieListPage movieListPage = new MovieListPage();
    movieListPage.setArguments(createBundle(index, movieDto));
    return movieListPage;
}

@NonNull
private Bundle createBundle(
        @IntRange(from = 0, to = Integer.MAX_VALUE) int index,
        @NonNull MovieDto movieDto) {
    Bundle bundle = new Bundle(6 /* capacity */);
    bundle.putInt(INDEX_BUNDLE_KEY, index);
    bundle.putString(TITLE_BUNDLE_KEY, movieDto.getTitle());
    bundle.putString(MAIN_POSTER_URL_BUNDLE_KEY, movieDto.getMainPosterUrl());
    bundle.putFloat(RESERVE_RATE_BUNDLE_KEY, movieDto.getReserveRate());
    bundle.putInt(RATING_STRING_ID_BUNDLE_KEY, movieDto.getRating().getStringId());
    bundle.putInt(D_DAY_BUNDLE_KEY, movieDto.getDDay());
    return bundle;
}
2. receiver(=fragment class) 쪽 onCreateView 메소드 내에서 getArgument(); 메소드를 호출하여 caller 쪽에서 보낸 데이터(bundle)를 이용하시면 됩니다.

@Override
@Nullable
public View onCreateView(
        @NonNull LayoutInflater inflater,
        @Nullable ViewGroup container,
        @Nullable Bundle savedInstanceState) {
    parseBundle();
    ViewGroup movieListPageLayout = (ViewGroup) inflater.inflate(
            R.layout.movie_list_page,
            container,
            false /* attachToRoot */);
    initUi(movieListPageLayout);
    return movieListPageLayout;
}

private void parseBundle() {
    Bundle bundle = getArguments();
    if (bundle == null) {
        return;
    }
    index = bundle.getInt(MovieListAdapter.INDEX_BUNDLE_KEY);
    String title = bundle.getString(MovieListAdapter.TITLE_BUNDLE_KEY);
    if (title == null) {
        this.title = "";
    } else {
        this.title = title;
    }
    String mainPosterUrl = bundle.getString(MovieListAdapter.MAIN_POSTER_URL_BUNDLE_KEY);
    if (mainPosterUrl == null) {
        this.mainPosterUrl = "";
    } else {
        this.mainPosterUrl = mainPosterUrl;
    }
    reserveRate = bundle.getFloat(MovieListAdapter.RESERVE_RATE_BUNDLE_KEY);
    ratingStringId = bundle.getInt(MovieListAdapter.RATING_STRING_ID_BUNDLE_KEY);
    dDay = bundle.getInt(MovieListAdapter.D_DAY_BUNDLE_KEY);
}

 

보니 createBundle() 메소드에서 Bundle 객체를 통해 페이지에 설정할 데이터를 넣어 보내고

프래그먼트에서 그걸 받아 페이지에 설정하는 방식인것 같습니다. 

근데 제가 잘이해되질 않는 부분은 createBundle() 부분에서 putInt,putString 등 데이터를 넣는 함수들에서

movieDto 객체의 get~~ 메소드를 통해 넣을 해당 페이지에 넣을 데이터를 불러오는것같은데..

궁금한게 이게 몇번째 데이터에 설정될 데이터인지 어떻게 아느냐 인겁니다..

매개변수로 index를 받는데 보아하니 이게 몇페이지에 관한 정보인것 같은데, 이 index는 

그냥 putInt로 보내버리기때문에 그 아래 getTitle(), getReserveRate() 등등..은 헤당페이지가 

몇페이지인지 알지를 못하는데 데이터인지 어떻게 아는걸까요..? getTitle() 등에 index 정보를 전달하는것도

아닌데 어떻게 알수 있는걸까요..? 

 

프래그먼트에서 index를 받아도 index가지고 뭐하는게 없는데 어떻게 해당페이지에 맞는 설정을 하는지

추측이 잘안가는데..

너무 추상적인 질문이고 코드 정보가 이게다라 드릴말씀이 없습니다만..

혹시나 어떻게 구성되어있는것 같다라고 추측이라도 가능하실까요?

 

codeslave (3,940 포인트) 님이 2020년 9월 28일 질문

1개의 답변

+1 추천
몇페이지에 대한 정보는
createMovieListPage()가 호출되면서 movieDto 파라미터가 전달될 때
이미 결정되어 있는 것으로 보이네요.

즉, movieDto가 해당 페이지에 대한 정보만 가지고 있습니다.
(fragment는 생성될때 영화의 정보가 결정되고, 영화 하나의 정보만 가지고 있습니다.)
디자이너정 (42,810 포인트) 님이 2020년 9월 28일 답변
그러면 createMovieListPage가 호출되는 시점에서 이미 movieDto는
몇페이지에 대한 정보인지를 더 가지고 있다는 말씀이신가요?
뭐..2페이지면 타이틀에서 getTitle()에서 이미 2.공조 데이터를 가지고있다는 말씀이시네요..?
선생님 그렇다면 이렇게되려면 movieDto의 경우도
getTitle()내에서 1페이지부터~몇페이지까지 타이틀 데이터 정보를 다 가지고 있고
객체생성시에 index정보만 보내서 몇페이지 객체인지만 정하는 형태일까요..?
movieDto 인스턴스가 여러개인 것이고
createMovieListPage()가 여러 번 호출되서
MovieListPage fragment가 여러개인 상황입니다.

movieDto는 하나의 영화 정보만 가지고 있고,
따라서 movieDto.getTitle()는 하나의 영화 제목만 리턴합니다.
...