programing

ViewPager에서 조각이 표시되는 시기를 결정하는 방법

batch 2023. 6. 10. 08:34
반응형

ViewPager에서 조각이 표시되는 시기를 결정하는 방법

fragment: fragmentonResume()ViewPager조각이 실제로 보이기 전에 발사됩니다.

를 들어, 저는 으로 된 2개의 조각을 .ViewPager그리고.FragmentPagerAdapter두 번째 조각은 인증된 사용자만 사용할 수 있으며 조각이 표시되면 사용자에게 로그인하도록 요청해야 합니다(경고 대화 상자 사용).

지하만만▁but.ViewPager에서는 두 번째 조각을 캐시하기 위해 첫 번째 조각이 표시될 때 두 번째 조각을 만들고 사용자가 스위핑을 시작할 때 이 조각을 표시합니다.

그래서 그onResume()이벤트가 표시되기 훨씬 전에 두 번째 조각에서 발생합니다.그렇기 때문에 적절한 순간에 대화를 보여주기 위해 두 번째 조각이 보일 때 발생하는 이벤트를 찾으려고 합니다.

이것이 어떻게 행해지는가?

ViewPager에서 조각이 표시되는 시기를 결정하는 방법

재지정하여 다음을 수행할 수 있습니다.setUserVisibleHint의 신의에Fragment:

public class MyFragment extends Fragment {
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isVisibleToUser) {
        }
        else {
        }
    }
}

업데이트: Android 지원 라이브러리(rev 11)에서 사용자가 볼 수 있는 힌트 문제를 해결했습니다. 이제 조각에 지원 라이브러리를 사용하면 안전하게 사용할 수 있습니다.getUserVisibleHint()또는 오버라이드setUserVisibleHint()곤의 답변에 설명된 대로 변경 사항을 캡처합니다.

업데이트 1 여기 한 가지 작은 문제가 있습니다.getUserVisibleHint()으로 " 이값기입니다값"입니다.true.

// Hint provided by the app that this fragment is currently visible to the user.
boolean mUserVisibleHint = true;

그래서 이전에 사용하려고 할 때 문제가 있을 수 있습니다.setUserVisibleHint()호출되었습니다.으로 해결방로다값설수있할다습니정을서음에 할 수 .onCreate이와 같은 방법.

public void onCreate(@Nullable Bundle savedInstanceState) {
    setUserVisibleHint(false);

시대에 뒤떨어진 대답:

대부분의 사용 사례에서,ViewPager한 번에 하나의 페이지만 표시하지만, 사용 중인 경우 사전 삭제된 조각도 "표시되지 않음" 상태가 됩니다.FragmentStatePagerAdapterAndroid Support Library pre-r11.

재정의:

public class MyFragment extends Fragment {
    @Override
    public void setMenuVisibility(final boolean visible) {
        super.setMenuVisibility(visible);
        if (visible) {
            // ...
        }
    }
   // ...
}

ViewPager에서 하나의 조각만 실제로 부모 활동의 항목과 함께 메뉴 항목을 배치할 수 있기 때문에, 가장 적합한 "가시성" 상태라고 생각하는 조각의 초점 상태를 캡처하는 것입니다.

이것은 정상적인 상태를 회복하는 것처럼 보입니다.onResume()당신이 예상할 수 있는 행동.홈 키를 눌러 앱을 떠난 후 다시 앱에 들어가는 것이 좋습니다. onResume()는 두 번 연속으로 호출되지 않습니다.

@Override
public void setUserVisibleHint(boolean visible)
{
    super.setUserVisibleHint(visible);
    if (visible && isResumed())
    {
        //Only manually call onResume if fragment is already visible
        //Otherwise allow natural fragment lifecycle to call onResume
        onResume();
    }
}

@Override
public void onResume()
{
    super.onResume();
    if (!getUserVisibleHint())
    {
        return;
    }

    //INSERT CUSTOM CODE HERE
}

사용하는 다른 방법은 다음과 같습니다.onPageChangeListener:

  ViewPager pager = (ViewPager) findByViewId(R.id.viewpager);
  FragmentPagerAdapter adapter = new FragmentPageAdapter(getFragmentManager);
  pager.setAdapter(adapter);
  pager.setOnPageChangeListener(new OnPageChangeListener() {

  public void onPageSelected(int pageNumber) {
    // Just define a callback method in your fragment and call it like this! 
    adapter.getItem(pageNumber).imVisible();

  }

  public void onPageScrolled(int arg0, float arg1, int arg2) {
    // TODO Auto-generated method stub

  }

  public void onPageScrollStateChanged(int arg0) {
    // TODO Auto-generated method stub

  }
});

ViewPager2그리고.ViewPager 전부에서androidx.fragment:fragment:1.1.0그냥 사용할 수 있습니다.onPause그리고.onResume사용자가 현재 볼 수 있는 조각을 결정하기 위해 콜백합니다. onResume되고 fragment가 표시되면 됩니다.onPause그것이 보이기 시작할 때.

goodViewPager2에 한 동작을 할 수 .ViewPager쉽게.

이하려면 "ViewPager"를 .FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT두 번 인 로 변 수 개의 두 변수FragmentPagerAdapter시공자

FragmentPagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT)

