Chcę wyłączyć przesuwanie, ale tylko po prawej stronie. Znalazłem działające rozwiązanie w odpowiedzi na this. Niestety kopiuje to całe źródło ViewPager
, aby osiągnąć cel. Czy istnieją metody dziedziczące istniejącą klasę, a nie dublowanie?ViewPager wyłącza przesuwanie w określonym kierunku.
Odpowiedz
nie jestem pewien to jest dokładnie to, czego potrzebujesz: Potrzebowałem wizualizatora dla kreatora z maksymalną stroną, której użytkownik nie może przekazać.
Na koniec rozwiązanie było w adapterze. Zmieniłem rachubę PagerAdapter iw ten sposób blokuje użytkownikowi przechodzenie max strony:
@Override
public int getCount() {
return mProgress; //max page + 1
}
Gdy użytkownik przechodzi do następnej strony:
private void setWizardProgress(int progress) {
if(progress > mProgress) {
mProgress = progress;
mWizardPagerAdapter.notifyDataSetChanged();
}
}
W ten sposób, gdy użytkownik jest w maksymalna strona nie może przewinąć w prawo.
Dzięki! To jest stare pytanie, już to rozwiązałem (poprzez upuszczenie 'ViewPager' i użycie animacji' Fragment', aby całkowicie kontrolować przepływ). Myślę, że twoje jest dobre rozwiązanie, więc akceptuję to. :) – WonderCsabo
Musisz utworzyć własną ViewPager podklasy i przesłonić funkcję canScrollHorizontally
Po prostu próbowałem, canScrollHorizontally nigdy zostaje wywołany. : S – WonderCsabo
Następnie spróbuj metody canScroll, użyłem jej i nazywa się – viplezer
nigdy nie jest wywoływana ani – Thomas
Można spróbować następujących czynności:
Krok 1: utworzyć nowy zwyczaj klasa powiedzieć "CustomViewPager
". Klasa dziedziczy po "ViewPager
" i zawiera nową dostosowaną metodę o nazwie "setPagingEnabled
" w celu włączenia/wyłączenia przesuwania w zależności od wymagań.
Krok 2: Zastąp dwie metody: "onTouchEvent
" i "onInterceptTouchEvent
". Oba zwrócą "false
", jeśli stronicowanie ma zostać całkowicie wyłączone.
Krok 3: zastąpić "ViewPager
" tag w pliku arkusza doda klasy:
<package_name.customviewpager
android:id="@+id/customViewPager"
android:layout_height="match_parent"
android:layout_width="match_parent" />
Krok 4: CustomViewPager.java
public class CustomViewPager extends ViewPager {
private boolean enabled;
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
this.enabled = true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (this.enabled && detectSwipeToRight(event)) {
return super.onTouchEvent(event);
}
return false;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (this.enabled && detectSwipeToRight(event)) {
return super.onInterceptTouchEvent(event);
}
return false;
}
// To enable/disable swipe
public void setPagingEnabled(boolean enabled) {
this.enabled = enabled;
}
// Detects the direction of swipe. Right or left.
// Returns true if swipe is in right direction
public boolean detectSwipeToRight(MotionEvent event){
int initialXValue = 0; // as we have to detect swipe to right
final int SWIPE_THRESHOLD = 100; // detect swipe
boolean result = false;
try {
float diffX = event.getX() - initialXValue;
if (Math.abs(diffX) > SWIPE_THRESHOLD) {
if (diffX > 0) {
// swipe from left to right detected ie.SwipeRight
result = false;
} else {
// swipe from right to left detected ie.SwipeLeft
result = true;
}
}
}
catch (Exception exception) {
exception.printStackTrace();
}
return result;
}
}
Dzięki! Sprawdź swój kod, nie kompiluje! – WonderCsabo
ya, zaktualizowałem swój post. –
Próbowałem zaktualizowanej odpowiedzi. 'diffX' jest zawsze dodatni, więc metoda nigdy nie zwraca' true'. – WonderCsabo
private float initialXValue;
@Override
public boolean onTouchEvent(MotionEvent event) {
if (this.mEnabled) {
return super.onTouchEvent(event);
}
if(event.getAction()==MotionEvent.ACTION_DOWN){
initialXValue = event.getX();
}else if(event.getAction()==MotionEvent.ACTION_MOVE){
if(detectSwipeToRight(event)){
System.out.println("right swipe detected");
}
}
return true;
}
private boolean detectSwipeToRight(MotionEvent event) {
final int SWIPE_THRESHOLD = 100; // detect swipe
boolean result = false;
try {
float diffX = event.getX() - initialXValue;
if (Math.abs(diffX) > SWIPE_THRESHOLD) {
if (diffX < 0) {
// swipe from right to left detected ie.SwipeLeft
result = true;
}
}
} catch (Exception exception) {
exception.printStackTrace();
}
return result;
}
To byłaby znacznie lepsza odpowiedź, jeśli wyjaśnisz kod nieco więcej. – skrrgwasme
Można użyć metod beginFakeDrag()
i endFakeDrag()
.
beginFakeDrag()
jeśli chcesz wyłączyć przesunięcie i endFakeDrag()
, jeśli chcesz ponownie włączyć.
Jak to: viewPager.beginFakeDrag();
Nie, nie będzie działać ... Nadal przewija się przez chwilę ... – ichalos
Tu pracuje klasę ViewPager z możliwością wyłączenia jakiegokolwiek stronicowania kierunek. Sprawdź wszystkie answer here.
public class CustomViewPager extends ViewPager {
private float initialXValue;
private SwipeDirection direction;
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
this.direction = SwipeDirection.all;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (this.IsSwipeAllowed(event)) {
return super.onTouchEvent(event);
}
return false;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (this.IsSwipeAllowed(event)) {
return super.onInterceptTouchEvent(event);
}
return false;
}
private boolean IsSwipeAllowed(MotionEvent event) {
if(this.direction == SwipeDirection.all) return true;
if(direction == SwipeDirection.none)//disable any swipe
return false;
if(event.getAction()==MotionEvent.ACTION_DOWN) {
initialXValue = event.getX();
return true;
}
if(event.getAction()==MotionEvent.ACTION_MOVE) {
try {
float diffX = event.getX() - initialXValue;
if (diffX > 0 && direction == SwipeDirection.right) {
// swipe from left to right detected
return false;
}else if (diffX < 0 && direction == SwipeDirection.left) {
// swipe from right to left detected
return false;
}
} catch (Exception exception) {
exception.printStackTrace();
}
}
return true;
}
public void setAllowedSwipeDirection(SwipeDirection direction) {
this.direction = direction;
}
To coś działa. (Chociaż styl składni jest bardzo zły) – vedant1811
@ vedant1811 co jest złego w tym? – lelloman
@lelloman prawdopodobnie oznacza brak autoformatowania, IsSwipeAllowed z wielką pierwszą literą, try-catch, gdzie nie jest zgłaszany wyjątek, a także printStackTrace tam, i "to" w niepotrzebnych miejscach (i overriden metody mogą być rzeczywiście inline). Ale i tak odpowiedź jest pomocna. – 0101100101
Innym prostym sposobem jest użycie setCurrentItem(), aby przejść z powrotem do żądanej slajdu, jeśli trafisz pewną pozycję.Na przykład, pozwoli to tylko do przodu przesuwając:
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
@Override
public void onPageSelected(int position) {
if(position < mProgress) {
mViewPager.setCurrentItem(mProgress, true);
} else {
mProgress = position;
}
}
@Override
public void onPageScrollStateChanged(int state) {}
});
Lub jeśli chcesz mieć max slajd:
if(position > 4) {
mViewPager.setCurrentItem(4, true);
}
Rozwiązanie to technicznie nie całkowicie wyłączyć bezstykowa, jak będziesz jeszcze zobaczyć mała część niedozwolonego slajdu po wykonaniu ruchu machnięcia. Ale w przypadku niektórych aplikacji może to być preferowane.
Czy używasz wanilii ViewPager? – Shark
Jeśli istnieje lib, który zawiera 'ViewPager' z takim zachowaniem, mogę go używać BTW. Zauważ, że chcę dynamicznie włączać i wyłączać przesuwanie w prawo, a nie tylko wyłączać je statycznie. – WonderCsabo
Przypuśćmy, że możesz spróbować przesłonić TouchEvent lub onInterceptTouchEvent i spróbować odfiltrować zdarzenia dotykowe, na które nie chcesz reagować (i zadzwonić super do reszty). – Karakuri