10

Ich versuche, einige visuelle Anzeige hinzuzufügen, dass es keine weiteren Seiten in der gewünschten Schleuderrichtung im ViewPager gibt. Ich kämpfe jedoch, um einen Platz zu finden, wo man relevanten Code einbringen kann.visuelle Anzeige von Über Scroll in Android

Ich habe versucht, ViewPager-Klasse mit folgendem Code zu erweitern, aber der Toast wird nicht angezeigt (ev.getOrientation() gibt immer 0 zurück). Ich habe auch das gleiche mit historischen Punkten versucht, aber ev.getHistorySize() gibt auch 0 zurück.

Was vermisse ich?

Klasse Beispiel:

public class CustomViewPager extends ViewPager { 

    public CustomViewPager(Context context) { 
     super(context); 
    } 

    public CustomViewPager(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    /** 
    * @see android.support.v4.view.ViewPager#onTouchEvent(android.view.MotionEvent) 
    */ 
    @Override 
    public boolean onTouchEvent(MotionEvent ev) { 
     boolean result = super.onTouchEvent(ev); 

     switch (ev.getAction() & MotionEventCompat.ACTION_MASK) { 
      case MotionEvent.ACTION_MOVE: 
       if (ev.getOrientation() > 0) { 
        Toast.makeText(getContext(), "left", 0).show(); 
       } 
     } 

     return result; 
    } 
} 

Antwort

-1

Regel mit ViewPager, verwendet man eine PagerAdapter wie FragmentPagerAdapter oder FragmentStatePagerAdapter die ViewPager mit Inhalten fluten (Ihre Inhalte Ansichten sein werden).

Jetzt, wenn Sie eine PagerAdapter verwenden, haben Sie eine Methode namens getCount(), http://developer.android.com/reference/android/support/v4/view/PagerAdapter.html#getCount%28%29, die Ihnen die Größe des Inhalts geben wird.

Da Sie jetzt wissen, die Größe können Sie eine Nachricht mit einer if-Anweisung leicht anzeigen.

Versuchen Sie diesen Code: http://developer.android.com/reference/android/support/v4/view/ViewPager.html

Anmerkung: Ich glaube nicht, dass Sie einen benutzerdefinierten ViewPager benötigen. Sie müssen auch Fragmente für ViewPager verstehen. Sieh dir Beispiele in ApiDemos an. Es ist eine großartige Quelle.

+0

Das ist nicht das, was er hat gefragt. Er wollte genau wissen, wie man einen Overscroll-Effekt wie das Gummiband auf iOS macht, das in ViewPager zumindest bis ICS fehlt. –

1

Sie haben viele Optionen, Sie können einen Toast anzeigen, einen Dialog anzeigen, eine TextView oder ein Bild über Ihrer UI anzeigen usw. Oder Sie kennen die Anzahl der View-Elemente im ViewPager anders Zeigen Sie an den Positionen 0 und/oder n + 1 mit der Nachricht an und lassen Sie sie zur letzten Ansicht springen, die Ihre Daten enthält.

könnten Sie implementieren:

viewPager.setOnPageChangeListener(new OnPageChangeListener() { 
    public void onPageSelected(int position) { 
     //TODO If position is the 0 or n item, add a view at 0 or at n+1 to indicate there is no more pages with data. 
    } 

    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 
     // TODO Show a Toast, View or do anything you want when position = your first/last item; 
    } 

    public void onPageScrollStateChanged(int state) { 
    } 
}); 
+2

Es gibt einen Systemstandard-Leuchteffekt, wenn Sie versuchen, über das Ende eines ViewPagers hinaus zu blättern. Dies ist derselbe Vorgang wie beim Scrollen über den unteren Rand einer Liste. Ich möchte so etwas - aber es sollte auf allen Versionen (das aktuelle Glühen ist nur ICS) funktionieren. Ihre Vorschläge würden für eine klobige Benutzeroberfläche sorgen, und wenn das wirklich die einzigen Optionen sind, dann werde ich ohne Angabe bleiben. –

+0

Ich weiß, und es ist genug für meine App, aber wenn @Ekramus fragte, nehme ich an, weil er etwas mehr braucht. :) –

0

Sie die setUserVisibleHint (boolean) Funktion in Fragmente überlasten können. Pseudo-Code:

void setUserVisibleHint(boolean isVisibleToUser) { 
     // If this fragment is becoming visible 
     if (isVisibleToUser == true) { 
      // Check if it is the last fragment in the viewpager 
      if (indexOfThis == getActivity().indexOfLast) { 
       // Display right limit reached 
       Toast(..., "No more Frags to right",...) 
       } 
      // Check if it is the first fragment in the viewpager 
      else if (indexOfThis == getActivity().indexOfFirst) { 
       // Display Left Limit reached 
       Toast(..., "No more Frags to left",...) 
      } 
     } 
    } 

Ich habe diese Funktion nicht für diesen Zweck verwendet werden, haben aber aus anderen Gründen verwendet und es tut Feuer angemessen. Hoffe, das hilft ...

+0

Dies hat die gleichen Auswirkungen auf die Benutzeroberfläche wie Oscars Antwort, außer dass es eine Methode überschreibt, die nicht überschrieben werden soll, anstatt einen Listener zu verwenden, was gefährlich erscheint. –

19

Wenn Sie sich die v4 Support-Bibliothek ansehen, sehen Sie eine Klasse namens ViewPager namens EdgeEffectCompat (dies liefert den Leuchteffekt, wenn Sie den Anfang oder das Ende eines View Pagers in ICS + erreichen) Wenn Sie sich die Implementierung in der compat-Bibliothek ansehen, werden Sie sehen, dass sie eine if-Anweisung hat, um zu sehen, ob die Build-Version 14+ (ICS) ist oder nicht. Wenn dies der Fall ist, endet es schließlich (wenn Sie lange genug nachzeichnen) unter Verwendung der normalen Klasse EdgeEffect, die in ICS eingeführt wurde. Ansonsten verwendet es BaseEdgeEffectImpl, das im Grunde nichts enthält.

Wenn Sie möchten, können Sie Ihren eigenen benutzerdefinierten ViewPager erstellen, der Ihren eigenen EdgeEffect verwendet. Sie können den android Quellcode sehen, um zu sehen, wie sie EdgeEffect here implementiert haben, das Sie ziemlich kopieren können (kopieren Sie einfach die overscroll_edge und overscroll_glow Zeichen in den AOSP/res/Zeichnungsverzeichnissen zu Ihrem eigenen Projekt, da sie intern zu android sind) oder mach weiter und erstelle deine eigene Version.

Viel Glück.

(Übrigens, das ist, wie sie die cool aussehende Rand Kippeffekt im Startmenü auf ICS erstellen ... so können Sie ziemlich viel wie kreativ sein, wie Sie mit diesem wollen;)

+0

Das sieht so aus als würde es das tun! Vielen Dank. –

7

Ich habe versucht, um genau den gleichen Effekt zu erzielen, der in dieser Frage gestellt wurde. Ich kämpfe damit und dann lese ich @ wnafee antwort (ich konnte es nicht mit raus machen).

Aber dann habe ich Mühe zu implementieren, was klang ziemlich einfach aus der Antwort. Ich hatte so viele Probleme mit der Implementierung, dass ich die Antwort vielleicht nicht richtig verstanden habe, aber es gab zu viele Probleme mit nicht zugänglichen APIs, da ich nicht im selben Paket der Kompatibilitätsbibliothek arbeitete.

Nachdem ich einige Ansätze versucht hatte (keine von ihnen gelungen, und sie waren ziemlich kompliziert) ging ich in eine etwas andere Richtung, und jetzt funktioniert es wie ein Charme. Ich habe einige Überlegungen angestellt, für diejenigen, die es nie benutzt haben, mach dir keine Sorgen, es ist wirklich die Grundlage der Reflexion.

Ich bin nicht sicher, ob es die beste Lösung da draußen ist, aber es hat für mich funktioniert, also wenn Sie es verwenden möchten, sind Sie willkommen. Bitte lesen Sie das Wnafee-Beispiel, da es einige der Dinge erklärt, die ich gemacht habe.

Um diese Aufgabe zu erfüllen, sollten Sie nur meine drei Teile Lösung folgen. (Werden Sie zwischen 3-10 Minuten)

Teil I:

Wie Wnafee sagte ich meine eigene EdgeEffect Klasse nur durch Kopie gemacht, den Quellcode von here einfügen,

