2015-05-03 7 views
11

ich eine Aktivität haben, enthält ViewPager, erste Fragment in diesem ViewPager enthält Listview und wenn ich auf ein beliebiges Element klicken ersetzt es dieses Fragment mit einem ausgewählten, ich setCurrentItem(selectedItem,true)//for smooth scroll aber ViewPager schiebt alle Fragmente über vor Fragment ausgewählt ich will es nur an ausgewählte Fragment gleiten nicht über alle Fragmente ich versuchte PageTransfrom.transformPage wie dieViewPager setCurrentItem Slide

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

zu verwenden, aber ohne Glück

+0

Verwenden Sie einen benutzerdefinierten 'ViewPagerAdapter'? – Droidekas

Antwort

4

Eine mögliche Lösung besteht darin, den PagerAdapter so zu ändern, dass immer die gewünschte Seite auf Element 2 zurückgegeben wird.

Wenn Sie auf ein Element von der ersten Seite klicken, ändern Sie zunächst die Implementierung der Methode getItem(int position) des PagerAdapter (dies ist einfach, wenn Ihr PagerAdapter in derselben Klassendatei Ihres Codes implementiert ist), um die Seite zurück zu senden wollen, wenn position == 2, und rufen Sie dann setCurrentItem(2, true). Dies könnte direkt zu der ausgewählten Seite führen. Möglicherweise müssen Sie auch getCount() ändern, um die Anzahl auf nur 2 zu begrenzen, andernfalls ist die nächste Seite möglicherweise nicht die erwartete.

Aber diese Methode gibt die anderen Seiten frei. Der Benutzer konnte nur zur ersten Seite zurückblättern und dann zu einer anderen Seite navigieren. Wenn Sie die natürliche Reihenfolge der Seiten durch manuelles Blättern (nicht durch Klicken) beibehalten möchten, können Sie getItem(int position) zu Ihrer Standardimplementierung wiederherstellen, sobald der Bildlauf (durch Klicken) beendet wird, und die angehaltene aktuelle Seite durch Aufruf von setCurrentItem(position, false) erneut in die natürliche Reihenfolge laden. sofort, diesmal nicht reibungslos), dann kann der Benutzer manuell vor- und zurückblättern.

+1

Das ist die nächste Idee, wie ich es gelöst –

+0

Freut mich zu hören, dass funktioniert: D –

0

Also, wenn ich verstehe, Sie c Oder Sie möchten einen sanften Bildlauf zum ausgewählten Fragment, aber nur zum vorherigen. Recht?

Wenn Sie true an setCurrentItem übergeben, wird die aktuelle Position glatt geblättert. Dies kann nicht geändert werden. Daher besteht die Lösung für Ihr Problem darin, eine zweistufige Konfiguration vorzunehmen.

Verwenden Sie zuerst setCurrentItem (selectedItem-1, false), um es auf das vorherige Element zu setzen. Sobald dieser Übergang abgeschlossen ist, rufen Sie setCurrentItem (selectedItem, true) auf.

Ich habe das nicht selbst gemacht, aber ich sehe ein paar Komplikationen und Sonderfälle voraus.

Wenn Sie einen Aufruf von setCurrentItem nach einem anderen setzen, wird es wahrscheinlich nicht funktionieren. Möglicherweise müssen Sie auf den ersten Seitenwechsel warten (mithilfe von OnPageChangeListener), um den zweiten Aufruf von setCurrentItem auszuführen.

Auch gibt es die Out-of-Grenzen, wenn das ausgewählte Element das erste ist.

Hoffe, das hilft.

+0

setCurrentItem (selectedIndex-1, false) zeigt das Element selectedIndex-1 an, so dass es nicht gut ist, da UX –

+0

und NACH dem Ende von selectedItem-1 der Übergang zum selectedItem erfolgt. Das willst du, oder? – shalafi

0

ViewPager ist nicht das richtige Werkzeug für das, was Sie erreichen möchten. Wenn Sie ViewPager verwenden, fügen Sie als Seiten hinzu, und blättern Sie von Seite 0 bis 3, es wird definitiv von Seite 0 -> Seite 1 -> Seite 2 -> Seite 3 scrollen. Im Allgemeinen wird es einen Schritt nach dem anderen gehen, wobei ein Schritt dem Bewegen zur nächsten Seite entspricht.

Was Sie suchen, ist Descendant Navigation.

In Ihrem Fall können Sie alle Fragment-Implementierungen beibehalten, wie sie sind.Host einfach die Fragment enthält die ListView in einer Aktivität und wenn der Benutzer wählt ein Element in ihm, fügen Sie die entsprechende Fragment mit einer slide in transition.

Viel Glück.

0

Im Allgemeinen, wie viele bereits hier gesagt haben, sollten Sie ViewPager nicht verwenden, auch nicht für andere Zwecke.

Ich denke, dass einfachste Weg ist, mit nur einfachem Fragmente Schalt zu gehen, zum Beispiel:

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. 
       } 
      } 
     }); 

So erhalten Sie volle Kontrolle darüber haben + Möglichkeit der richtige Animation für jedes Fragment Aussehen zu setzen.

Ich hoffe, Sie haben meine Idee.

0

ich dieses Problem wie dieses gelöst Ich habe eine ViewPager (VP1) zwei Fragment, Faust ein Listview der Elemente enthält, enthält der zweiten Fragmente eine andere ViewPager (VP2) I an ausgewählte Artikel gleiten, ohne gleiten über alle bisherigen Produkte wie dies wenn Benutzer klicken Sie auf Artikel auf Listview

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

erstes Satz aktuelles Element auf dem zweiten viewpager ohne Rutsche, und dann die ersten viewpager gleiten, und das ist es

0

Sie haben sichtbar zu halten, nicht nur das ausgewählte Element aber auch das auf e, das zuvor ausgewählt wurde, wenn die Folie von einem zum anderen animiert werden soll. Nach dem Aufruf setCurrentItem(selectedItem,true), alle Aufrufe an viewPager.getCurrentItem() innerhalb transformPage gibt den gleichen Wert zurück, den Sie zuvor festgelegt haben, es ist nicht, dass es durch Smooth Scroll geändert wird. Ich denke, man kann mit transformPage es auf diese Weise tun:

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); 
      } 
     } 
    }); 
} 

relative ist die Seite Position relativ zur Seite auf setCurrentItem gesetzt, so dass die gegebenen View page in der Animation zu dieser Position gehen (aber nicht in Echt Pagerzustand). Wenn Sie zum Beispiel auf der Seite 0 und ruft setCurrentItem(2,true) in transformPage können Sie erhalten:

  • aktuelle Ansicht auf Seite 1 mit relativem = -2
  • aktueller Ansicht in Seite 0 mit relativem = -1
  • Strom Ansicht auf Seite 2 mit relativerPosition = 0

Natürlich variieren diese Werte zwischen ihnen, um den Übergangseffekt zu machen. ViewPager smoothScroll hat nicht für mich funktioniert, musste diese Lösung verwenden, um das zu beheben ->https://stackoverflow.com/a/14776244/4282954