참고:setUserVisibleHint() 및 방법FragmentPagerAdapter하나의 매개 변수를 가진 생성자는 이제 안드로이드 제트팩의 새로운 버전의 프래그먼트에서 더 이상 사용되지 않습니다.

setUserVisibleHint()전에 가끔 전화가 옵니다. onCreateView()그리고 때때로 그 후에 문제를 일으킵니다.

는 이를극려확합니다야해를 확인해야 .isResumed()▁▁well▁setUserVisibleHint()방법.하지만 이번 사건에서 저는 깨달았어요setUserVisibleHint()Fragment가 다시 시작되어 표시되는 경우에만 호출되며, 생성된 경우에는 호출되지 않습니다.

그래서 만약 당신이 프래그먼트가 다음일 때 무언가를 업데이트하고 싶다면.visible의 업데이트 을 트기둘다에넣다습니을능데에 둘 다 .onCreate()그리고.setUserVisibleHint():

@Override
public View onCreateView(...){
    ...
    myUIUpdate();
    ...        
}
  ....
@Override
public void setUserVisibleHint(boolean visible){
    super.setUserVisibleHint(visible);
    if (visible && isResumed()){
        myUIUpdate();
    }
}

업데이트: 그래도 깨달았습니다.myUIUpdate()번경우가 , 그 세이가 두 탭에 , 첫탭을 열 때 두 탭이 두 번째 되고 때개두번호니다됩출때그로 3이이고이두코번탭경째가있드에우유 3생는니다탭는때처열탭두번도성됩째음을번첫째이탭개▁is▁gets▁even,▁twice▁also▁created,▁the생탭다니됩성▁sometimes도번두째때▁is▁called▁if▁and열nd▁the▁it,처음▁is▁2▁when,▁reason▁tab탭▁tabs때▁2때다번을▁on▁codemyUIUpdate()이 호출됩니다.에 두 번째으로 스와이프를 면두번탭스으와하면프이로째그러,면▁then하,프▁you▁to▁2.myUIUpdate()if (visible && isResumed()) 호출결으로이과적고되로▁is으이결과▁called.myUIUpdate()한 번에 두 번씩 전화가 올 수도 있습니다.

다른 문제는!visiblesetUserVisibleHint와 2할 때 둘 다 됩니다. 1) fragment 화면으로 전환할 때 1) fragment 화면이 생성되기 에 호출됩니다.

솔루션:

private boolean fragmentResume=false;
private boolean fragmentVisible=false;
private boolean fragmentOnCreated=false;
...

@Override
public View onCreateView(...){
    ...
    //Initialize variables
    if (!fragmentResume && fragmentVisible){   //only when first time fragment is created
        myUIUpdate();
    }
    ...        
}

