2015-05-03 17 views
11

mam aktywny zawiera ViewPager, pierwszy fragment w tym ViewPager zawiera ListView i gdy klikam na jakikolwiek element zastępuje ten fragment o wybrany jeden, używam setCurrentItem(selectedItem,true)//for smooth scroll ale ViewPager ślizga się wszystkie fragmenty wcześniej wybranego fragmentu Chcę, aby przesunąć do wybranego fragmentu nie tylko w stosunku do wszystkich fragmentów Próbuję użyć PageTransfrom.transformPage jak tenViewPager setCurrentItem slajdów

@Override 
public void transformPage(View page, float position) { 
    int currentItem = viewPager.getCurrentItem(); 
    if (currentItem != selectedItem) 
     page.setVisibility(View.GONE); 
} 

ale bez powodzenia

+0

Czy używasz niestandardowego 'ViewPagerAdapter'? – Droidekas

Odpowiedz

4

Jednym z możliwych rozwiązań jest zmodyfikowanie PagerAdapter tak, aby zawsze zwracał żądaną stronę w punkcie # 2.

Po kliknięciu dowolnego elementu na pierwszej stronie najpierw zmień implementację metody getItem(int position) w PagerAdapter (jest to łatwe, jeśli Twój PagerAdapter jest zaimplementowany w pliku tej samej klasy kodu), aby zwrócić stronę, którą chcesz, gdy position == 2, a następnie zadzwoń setCurrentItem(2, true). Może to sprawić, że płynnie przejdziesz do wybranej strony bezpośrednio. Może być również konieczna zmiana getCount(), aby ograniczyć liczbę do 2, w przeciwnym razie następna strona może nie być oczekiwana.

Ale ta metoda powoduje odrzucenie pozostałych stron. Użytkownik może tylko przewinąć z powrotem na pierwszą stronę, a następnie przejść do następnej strony. Jeśli chcesz zachować naturalną kolejność stron przez ręczne przewijanie (nie poprzez kliknięcie), możesz przywrócić domyślną implementację getItem(int position) po zatrzymaniu się skórki (przez kliknięcie) i ponownie załadować zatrzymaną bieżącą stronę do naturalnego porządku, wywołując setCurrentItem(position, false) (natychmiast, nie płynnie tym razem), a następnie użytkownik może przewijać tam iz powrotem ręcznie.

+1

to jest najbliższy pomysł, ponieważ go rozwiązałem. –

+0

Cieszę się, że to działa: D –

0

Tak więc, jeśli rozumiem, że c orrectly, chcesz płynnie przewinąć do wybranego fragmentu, ale tylko od poprzedniego. Dobrze?

Po przejściu do pozycji setCurrentItem płynnie przewija z aktualnie wybranej pozycji. Tego nie można zmienić. Dlatego rozwiązaniem twojego problemu jest wykonanie 2-etapowej konfiguracji.

Najpierw użyj setCurrentItem (selectedItem-1, false), aby ustawić go na poprzedni element. Po zakończeniu tego przejścia wywołaj setCurrentItem (selectedItem, true).

Nie zrobiłem tego sam, ale przewiduję kilka komplikacji i szczególnych przypadków.

Jeśli połączysz jedno połączenie z setCurrentItem po drugim, prawdopodobnie nie będzie działać. Być może trzeba będzie nasłuchiwać zmiany pierwszej strony (przy użyciu OnPageChangeListener), aby wykonać drugie wywołanie setCurrentItem.

Występuje również poza zakresem, gdy wybrany element jest pierwszy.

Mam nadzieję, że to pomoże.

+0

setCurrentItem (selectedIndex-1, false) wyświetli element selectedIndex-1, więc nie będzie on dobry, ponieważ UX –

+0

i AFTER wybranego elementu-1 zakończy się, dokonasz płynnego przejścia do wybranego elementu. Tego właśnie chcesz, prawda? – shalafi

0

ViewPager nie jest właściwym narzędziem do tego, co próbujesz osiągnąć. Jeśli używasz ViewPager, dodaj Fragments jako strony i przewiń od strony 0 do 3 z pewnością przewiniesz z poziomu Page 0 -> Strona 1 -> Strona 2 -> Strona 3. Ogólnie rzecz biorąc, będzie to krok po kroku, gdy jeden krok odpowiada przejściu do następnej strony.