(nur stellen sie sicher, die overscroll_edge zu kopieren und overscroll_glow Drawables in den AOSP/res/ziehbar Verzeichnisse Ihr eigenes Projekt , da sie zu android intern sind)

Ich habe nur zwei wirklich kleine Änderungen:

  1. Ich erkläre, dass die Klasse erweitert EdgeEffectCompat (ich meine Klasse EdgeEffectForEarlyVersions genannt). public class EdgeEffectForEarlyVersions extends EdgeEffectCompat. Der Grund für diese Änderung ist, dass die mLeftEdge und mRightEdge vom Typ EdgeEffectCompat sind.
  2. In der ersten Zeile des Konstruktors von "meine" neue Klasse habe ich einen Aufruf an den übergeordneten Konstruktor super(context); hinzugefügt. Da es keinen Standardkonstruktor für EdgeEffectCompat gibt, müssen Sie den Konstruktor explizit aufrufen.

Teil II

Außerdem schrieb ich eine andere Funktion. Der Zweck der Funktion ist, dass wir im Falle einer frühen Version (vor ICS) die EdgeEffectForEarlyVersions verwenden möchten, die wir gerade kopiert haben. Um diesen Zweck zu erreichen, habe ich nachgedacht.

Dies ist die Funktion:

private static void changeEdgeEffectCompactOnEarlyVersions(ViewPager viewPager, Context context) 
{ 
    /* In case that the version is earlier than 14 there is only empty implementation for the edge effect, therefore we change it. 
    * for more information look on the following links: 
    * 1. http://stackoverflow.com/questions/10773565/visual-indication-of-over-scroll-in-android 
    * 2. http://grepcode.com/file/repo1.maven.org/maven2/com.google.android/support-v4/r7/android/support/v4/view/ViewPager.java#ViewPager.0mLeftEdge 
    * 3. http://grepcode.com/file/repo1.maven.org/maven2/com.google.android/support-v4/r7/android/support/v4/widget/EdgeEffectCompat.java#EdgeEffectCompat 
    */ 

    if (Build.VERSION.SDK_INT < 14) 
    { 
     try 
     { 
      Class<ViewPager> viewPagerClass = ViewPager.class; 
      //Get the left edge field, since it is private we used getDeclaredField and not getDeclared 
      Field leftEdge = viewPagerClass.getDeclaredField("mLeftEdge"); 
      leftEdge.setAccessible(true); 
      //Get the right edge field, since it is private we used getDeclaredField and not getDeclared 
      Field rightEdge = viewPagerClass.getDeclaredField("mRightEdge"); 
      rightEdge.setAccessible(true); 

      EdgeEffectForEarlyVersions leftEdgeEffect = new EdgeEffectForEarlyVersions(context); 
      EdgeEffectForEarlyVersions rightEdgeEffect = new EdgeEffectForEarlyVersions(context); 

      //Set the mLeftEdge memeber of viewPager not to be the default one, but to be "our" edgeEffect 
      leftEdge.set(viewPager, leftEdgeEffect); 
      //Set the mRightEdge memeber of viewPager not to be the default one, but to be "our" edgeEffect 
      rightEdge.set(viewPager, rightEdgeEffect);    
     } 
     catch (Exception ex) 
     { 
      Log.e("refelection", ex.getMessage()); 
     } 

    } 
} 

Teil III

Jetzt alles, was es zu tun bleibt, ist, dass die Funktion aufrufen, nachdem Sie die ViewPager Instanz und nichts mehr haben.

Ich hoffe, es wird jemandem helfen.

+0

Dies funktioniert nicht mit API <= 8. (in der letzten Version 11) mit v4 compat lib. Weil es BaseViewCompatImpl verwendet, das immer OVER_SCROLL_NEVER zurückgibt, wenn nach dem Overscroll-Modus gefragt wird. In der onDraw() überspringt es dann die Zeichnung der Über-Rolle ... – Nick

1

nur zur Ergänzung von @goBeepit dev Antwort, wenn Sie Ihre eigenen Edgeffect-Klasse erstellen und Sie erweitern von EdgeEffectCompat einige Methoden erfordert, boolean. Sie können diese Methoden auf booleschen Typ ändern und dann auf jeden Fall True zurückgeben. So funktioniert alles gut