본문

[2018.11.24] 115. setUserVisibleHint 개념 및 실습

도입

이번 포스팅에서는 Fragment의 mUserVisibleHint 변수에 대해 알아볼 예정이다.

ViewPager를 통해 Fragment를 보여주면서 

현재 Fragment가 사용자에게 보여지고 있다는 것을 기준으로 

처리해야하는 로직이 생겼다.


그래서 현재 Fragment가 사용자에게 보여지고 있다는 것을 확인하는 방법으로 mUserVisibleHint를 사용했고 해당 내용을 정리할 예정이다.


생각했던 방법

1. ViewPager의 PageChangeListener을 통한 방법

단순히 ViewPager의 PageChangeListener를 사용한다면 Fragment가 사용자에게 보여지고 있다는 것을 판단 할 수 있다고 생각했다.

그러나, 이름처럼 Page가 변경될 때 호출되는 Listener이기 때문에 

Fragment가 ViewPager에 처음 추가되는 케이스에서는 호출되지 않는 문제점이 있었다.


2. Fragment의 mUserVisibleHint을 사용하는 방법

mUserVisibleHint를 설정하는 setter는 FragmentPagerAdapter을 통해 데이터가 추가되는 instantiateItem 메소드를 통해 호출되기 때문에 Fragment가 ViewPager에 처음 추가되는 케이스에서는 호출되지 않는 문제점을 해결 할 수 있었다. 

아래 코드는 FragmentPagerAdapter의 코드이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@NonNull
public Object instantiateItem(@NonNull ViewGroup container, int position) {
    if (this.mCurTransaction == null) {
        this.mCurTransaction = this.mFragmentManager.beginTransaction();
    }
 
    long itemId = this.getItemId(position);
    String name = makeFragmentName(container.getId(), itemId);
    Fragment fragment = this.mFragmentManager.findFragmentByTag(name);
    if (fragment != null) {
        this.mCurTransaction.attach(fragment);
    } else {
        fragment = this.getItem(position);
        this.mCurTransaction.add(container.getId(), fragment, makeFragmentName(container.getId(), itemId));
    }
 
    if (fragment != this.mCurrentPrimaryItem) {
        fragment.setMenuVisibility(false);
        fragment.setUserVisibleHint(false);
    }
 
    return fragment;
}
cs

mUserVisibleHint는 Fragment 내에서 default로 true 값이다.


개념

mUserVisibleHint를 설정하는 setUserVisibleHint 메소드의 공식 설명은 아래와 같다.

(출처 - https://developer.android.com/reference/android/app/Fragment.html#setUserVisibleHint(boolean))

여기서 주의할 점은 setUserVisibleHint는 fragment의 lifecycle과는 무관하다는 것이다. 그렇기 때문에 lifecycle 메소드들을 통해 순서를 보장할 수 없다는 것이다. 변수명처럼 말 그래돌 hint인것이다.


실습

Step1. Fragment에서 setUserVisibleHint를 구현

1
2
3
4
5
6
7
8
9
class Test1Fragment : Fragment() {
    // ...
    override fun setUserVisibleHint(isVisibleToUser: Boolean) {
        super.setUserVisibleHint(isVisibleToUser)
        // 원하는 로직 
        Log.e("setUserVisibleHint""Test1 isVisibleToUser: $isVisibleToUser")
    }
    // ...
}
cs




스크린 샷



#setUserVisibleHint #mUserVisibleHint #fragment

공유

댓글