To, czego szukasz, to Descendant Navigation.

W twoim przypadku możesz zachować wszystkie implementacje fragmentów bez zmian.Po prostu host Fragment zawierający ListView w działaniu i gdy użytkownik wybierze element w nim, dodać odpowiedni Fragment z slide in transition.

Powodzenia.

0

Ogólnie rzecz biorąc, jak wielu już tu powiedziano, nie powinieneś używać ViewPagera, a także absolutnie do innych celów.

Myślę, że najprostszym sposobem jest pójść z tylko proste przełączanie fragment, na przykład:

yourListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
      @Override 
      public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) { 
       switch (position) { 
        case 0: 
         getSupportFragmentManager().beginTransaction().setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right) 
           .replace(R.id.content, MyFirstFragment.newInsance()).commit(); 
         break; 
        case 1: 
         getSupportFragmentManager().beginTransaction().setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right) 
           .replace(R.id.content, MySecondFragment.newInsance()).commit(); 
         /etc. 
       } 
      } 
     }); 

Więc będziesz mieć pełną kontrolę nad nim + możliwość ustawienia odpowiedniego wyglądu animacji dla każdego fragmentu.

Mam nadzieję, że masz mój pomysł.

0

I rozwiązać ten problem jak ten Mam jeden ViewPager (VP1) składa się z dwóch fragmentów, Fist jedna zawiera ListView przedmiotów, drugich fragmentów zawiera inny ViewPager (VP2) ja wsunąć do wybranego elementu bez suwaka nad wszystkimi poprzednimi przedmiotów, takich jak to gdy użytkownik kliknie na element na ListView

vp2.setCurrentItem(selectedItemIndex,false); 
vp1.setCurrentItem(1,true); 

pierwszy zestaw poz prąd na drugim viewpager bez suwaka, a następnie przesuń pierwszy viewpager, i to

0

trzeba zachować widoczny nie tylko wybrany element, ale także na e zostało wybrane wcześniej, jeśli chcesz, aby slajd był animowany od jednego do drugiego. Po wywołaniu setCurrentItem(selectedItem,true) wszystkie wywołania do viewPager.getCurrentItem() wewnątrz transformPage zwracają tę samą ustawioną wcześniej wartość, ale nie zmieniają się przez płynne przewijanie. Myślę, że można zrobić to w ten sposób z transformPage:

int prevSelFrag = 0, currentSelFrag = 0; //member variables 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    pager.setOnPageChangeListener(new OnPageChangeListener() { 
     @Override 
     public void onPageSelected(int pos) { 
      prevSelFrag = currentSelFrag; 
      currentSelFrag = pos; 
     } 

     @Override 
     public void onPageScrolled(int arg0, float arg1, int arg2) { 
     } 

     @Override 
     public void onPageScrollStateChanged(int arg0) { 
     } 
    }); 
    pager.setPageTransformer(false, new PageTransformer() { 
     @Override 
     public void transformPage(View page, float relativePosition) { 
      float transDiff = prevSelFrag - currentSelFrag; 
      if (transDiff > 1.0f || transDiff < -1.0f) { 
       boolean transIsToRight = transDiff < 0.0f; 
       if (transIsToRight && relativePosition < -1) { 
        page.setVisibility(View.GONE); 
       } else if (relativePosition > 1) { //trans is to left 
        page.setVisibility(View.GONE); 
       }else{ 
        page.setVisibility(View.VISIBLE); 
       } 
      }else{ 
       page.setVisibility(View.VISIBLE); 
      } 
     } 
    }); 
} 

relativePosition jest pozycja strony w stosunku do strony ustawionej na setCurrentItem, tak że dany View page musi iść do tej pozycji w animacji (ale nie w czasie rzeczywistym stan pager). Jeśli na przykład na stronie 0 i wywołać setCurrentItem(2,true) w transformPage można otrzymać:

  • aktualny pogląd na stronie 1 w relativePosition = -2
  • bieżącego widoku w stronę 0 z relativePosition = -1
  • prąd zobacz na stronie 2 z względną pozycją = 0

Oczywiście te wartości różnią się między sobą, aby uzyskać efekt przejścia. ViewPager smoothScroll nie działał dla mnie, musiał użyć tego rozwiązania, aby to naprawić ->https://stackoverflow.com/a/14776244/4282954

Powiązane problemy