Erklärung ViewPager

  • Antworten:14
  • Geschlossen
Gelöschter Account
  • Forum-Beiträge: 227

25.10.2014, 16:37:07 via Website

Hallo, ich habe folgendes Beispiel zum ViewPager gefunden.
Könnte mir jemand dieses vl kurz erklären wie es genau funktioniert?

MainActivity:

package in.wptrafficanalyzer.viewpagerdemo;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.view.ViewPager;
import android.view.Menu;

public class MainActivity extends FragmentActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        /** Getting a reference to the ViewPager defined the layout file */        
        ViewPager pager = (ViewPager) findViewById(R.id.pager);

        /** Getting fragment manager */
        FragmentManager fm = getSupportFragmentManager();

        /** Instantiating FragmentPagerAdapter */
        MyFragmentPagerAdapter pagerAdapter = new MyFragmentPagerAdapter(fm);

        /** Setting the pagerAdapter to the pager object */
        pager.setAdapter(pagerAdapter);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
}

MyFragment:

package in.wptrafficanalyzer.viewpagerdemo;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;


public class MyFragment extends Fragment{

    int mCurrentPage;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        /** Getting the arguments to the Bundle object */
        Bundle data = getArguments();

        /** Getting integer data of the key current_page from the bundle */
        mCurrentPage = data.getInt("current_page", 0);

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.myfragment_layout, container,false);             
        TextView tv = (TextView ) v.findViewById(R.id.tv);
        tv.setText("You are viewing the page #" + mCurrentPage + "\n\n" + "Swipe Horizontally left / right"); 
        return v;       
    }
}

MyFragment Pager:

package in.wptrafficanalyzer.viewpagerdemo;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

public class MyFragmentPagerAdapter extends FragmentPagerAdapter{

    final int PAGE_COUNT = 5;

    /** Constructor of the class */
    public MyFragmentPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    /** This method will be invoked when a page is requested to create */
    @Override
    public Fragment getItem(int arg0) {

        MyFragment myFragment = new MyFragment();
        Bundle data = new Bundle();
        data.putInt("current_page", arg0+1);
        myFragment.setArguments(data);
        return myFragment;
    }

    /** Returns the number of pages */
    @Override
    public int getCount() {     
        return PAGE_COUNT;
    }

    @Override
    public CharSequence getPageTitle(int position) {        
        return "Page #" + ( position + 1 );
    }
}

activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
    >
        <android.support.v4.view.PagerTabStrip
            android:id="@+id/pager_tab_strip"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="top"
            android:background="#33b5e5"
            android:textColor="#fff"
            android:paddingTop="4dp"
            android:paddingBottom="4dp" />

    </android.support.v4.view.ViewPager>

</RelativeLayout>

my_fragment_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/tv"    
    android:layout_width="match_parent"
    android:layout_height="match_parent" 
    android:gravity="center"    
    >    
</TextView>   

pepperonas
  • Forum-Beiträge: 434

25.10.2014, 17:10:46 via Website

Hehe, was willst du denn genau wissen?

Die Kommentierungen sind zwar englisch, aber das zu verstehen, sollte ja nicht das Problem sein.

Du hast eine MainActivity, in der du einen FragmentManager beziehst und der übernimmt dann mittels der Adapter die Verwaltung (besser: Positionierung) der einzelnen Fragmente.

Ist kein Hexenwerk, aber vielleicht hast du auch etwas die falsche Frage gestellt...
... jedenfalls sollte man grob wissen, wie Fragmente an sich funktionieren, bevor man sich den ViewPager ansieht.

Vielleicht hilfts deinem Vorstellungsvermögen aber auch schon, wenn du den Code mal mit ein paar Logcat-Ausgaben ausstattest und die Augen auf die Konsole richtest und unnötigen Code (zB das Options-Menü;) erst mal streichst :)

Open Source

Gelöschter Account
  • Forum-Beiträge: 227

25.10.2014, 19:51:25 via Website

Hallo, danke für die Erklärung.
Ist es möglich, das ich ein ListView habe und beim Auswählen von z.b. Element 3 komme ich im ViewPager zum Element 3. Wenn ich dann nach links wische zum Element 2 und durch rechts wischen zum Element 4 komme?
Wie könnte ich das realisieren?
Ich habe schon das ListView und kann schon durch klicken auf ein Element zum ViewPager (wie bsp oben) wechseln.

Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

26.10.2014, 07:00:38 via App

Das kommt darauf an wie deine Bestehende Logik aussieht, ist der View Pager in einer eigenen Activtiy?
Wenn ja kannst du über einen Intent eine bestimmte Position mitgeben.
Das mit dem gewünschetn wischen wird ein bisschen problematisch da ein ViewPager eige tlich nur für eine Bestimmte Reihenfolge (12345...)
nach rechts gewischt gedacht ist.
M8t ettas überlegung kannst du das ganze aber dynamisch machen, sodass dein Vorhaben funktioniert

LG Pascal //It's not a bug, it's a feature. :) ;)

Gelöschter Account
  • Forum-Beiträge: 227

26.10.2014, 17:22:42 via Website

Okay, ja der View Pager kommt in eine eigene Activity. Dann mach ich mal das mit dem Intent (Position übergeben) und überlegt mir die nächsten Schritte.

pepperonas
  • Forum-Beiträge: 434

27.10.2014, 00:35:16 via Website

Hmm, meines Wissens ist die Intentübergabe genau das, was man mit dem ViewPager vermeiden möchte, da er mit Fragmenten arbeitet.
Habe den ViewPager aber selbst auch nur bei einer App genutzt, müsste mich nochmal einlesen, um eine sichere Antwort geben zu können.

Open Source

Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