@Override
public void setUserVisibleHint(boolean visible){
    super.setUserVisibleHint(visible);
    if (visible && isResumed()){   // only at fragment screen is resumed
        fragmentResume=true;
        fragmentVisible=false;
        fragmentOnCreated=true;
        myUIUpdate();
    }else  if (visible){        // only at fragment onCreated
        fragmentResume=false;
        fragmentVisible=true;
        fragmentOnCreated=true;
    }
    else if(!visible && fragmentOnCreated){// only when you go out of fragment screen
        fragmentVisible=false;
        fragmentResume=false;
    }
}

설명:

fragmentResume,fragmentVisible ㅠㅠmyUIUpdate()onCreateView()재개가 아닌 fragment가 생성되어 표시되는 경우에만 호출됩니다.또한 첫 번째 탭에 있을 때 문제가 해결되고, 보이지 않더라도 두 번째 탭이 생성됩니다.이렇게 하면 문제가 해결되고 다음과 같은 경우 단편 화면이 표시되는지 확인할 수 있습니다.onCreate.

fragmentOnCreated조각을 처음 만들 때 조각이 표시되지 않고 호출되지 않도록 합니다.이제 이 if 절은 fragment에서 스와이프할 때만 호출됩니다.

업데이트 이 코드를 모두 넣을 수 있습니다.BaseFragment이와 같은 코드와 오버라이드 메소드

신규

ViewPager2+FragmentStateAdapter+onResume()에서) 를

이전 답변(사용되지 않음)

지하기를 탐지하는 FragmentViewPager눈에 보이는, 나는 단지 사용하는 이 꽤 확신합니다. setUserVisibleHint충분하지 않습니다.
조각이 표시되는지 보이지 않는지 확인할 수 있는 솔루션이 있습니다. viewpager를 실행할 때로 합니다.

public class BaseFragmentHelpLoadDataWhenVisible extends Fragment {
    protected boolean mIsVisibleToUser; // you can see this variable may absolutely <=> getUserVisibleHint() but it not. Currently, after many test I find that

    /**
     * This method will be called when viewpager creates fragment and when we go to this fragment background or another activity or fragment
     * NOT called when we switch between each page in ViewPager
     */
    @Override
    public void onStart() {
        super.onStart();
        if (mIsVisibleToUser) {
            onVisible();
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        if (mIsVisibleToUser) {
            onInVisible();
        }
    }

    /**
     * This method will called at first time viewpager created and when we switch between each page
     * NOT called when we go to background or another activity (fragment) when we go back
     */
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        mIsVisibleToUser = isVisibleToUser;
        if (isResumed()) { // fragment have created
            if (mIsVisibleToUser) {
                onVisible();
            } else {
                onInVisible();
            }
        }
    }

    public void onVisible() {
        Toast.makeText(getActivity(), TAG + "visible", Toast.LENGTH_SHORT).show();
    }

    public void onInVisible() {
        Toast.makeText(getActivity(), TAG + "invisible", Toast.LENGTH_SHORT).show();
    }
}

설명 아래 로그캣을 주의 깊게 확인하면 이 솔루션이 작동하는 이유를 알 수 있다고 생각합니다.

첫 출시

Fragment1: setUserVisibleHint: isVisibleToUser=false isResumed=false
Fragment2: setUserVisibleHint: isVisibleToUser=false isResumed=false
Fragment3: setUserVisibleHint: isVisibleToUser=false isResumed=false
Fragment1: setUserVisibleHint: isVisibleToUser=true isResumed=false // AT THIS TIME isVisibleToUser=true but fragment still not created. If you do something with View here, you will receive exception
Fragment1: onCreateView
Fragment1: onStart mIsVisibleToUser=true
Fragment2: onCreateView
Fragment3: onCreateView
Fragment2: onStart mIsVisibleToUser=false
Fragment3: onStart mIsVisibleToUser=false

2페이지로 이동

