ViewPager 완전정복 - setOffscreenPageLimit, setUserVisibleHint
ViewPager 완전정복
(setOffscreenPageLimit, setUserVisibleHint)
ㆍ 이번글은 제목에도 나와있듯이 setOffscreenPageLimit와
setUserVisibleHint에 대해서 알아보도록 하겠습니다.
ㆍ 코드는 이전글에서 만들었던 코드를 그대로 가져다가
사용할 예정입니다.
setOffScreenPageLimit 어디다가 쓰나?
첫번째 글 마지막부분에서
제가 이렇게 써놨었습니다.
현재 보이는 페이지 좌우만
생성해놓고 사용하는 구조이다.
이게 무슨말인지 한번 보겠습니다.
마우스로 Swipe를 하다보니
깔끔하게 넘어가지 않은 부분이
있지만..
위의 gif를 보게되면
가운데 탭인 채팅방의
숫자카운터는 계속 유지되는데
친구, 설정탭의 숫자카운터는
초기화 되는 모습을 볼 수 있습니다.
위에서 말했던 그대로입니다.
앱을 실행하면
첫번째 친구탭에서는
다음탭인 채팅방탭을
미리 생성해놓습니다.
그리고 채팅방탭에
넘어왔을때는 채팅방탭 기준
좌우(이전,다음)페이지인
친구, 설정탭을 생성하게 됩니다.
친구탭은 미리 생성되있으므로
설정탭만 생성하면 되겠죠
그리고 이제 3번째
설정탭을 누르게되면
이전페이지인 채팅방탭만
생성(준비)되어있으면 됩니다.
이때, 첫번째탭인 친구탭은
준비하고(그려놓고) 있을 필요가 없습니다.
그러므로 페이지를 파괴해놓습니다.
(이때 숫자카운터 한 내용은 싹 날라가죠)
그리고 3번째에서
다시 2번째탭으로
넘어왔을때, 첫번째탭이
그려져있어야 하는데
파괴된 상태이므로
새로 생성하게됩니다
이런식으로 바로
좌우(이전,다음)페이지와
연결되어 있지 않을때
화면에 그려놓은 내용은
싹 초기화 하게 되는 것입니다
두번째 탭은 어느탭에 있던
항상 좌우에 포함되므로 계속
유지되게 되는것 입니다.
그럼 모든 탭의 화면을 항상
유지하고 싶다면 어떻게
하면 될까요?
바로!!
setOffscreenPageLimit를
사용하면 됩니다
사용방법은 간단합니다
vp.setAdapter(new pagerAdapter(getSupportFragmentManager()));
vp.setOffscreenPageLimit(2);
vp.setCurrentItem(0);
vp는 ViewPager입니다.
setOffscreenPageLimit를 통하여
좌우 몇개의 페이지를 그려놓고(준비)
있을지 설정해 줄 수 있습니다.
위와 같이 2라고 적으면
좌 2, 현재, 우2
총 5페이지가 그려져(준비)있는
상태겠죠
결과를 보겠습니다
처음 결과와 다르게
값이 초기화되지 않고
유지되는 것을 확인 할 수 있습니다.
그럼 화면으로 말고 코드로 확인해보자!
그럼 위에서 한 말을
코드를 통해서 확인해보겠습니다.
확인을 해보기 위해서
각 Fragment의
onCreateView와
onDestroyView에 로그를
달아보도록 하겠습니다.
public class FirstFragment extends Fragment
{
public FirstFragment()
{
}
TextView tv;
int i = 0;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
Log.d("ITPANGPANG","onCreateView(First)");
RelativeLayout layout = (RelativeLayout) inflater.inflate(R.layout.fragment_first, container, false);
tv = (TextView)layout.findViewById(R.id.tv);
Button btn = (Button)layout.findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
i++;
tv.setText(""+i);
}
});
return layout;
}
@Override
public void onDestroyView()
{
Log.d("ITPANGPANG","onDestroyView(First)");
super.onDestroyView();
}
}
자 다른 부분은
볼 것 없고
onCreateView와 onDestoryView에
Log를 추가한 것만 확인하시면 됩니다.
이런식으로 Second, Third Fragment에도
추가시킨 후에 앱을 다시 돌려보도록
하겠습니다
먼저
setOffscreenPageLimit를
추가시키기 전입니다.
[앱 실행시]
1, 2번 탭이 생성되었습니다
(왜 Second가 먼저인지는 나중에 찾아봐야겠네요)
[두번째 탭 이동]
두번째 탭으로 이동하니
세번째탭이 생성되는 것을
확인 할 수 있습니다
[세번째 탭 이동]
세번째 탭으로 이동하니
첫번째 Fragment가 파괴되는
것을 확인 할 수 있었습니다.
[세번째 탭 -> 두번째 탭 -> 첫번째탭]
세번째 탭에서
다시 차례대로
두번째, 첫번째탭으로 돌아왔을때의
로그를 확인 해보니
두번째 탭으로 왔을때 : onCreateView(First)
첫번째 탭으로 왔을때 : onDestroyView(Third)
의 결과를 얻을 수 있었습니다.
이제
setOffscreenPageLimit(2)를
추가하고 확인해보겠습니다.
[앱 실행시]
실행하자마자
모든 Fragment가 생성되는것을
확인 할 수 있었습니다.
[두번째 탭 이동]
변화 없음
[세번째 탭 이동]
변화 없음
[세번째 탭 -> 두번째 탭 -> 첫번째탭]
변화 없음
뭐 당연한 결과였습니다.
모든 페이지가 그려져있으므로
(항상 준비되어 있어야 하므로)
파괴되는 Fragment도 없어야 합니다
그럼 setOffscreenPageLimit(0)을 넣으면?
자 만약에
setOffscreenPageLimit에
0값을 넣으면 어떻게 될까요?
위에서 설명한대로 라면
좌우(이전,다음) 준비되는 페이지가
없어야 하므로..
현재 눈에 보이는 페이지만
그려져있고, 다음탭으로 넘어갈때
그때서야 다음페이지가 생성될까요?
결과만 말씀드리면
위의 예상결과는 틀린답입니다.
실제로 0값을 넣어봐도
1값을 넣은 것과 동일한 결과가
나옵니다.
(앱이 죽을수도 있는지는 모르겠습니다)
과연
이 부분이 대단히 중요한
부분일까요?
하나 예를 들어보겠습니다.
만약 첫번째 탭에서
어떤 변화를 줬을때
그 변화가 두번째 탭에
영향을 끼쳐야 하는 상황이라면?
ViewPager에 담겨있는
첫번째 페이지에서
구매할 사과의 갯수를 고를 수 있고
두번째 페이지를 넘어왔을때
그 갯수에 해당하는 사과의
가격이 자동으로 찍혀있어야 하는
상황이라면?
어떻게 해야할까요?
두번째 탭을 넘어올때
첫번째 입력한 사과의 갯수를 받아와서
화면에 뿌려줘야 하는데
위에서 로그를 찍어봐서 알겠지만
첫번째에서 두번째 탭으로 넘어올때
onCreateView를 타지않습니다
(미리 그려져있는데 다시 그릴 필요가 없으니까요)
그렇다면 이 사과의 갯수는
어떻게 받을 수 있을까요?
이 상황을 해결하기 위해서는
setUserVisibleHint
바로 이놈을 사용해줘야 합니다.
과연 이놈이 무엇인지는
다음글에서 알아보도록 하겠습니다.
- setUserVisibleHint를 사용한 예제
위 예를 든 부분은
제가 글을 잘 못쓰기도하고
잘 썼다고 해도 이해하기 어려울 수 있습니다.
그러므로 다음글에서
결과화면과 로그를 동시에 보면서
도대체 무슨말을 한것이었는지
알아보도록 하겠습니다.
'안드로이드(android) > ViewPager' 카테고리의 다른 글
ViewPager wrap_content일때 Height 구하기 (0) | 2016.12.13 |
---|---|
ViewPager 완전정복 - addOnPageChangeListener에 대해서 (3) | 2016.11.05 |
ViewPager 완전정복 - setUserVisibleHint를 사용한 예제 (5) | 2016.11.02 |
ViewPager 완전정복(탭 꾸미기) (3) | 2016.10.31 |
ViewPager 완전정복(일단 만들기) (17) | 2016.10.28 |