27.10.2014, 07:34:28 via App

@Martin: Das stimmt schon, aber wenn dein Viewpager mit allen Fragments in einer Anderen Activity ist, wie soll man das sonst machen.
Ich meine Ja nicht, dass alle Fragments plötzlich mit intents aufgerufen werden. Das wäre ja ganz blöde..

LG Pascal //It's not a bug, it's a feature. :) ;)

pepperonas
  • Forum-Beiträge: 434

27.10.2014, 21:11:32 via Website

@Pascal: Hmm, jo.. das Einzige was mir auf die Schnelle einfallen würde, wäre über einen ClickListener (bzw. über TouchEvents) den FragmentManager anzusteuern und dort die Transaction je nach "Vorgabe" unterschiedlich zu behandeln. Ob das funktioniert weiß ich allerdings auch nicht wäre auf jeden Fall mal interessant herauszufinden (wäre wahrscheinlich so eine Art "Try&Error"-Implementierung)^^
Nachteilhaft ist bei diesem Konzept auf jeden Fall, dass wohl ein Großteil des Codes just in Time erstellt werden müsste, ggf. wird die App dann für ältere Geräte unbrauchbar, da eventuell zu langsam.. Aber das sind nur wilde Spekulationen meinerseits, gut möglich, dass es mit dieser Vorgehensweise gar nicht funktioniert.

Insgesamt sind Fragmente zwar eine schöne Sache, aber "ob man sie wirklich immer braucht nur weil man sie nutzen könnte" ist fraglich und da bin ich wieder voll deiner Meinung und denke dass sich Einsteiger durch die Wahl von Intents einige unschöne Erscheinungen ersparen (Nullptr, Parent-View und einen erweiterten Lifecycle, der es wirklich in sich hat - um ein paar potenzielle Fehlerquellen zu nennen)... Und selbst Intents können es mit ihren Launch-Modes noch ziemlich in sich haben, wenn man "besondere Funktionalitäten" anbieten will (zB das Wechseln von Themes)

Open Source

Gelöschter Account
  • Forum-Beiträge: 227

30.10.2014, 18:12:00 via Website

Ich fass nochmal kurz zusammen wie ich mir das genau vorstelle bzw. vielleicht gibt es ja eine einfachere Lösung.

Ich habe eine ListView mit z.b. 12 Autos. Wenn ich jetzt in der ListView "Auto 3" auswähle (-> nächste Activity) mochte ich mit dem ViewPager alle Daten zum Auto anzeigen. Nun sollte man durch "wischen" auch zu den anderen Autos welche in des ListView sind kommen ohne dabei zurück zu ListView zu müssen (sollte aber trotzdem möglich sein, mit zurück in die ListView zu kommen und ein anderes Auto auszuwählen).

Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

30.10.2014, 18:15:26 via App

Ist locker umsetzbar.
Dafür musst du dich aber gründlich in Fragments und Viwepager etc. einlesen Dann geht das klar

— geändert am 30.10.2014, 18:15:53

LG Pascal //It's not a bug, it's a feature. :) ;)

pepperonas
  • Forum-Beiträge: 434

31.10.2014, 00:52:59 via Website

Kleiner Tipp zum Einstieg:
die Methode getActivty()ist so mit einer der Dreh und Angelpunkte für das Arbeiten mit Fragmenten. Auch wenn man damit schon relativ viel bewerkstelligen kann, trifft es das, was Pascal geschrieben hat, sehr gut. Gründliches Einlesen ist auf jeden Fall notwendig, um nicht am Ende mit halbfertigen Activities und haufenweise Nullpointern da zustehen. :)
"Einfach Ausprobieren ist in Android meistens schlecht - bei Fragmenten komplett sinnlos" <- das ist jedenfalls die Erfahrung, die ich gemacht habe :D

Open Source

Gelöschter Account
  • Forum-Beiträge: 227

01.11.2014, 16:10:16 via Website

Hallo, wie bekomme ich das hin, wenn ich ein Array habe welches dann das ListView füllt, das ich dann die Anzahl der Elemente im Array und den Namen an den PageViewer übergebe? Damit ich immer in der Überschrift den Namen habe bzw. weis wie viele Pages ich erstellen muss.

Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

01.11.2014, 16:22:38 via Website

Da du ein Array hast, was bietet sich an??
Lies einfach die Arraygröße aus, dann hast du die Anzahl der pages.
Wenn du die Überschriften ebenso in einem Array hast, dann ist das ganze kein Problen, denn dann muss du in public CharSequence getPageTitle(int position) nur den String des Array an der aktuellen postition lesen.

LG Pascal //It's not a bug, it's a feature. :) ;)

Gelöschter Account
  • Forum-Beiträge: 227

01.11.2014, 16:55:01 via Website

Also ich habe folgendes Array für die ListView

String[] values = new String[] {
"Item1",
"Item2",
"Item3",
};

Ich kann schon wenn Item2 gedrückt ist den Namen (Item2) in die nächste Activity übergeben.
Da die nächste Activity der ViewPager ist, brauche ich ja noch die Anzahl der Elemente (=Anz. der Pages) und eig. bräuchte ich alle Namen Item1, Item2, Item3 die dann als Überschriften auf den jeweiligen Pages stehen.

— geändert am 01.11.2014, 16:57:15

Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

01.11.2014, 16:58:48 via Website

Wie schon im anderen Thread geschreiben, trennst du deine Themen nicht.
Das das nun nichts mehr mit der Ursprünglsichen Frage der Erklärung des ViewPagers zu tun hat, mache ich hier mal zu.
Schreibe bitte in deinem anderen Thread weiter.

LG Pascal

LG Pascal //It's not a bug, it's a feature. :) ;)