Fragment1: setUserVisibleHint: isVisibleToUser=false isResumed=true
Fragment2: setUserVisibleHint: isVisibleToUser=true isResumed=true

3페이지로 이동

Fragment2: setUserVisibleHint: isVisibleToUser=false isResumed=true
Fragment3: setUserVisibleHint: isVisibleToUser=true isResumed=true

백그라운드로 이동:

Fragment1: onStop mIsVisibleToUser=false
Fragment2: onStop mIsVisibleToUser=false
Fragment3: onStop mIsVisibleToUser=true

전경으로 이동

Fragment1: onStart mIsVisibleToUser=false
Fragment2: onStart mIsVisibleToUser=false
Fragment3: onStart mIsVisibleToUser=true

여기에 DEMO 프로젝트

도움이 되길 바랍니다.

package com.example.com.ui.fragment;


import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.example.com.R;

public class SubscribeFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_subscribe, container, false);
        return view;
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);

        if (isVisibleToUser) {
            // called here
        }
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
    }
}

재정의setPrimaryItem()에 시대에FragmentPagerAdapterㅠㅠㅠㅠ 는 이 합니다.저는 이 방법을 사용하는데, 효과가 좋습니다.

@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
    // This is what calls setMenuVisibility() on the fragments
    super.setPrimaryItem(container, position, object);

    if (object instanceof MyWhizBangFragment) {
        MyWhizBangFragment fragment = (MyWhizBangFragment) object;
        fragment.doTheThingYouNeedToDoOnBecomingVisible();
    }
}

그것을 위해 오버라이드합니다.

public void onHiddenChanged(boolean hidden)

fragment의 숨겨진 상태(에서 반환됨)가 변경된 경우 호출됩니다.fragment는 숨기지 않고 시작합니다. fragment가 상태를 변경할 때마다 호출됩니다.


hidden-boolean입니다.fragment는 true이고, 는 fragment는 false입니다.

오직 이것만이 나에게 효과가 있었습니다!!그리고.setUserVisibleHint(...)이제는 더 이상 사용되지 않습니다(마지막에 문서를 첨부했습니다). 즉, 대부분의 다른 답변은 더 이상 사용되지 않습니다;-)

public class FragmentFirewall extends Fragment {
    /**
     * Required cause "setMenuVisibility(...)" is not guaranteed to be
     * called after "onResume()" and/or "onCreateView(...)" method.
     */
    protected void didVisibilityChange() {
        Activity activity = getActivity();
        if (isResumed() && isMenuVisible()) {
            // Once resumed and menu is visible, at last
            // our Fragment is really visible to user.
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        didVisibilityChange();
    }

    @Override
    public void setMenuVisibility(boolean visible) {
        super.setMenuVisibility(visible);
        didVisibilityChange();
    }
}

테트및가능과 함께 합니다.NaviagationDrawer 거기에, 시에, 기거.isMenuVisible() 항상돌것입니다올아다것을 반환합니다.true)onResume()충분해 보이지만, 우리는 지원하고 싶습니다.ViewPager

setUserVisibleHint사용되지 않습니다.이 메서드를 재정의하는 경우 전달 시 동작이 구현됩니다.true 옮겨야 .Fragment.onResume()그리고 통과할 때 실행되는 행동.false 옮겨야 .Fragment.onPause().

setUserVisibleHint(boolean visible)이제 더 이상 사용되지 않습니다. 따라서 이것이 올바른 솔루션입니다.

FragmentPagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT)

버전에서 ViewPager2ViewPagerandroidx.fragment:fragment:1.1.0그냥 사용할 수 있습니다.onPause()그리고.onResume()현재 사용자가 볼 수 있는 조각을 확인합니다. onResume()조각이 눈에 띄고, 그리고onPause그것이 보이기 시작할 때.

이하려면 "ViewPager"를 .FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT의 두 로서의 매개 변수입니다.FragmentPagerAdapter시공자

