setCurrentItem (0)을 호출 할 때 onPageSelected가 트리거되지 않습니다.
많은 사진을 표시하는 ViewPager가있는 활동이 있습니다. ViewPager가 시작되면 사용자가 이전 활동에서 선택한 항목에 따라 ViewPager의 위치가 설정됩니다. 갤러리와 비슷합니다.
새 페이지가 선택 될 때마다, 즉 활동이 처음 열릴 때 또는 사용자가 새 페이지로 슬라이드 할 때마다 onPageSelected가 호출되기를 원합니다.
다음과 같이 시작점을 설정했습니다.
mPager.setCurrentItem(index);
onPageSelected를 트리거하지 않기 때문에 인덱스가 0으로 설정된 setCurrentItem이 호출되는 경우를 제외하고 모든 것이 작동합니다.
mPager.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int index) {
Log.d(TAG, "onPageSelected " + index);
}
...
}
그래서 제 질문은; 이것이 버그입니까? 그렇다면 어떻게해야합니까?
지금까지 찾은 가장 깨끗한 솔루션은 ViewPager에서 설정 한 onPageChangeListener에 대한 참조를 가져 오는 것입니다 (ViewPager.getOnPageChangeListener () 메서드가 있다고 생각하지 않기 때문에), 그런 다음 ViewPager의 어댑터를 설정 한 후 , 전화 :
onPageChangeListener.onPageSelected(viewPager.getCurrentItem());
그러나 현재 인덱스에있는 페이지의 조각은 아직 인스턴스화되지 않았으므로 (적어도 FragmentStatePagerAdapter를 사용하는 경우) 실행 가능한 ala로 래핑해야 할 수 있습니다.
viewPager.post(new Runnable(){
@Override
public void run() {
onPageChangeListener.onPageSelected(viewPager.getCurrentItem());
}
});
또한 onPageSelected 처리기 내에서 조각에 대한 참조가 필요한 경우 직접 수행해야합니다. 인스턴스화 및 제거 메서드를 재정의하고 SparseArray에서 조각을 추가 / 제거하는 FragmentStatePagerAdapter에 추상 기본 클래스를 사용합니다.
좋아, 그래서 이것이 버그 (또는 기능)인지 알아낼 수 없었다. 하지만 문제에 대한 가능한 해결책이 어떻게 보일 수 있는지를 공유하고 싶습니다 ..
Activity의 메서드에서 수행하려는 기능을 작성한 다음 onPageSelected 메서드에서이를 호출합니다.
mPager.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int index) {
myOnPageSelectedLogic(index);
}
...
}
그리고 전화 직후
setCurrentItem(index);
활동에서 다음 if 문을 추가하십시오.
if(index == 0) {
myOnPageSelectedLogic(0);
}
너무 예쁘지는 않지만 누군가에게 도움이되기를 바랍니다. :)
사실 나는 이것이 BUG라고 생각합니다. ViewPager의 소스 코드를 확인하고 onPageSelected 의 유일한 트리거를 찾았습니다 .
if (dispatchSelected && mOnPageChangeListener != null) {
mOnPageChangeListener.onPageSelected(item);
}
위에서 변수 dispatchSelected 는 코드에 의해 결정됩니다.
final boolean dispatchSelected = mCurItem != item;
//item is what you passed to setCurrentItem(item)
그리고 mCurItem 변수 는 다음과 같이 정의되고 초기화됩니다.
private int mCurItem; // Index of currently displayed page.
따라서 mCurItem 은 기본값이 0입니다. setCurrentItem (0)을 호출 할 때 dispatchSelected 는 false이므로 onPageSelected ()가 전달되지 않습니다.
이제 setCurrentItem (0) 호출이 문제가되는 반면 setCurrentItem (1, 또는 2, 3 ...)은 그렇지 않은 이유를 이해해야합니다.
이 문제를 해결하는 방법 :
ViewPager 코드를 자신의 프로젝트에 복사하고 수정합니다.
from final boolean dispatchSelected = mCurItem != item; //the old line to final boolean dispatchSelected = mCurItem != item || mFirstLayout; //the new line
그런 다음 자신의 ViewPager를 사용하십시오.
의식적으로 setCurrentItem (0)을 호출하고 OnPageChangedListener를 참조 했으므로 onPageSelected ()를 직접 전달하십시오.
听 楼下 怎么 说 ...
다음 솔루션이 저에게 효과적입니다. 즉, 뷰 페이저가 처음로드 될 때와 사용자 스크롤 또는 setCurrentItem (x) 호출에서 모든 후속 선택에 대해 위치 0에서 콜백을받습니다. 나는 원하지 않는 행동을 관찰하지 않았습니다.
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if (positionOffsetPixels == 0) {
//Do something on selected page at position
}
}
@Override
public void onPageSelected(int position) {}
@Override
public void onPageScrollStateChanged(int state) {}
});
onPageSelected
is not triggered for page which is opened first. For this case I manually perform all needed actions. Also, I suppose that call to onPageSelected(0)
should work too.
You can extend the ViewPager
and call the Listener by yourself when the position is changed from 0 to 0
public class BetterViewPager extends ViewPager {
public BetterViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
// we some the listner
protected OnPageChangeListener listener;
@Override
public void setOnPageChangeListener(OnPageChangeListener listener) {
super.setOnPageChangeListener(listener);
this.listener = listener;
}
@Override
public void setCurrentItem(int item) {
// when you pass set current item to 0,
// the listener won't be called so we call it on our own
boolean invokeMeLater = false;
if(super.getCurrentItem() == 0 && item == 0)
invokeMeLater = true;
super.setCurrentItem(item);
if(invokeMeLater && listener != null)
listener.onPageSelected(0);
}
}
public class PageChangeListener implements ViewPager.OnPageChangeListener {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_IDLE && getCurrentItem() == 0) {
//this indicate viewpager finish scroll and page at position 0 is selected.
}
The simplest solution will be using of function e.g.
viewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrollStateChanged(int state) {}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
@Override
public void onPageSelected(int position) {
onPage(position);
}
});
// call first time
onPage(0);
private void onPage(int position) {
//...
}
If the ViewPager is in a fragment, in the onViewCreated method, call mPager.setOnPageChangeListener(this)
if you don't care screen animotion try
pager.setCurrentItem(1);
pager.setCurrentItem(0);
'IT Share you' 카테고리의 다른 글
파일 찾기에서 정규식을 사용하는 방법 (0) | 2020.12.03 |
---|---|
Python으로 ASCII 테이블을 어떻게 예쁘게 인쇄 할 수 있습니까? (0) | 2020.12.03 |
PHP를 사용한 Python SimpleHTTPServer (0) | 2020.12.03 |
Mac OSX Java 터미널 버전이 잘못되었습니다. (0) | 2020.12.03 |
Selenium WebDriverException을 수정하는 방법 : 연결하기 전에 브라우저가 종료 된 것 같습니다. (0) | 2020.12.03 |