는 그것을 되었습니다.onCreateOptionsMenu그리고.onPrepareOptionsMenu메서드는 조각이 실제로 보이는 경우에만 호출됩니다.나는 이런 동작을 하는 어떤 방법도 찾을 수 없었고, 또한 나는 시도했습니다.OnPageChangeListener. 를 들어 그나상황적않았다니습지하합러에▁initial로 합니다. 예를 들어, 초기화된 변수가 필요합니다.onCreate방법.

따라서 이 두 가지 방법은 특히 소규모 및 단기 작업에 대한 해결책으로 이 문제를 해결하는 데 사용될 수 있습니다.

저는 이것이 더 나은 해결책이지만 최선은 아니라고 생각합니다.나는 이것을 사용할 것이지만 동시에 더 나은 해결책을 기다릴 것입니다.

안부 전해요.

집합 Primary를 재정의하는 다른 솔루션이 여기에 게시되었습니다.크리스라슨의 호출기 어댑터에 있는 아이템은 거의 효과가 있었습니다.그러나 이 방법은 각 설정에 대해 여러 번 호출됩니다.또한 이 방법을 처음 몇 번 호출할 때는 준비가 되지 않았기 때문에 fragment의 뷰 등에서 NPE를 받았습니다.다음과 같은 변화가 저에게 효과가 있었습니다.

private int mCurrentPosition = -1;

@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
    super.setPrimaryItem(container, position, object);

    if (position == mCurrentPosition) {
        return;
    }

    if (object instanceof MyWhizBangFragment) {
        MyWhizBangFragment fragment = (MyWhizBangFragment) object;

        if (fragment.isResumed()) {
            mCurrentPosition = position;
            fragment.doTheThingYouNeedToDoOnBecomingVisible();
        }
    }
}

조각 내부에 다음 코드 추가

@Override
public void setMenuVisibility(final boolean visible) 
 {
    super.setMenuVisibility(visible);
    if (visible && isResumed()) 
     {

     }
}

작업 중에 동일한 문제가 발생했습니다.FragmentStatePagerAdapters3】.첫 번째 탭을 클릭할 때마다 Dilaog를 보여주고 다른 탭을 클릭할 때는 숨겨야 했습니다.

재정의 중setUserVisibleHint()현재 눈에 보이는 파편을 찾는 데 도움이 되지 않았습니다.

세 번째 탭에서 클릭할 때 -----> 첫 번째 탭.두 번째 조각과 첫 번째 조각에 대해 두 번 트리거되었습니다.isResumed() 메서드와 결합했습니다.

    @Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    isVisible = isVisibleToUser;

    // Make sure that fragment is currently visible
    if (!isVisible && isResumed()) {
        // Call code when Fragment not visible
    } else if (isVisible && isResumed()) {
       // Call code when Fragment becomes visible.
    }

}

에게 뷰가 된 하고 를 가지고 .fragment.onAttach().

setUserVisibleHint()할 세 했습니다. 해결해야 할 3가지 사례를 발견했습니다.onAttach()발표자가 언제 참석할 수 있는지 알 수 있도록 언급됨)

  1. 조각이 방금 작성되었습니다.시스템에서 다음 호출을 수행합니다.

    setUserVisibleHint() // before fragment's lifecycle calls, so presenter is null
    onAttach()
    ...
    onResume()
    
  2. 조각이 이미 생성되었으며 홈 버튼이 눌러졌습니다.앱을 포그라운드로 복원할 때 이를 다음이라고 합니다.

    onResume()
    
  3. 방향 변경:

    onAttach() // presenter available
    onResume()
    setUserVisibleHint()
    

가시성 힌트가 발표자에게 한 번만 전달되기를 원하므로 다음과 같이 수행합니다.

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View root = inflater.inflate(R.layout.fragment_list, container, false);
    setHasOptionsMenu(true);

    if (savedInstanceState != null) {
        lastOrientation = savedInstanceState.getInt(STATE_LAST_ORIENTATION,
              getResources().getConfiguration().orientation);
    } else {
        lastOrientation = getResources().getConfiguration().orientation;
    }

    return root;
}

@Override
public void onResume() {
    super.onResume();
    presenter.onResume();

    int orientation = getResources().getConfiguration().orientation;
    if (orientation == lastOrientation) {
        if (getUserVisibleHint()) {
            presenter.onViewBecomesVisible();
        }
    }
    lastOrientation = orientation;
}

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (presenter != null && isResumed() && isVisibleToUser) {
        presenter.onViewBecomesVisible();
    }
}

@Override public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putInt(STATE_LAST_ORIENTATION, lastOrientation);
}

에 검출focused view!

이것은 나에게 효과가 있습니다.

public static boolean isFragmentVisible(Fragment fragment) {
    Activity activity = fragment.getActivity();
    View focusedView = fragment.getView().findFocus();
    return activity != null
            && focusedView != null
            && focusedView == activity.getWindow().getDecorView().findFocus();
}

저도 같은 문제가 있었습니다. ViewPager다른 fragment 수명 주기 이벤트를 실행하므로 해당 동작을 변경할 수 없습니다.저는 단편과 이용 가능한 애니메이션을 사용하여 간단한 호출기를 작성했습니다.단순 페이지

제가 이걸 썼는데 효과가 있었어요!

mContext.getWindow().getDecorView().isShown() //boolean

저는 SectionsPagerAdapter와 하위 조각을 지원하므로 많은 문제가 발생한 후 다음 항목의 솔루션을 기반으로 작업 버전을 얻게 되었습니다.

public abstract class BaseFragment extends Fragment {

    private boolean visible;
    private boolean visibilityHintChanged;

    /**
     * Called when the visibility of the fragment changed
     */
    protected void onVisibilityChanged(View view, boolean visible) {

    }

    private void triggerVisibilityChangedIfNeeded(boolean visible) {
        if (this.visible == visible || getActivity() == null || getView() == null) {
            return;
        }
        this.visible = visible;
        onVisibilityChanged(getView(), visible);
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (!visibilityHintChanged) {
            setUserVisibleHint(false);
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        if (getUserVisibleHint() && !isHidden()) {
            triggerVisibilityChangedIfNeeded(true);
        }
    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        triggerVisibilityChangedIfNeeded(!hidden);
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        visibilityHintChanged = true;
        if (isVisibleToUser && isResumed() && !isHidden()) {
            triggerVisibilityChangedIfNeeded(true);
        } else if (!isVisibleToUser) {
            triggerVisibilityChangedIfNeeded(false);
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        triggerVisibilityChangedIfNeeded(false);
    }

    @Override
    public void onStop() {
        super.onStop();
        triggerVisibilityChangedIfNeeded(false);
    }

    protected boolean isReallyVisible() {
        return visible;
    }
}

:setUserVisibleHint(false)활동/분절 중지 시 호출되지 않습니다. 작동할 수 있습니다.register/unregister모든 청취자/등

또한, 당신은 받을 것입니다.setUserVisibleHint(false) " 에다"; "당은원않습니지하신visible작태조각다않▁if습니▁your"를 경우.unregister그런 경우에는 한 번도 등록한 적이 없기 때문에.

@Override
public void onStart() {
    super.onStart();

    if (getUserVisibleHint()) {
        // register
    }
}

@Override
public void onStop() {
    if (getUserVisibleHint()) {
        // unregister
    }

    super.onStop();
}

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);

    if (isVisibleToUser && isResumed()) {
        // register

        if (!mHasBeenVisible) {
            mHasBeenVisible = true;
        }
    } else if (mHasBeenVisible){
        // unregister
    }
}

사용자가 볼 수 있도록 보기 페이지의 조각이 화면에 표시될 때 타이머를 실행하려고 할 때 이 문제가 발생했습니다.

타이머는 항상 사용자가 조각을 보기 직전에 시작되었습니다.는 이유는그 때문입니다.onResume()우리가 그 조각을 보기 전에 그 조각의 메소드를 볼 수 있습니다.

제 해결책은 검사를 하는 것이었습니다.onResume()법방. pagers fragmentfragment 8일 때 'foo()'라고.

@Override
public void onResume() {
    super.onResume();
    if(viewPager.getCurrentItem() == 8){
        foo();
        //Your code here. Executed when fragment is seen by user.
    }
}

이게 도움이 되길 바랍니다.저는 이 문제가 자주 발생하는 것을 보았습니다.이것이 제가 본 것 중 가장 간단한 해결책인 것 같습니다.다른 많은 것들은 하위 API 등과 호환되지 않습니다.

프래그먼트로 이동하기 전에 사용자가 로그인했는지 확인하는 간단한 구현 방법입니다.

기본 활동에서 onNavigationItem 내에서 이와 같은 작업을 수행할 수 있습니다.선택한 방법입니다.

 case R.id.nav_profile_side:


                if (User_is_logged_in) {

                    fragmentManager.beginTransaction()
                            .replace(R.id.content_frame
                                    , new FragmentProfile())
                            .commit();
                }else {

                    ShowLoginOrRegisterDialog(fragmentManager);

                }

                break;

그러나 탐색 드로어를 사용하는 경우, 드로어의 선택 항목이 프로파일 조각으로 이동하지 않았더라도 프로파일로 변경됩니다.

선택을 현재 선택으로 재설정하려면 아래 코드를 실행합니다.

        navigationView.getMenu().getItem(0).setChecked(true);

많이 늦을 수도 있습니다.이건 저한테 효과가 있어요.저는 @Gobar와 @kris Solutions의 코드를 약간 업데이트했습니다.우리는 우리의 코드를 업데이트해야 합니다.PagerAdapter.

setPrimaryItem탭이 표시되고 위치가 반환될 때마다 호출됩니다.위치가 같다면 우리는 움직이지 않는다는 뜻입니다.위치가 변경되고 현재 위치가 클릭된 탭이 아닌 경우 -1로 설정됩니다.

private int mCurrentPosition = -1;

@Override
public void setPrimaryItem(@NotNull ViewGroup container, int position, @NotNull Object object) {
    // This is what calls setMenuVisibility() on the fragments
    super.setPrimaryItem(container, position, object);
    if (position == mCurrentPosition) {
        return;
    }
    if (object instanceof YourFragment) {
        YourFragment fragment = (YourFragment) object;
        if (fragment.isResumed()) {
            mCurrentPosition = position;
            fragment.doYourWork();//Update your function
        }
    } else {
        mCurrentPosition = -1;
    }
}

코틀린에서

override fun onHiddenChanged(hidden: Boolean) {
    super.onHiddenChanged(hidden)

    // Your code goes here..
}

연결된 FragmentStatePagerAdapter의 Count 메서드를 재정의하여 숨길 페이지 수를 뺀 총 카운트를 반환하도록 합니다.

 public class MyAdapter : Android.Support.V13.App.FragmentStatePagerAdapter
 {   
     private List<Fragment> _fragments;

     public int TrimmedPages { get; set; }

     public MyAdapter(Android.App.FragmentManager fm) : base(fm) { }

     public MyAdapter(Android.App.FragmentManager fm, List<Android.App.Fragment> fragments) : base(fm)
     {
         _fragments = fragments;

         TrimmedPages = 0;
     }

     public override int Count
     {
         //get { return _fragments.Count; }
         get { return _fragments.Count - TrimmedPages; }
     }
 }

따라서 처음에 ViewPager에 3개의 조각이 추가되고 어떤 조건이 충족될 때까지 처음 2개만 표시되어야 하는 경우, TrimpageredPages를 1로 설정하여 페이지 수를 재정의하고 처음 2개만 표시해야 합니다.

이것은 끝에 있는 페이지에는 효과적이지만 처음이나 중간에 있는 페이지에는 별로 도움이 되지 않습니다. (여러 가지 방법이 있지만).

언급URL : https://stackoverflow.com/questions/10024739/how-to-determine-when-fragment-becomes-visible-in-viewpager

반응형