Nachdem ich herausgefunden hatte, welche ViewPager-Methoden von ViewPager aufgerufen werden und welche für andere Zwecke verwendet werden, fand ich eine Lösung. Ich präsentiere es hier, da ich sehe, dass viele Leute damit zu kämpfen haben und ich keine anderen relevanten Antworten gesehen habe.
Hier ist zuerst mein Adapter; hoffentlich sind Kommentare im Code ausreichend:
public class MainPagerAdapter extends PagerAdapter
{
// This holds all the currently displayable views, in order from left to right.
private ArrayList<View> views = new ArrayList<View>();
//-----------------------------------------------------------------------------
// Used by ViewPager. "Object" represents the page; tell the ViewPager where the
// page should be displayed, from left-to-right. If the page no longer exists,
// return POSITION_NONE.
@Override
public int getItemPosition (Object object)
{
int index = views.indexOf (object);
if (index == -1)
return POSITION_NONE;
else
return index;
}
//-----------------------------------------------------------------------------
// Used by ViewPager. Called when ViewPager needs a page to display; it is our job
// to add the page to the container, which is normally the ViewPager itself. Since
// all our pages are persistent, we simply retrieve it from our "views" ArrayList.
@Override
public Object instantiateItem (ViewGroup container, int position)
{
View v = views.get (position);
container.addView (v);
return v;
}
//-----------------------------------------------------------------------------
// Used by ViewPager. Called when ViewPager no longer needs a page to display; it
// is our job to remove the page from the container, which is normally the
// ViewPager itself. Since all our pages are persistent, we do nothing to the
// contents of our "views" ArrayList.
@Override
public void destroyItem (ViewGroup container, int position, Object object)
{
container.removeView (views.get (position));
}
//-----------------------------------------------------------------------------
// Used by ViewPager; can be used by app as well.
// Returns the total number of pages that the ViewPage can display. This must
// never be 0.
@Override
public int getCount ()
{
return views.size();
}
//-----------------------------------------------------------------------------
// Used by ViewPager.
@Override
public boolean isViewFromObject (View view, Object object)
{
return view == object;
}
//-----------------------------------------------------------------------------
// Add "view" to right end of "views".
// Returns the position of the new view.
// The app should call this to add pages; not used by ViewPager.
public int addView (View v)
{
return addView (v, views.size());
}
//-----------------------------------------------------------------------------
// Add "view" at "position" to "views".
// Returns position of new view.
// The app should call this to add pages; not used by ViewPager.
public int addView (View v, int position)
{
views.add (position, v);
return position;
}
//-----------------------------------------------------------------------------
// Removes "view" from "views".
// Retuns position of removed view.
// The app should call this to remove pages; not used by ViewPager.
public int removeView (ViewPager pager, View v)
{
return removeView (pager, views.indexOf (v));
}
//-----------------------------------------------------------------------------
// Removes the "view" at "position" from "views".
// Retuns position of removed view.
// The app should call this to remove pages; not used by ViewPager.
public int removeView (ViewPager pager, int position)
{
// ViewPager doesn't have a delete method; the closest is to set the adapter
// again. When doing so, it deletes all its views. Then we can delete the view
// from from the adapter and finally set the adapter to the pager again. Note
// that we set the adapter to null before removing the view from "views" - that's
// because while ViewPager deletes all its views, it will call destroyItem which
// will in turn cause a null pointer ref.
pager.setAdapter (null);
views.remove (position);
pager.setAdapter (this);
return position;
}
//-----------------------------------------------------------------------------
// Returns the "view" at "position".
// The app should call this to retrieve a view; not used by ViewPager.
public View getView (int position)
{
return views.get (position);
}
// Other relevant methods:
// finishUpdate - called by the ViewPager - we don't care about what pages the
// pager is displaying so we don't use this method.
}
Und hier sind einige Codeausschnitte, die zeigen, wie der Adapter verwendet wird.
class MainActivity extends Activity
{
private ViewPager pager = null;
private MainPagerAdapter pagerAdapter = null;
//-----------------------------------------------------------------------------
@Override
public void onCreate (Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView (R.layout.main_activity);
... do other initialization, such as create an ActionBar ...
pagerAdapter = new MainPagerAdapter();
pager = (ViewPager) findViewById (R.id.view_pager);
pager.setAdapter (pagerAdapter);
// Create an initial view to display; must be a subclass of FrameLayout.
LayoutInflater inflater = context.getLayoutInflater();
FrameLayout v0 = (FrameLayout) inflater.inflate (R.layout.one_of_my_page_layouts, null);
pagerAdapter.addView (v0, 0);
pagerAdapter.notifyDataSetChanged();
}
//-----------------------------------------------------------------------------
// Here's what the app should do to add a view to the ViewPager.
public void addView (View newPage)
{
int pageIndex = pagerAdapter.addView (newPage);
// You might want to make "newPage" the currently displayed page:
pager.setCurrentItem (pageIndex, true);
}
//-----------------------------------------------------------------------------
// Here's what the app should do to remove a view from the ViewPager.
public void removeView (View defunctPage)
{
int pageIndex = pagerAdapter.removeView (pager, defunctPage);
// You might want to choose what page to display, if the current page was "defunctPage".
if (pageIndex == pagerAdapter.getCount())
pageIndex--;
pager.setCurrentItem (pageIndex);
}
//-----------------------------------------------------------------------------
// Here's what the app should do to get the currently displayed page.
public View getCurrentPage ()
{
return pagerAdapter.getView (pager.getCurrentItem());
}
//-----------------------------------------------------------------------------
// Here's what the app should do to set the currently displayed page. "pageToShow" must
// currently be in the adapter, or this will crash.
public void setCurrentPage (View pageToShow)
{
pager.setCurrentItem (pagerAdapter.getItemPosition (pageToShow), true);
}
}
Schließlich können Sie Folgendes für Ihr activity_main.xml
Layout verwenden:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</android.support.v4.view.ViewPager>
Ich suchte nach einer einfachen Lösung, um Ansichten dynamisch aus dem Viewpager (keine Fragmente) zu entfernen. Wenn Sie also Informationen haben, zu denen Ihre Seiten gehören, können Sie sie auf Als Tag anzeigen setzen. Einfach so (Adaptercode):
Sie müssen nur Ihre Daten aus mMessages entfernen und dann
notifyDataSetChanged()
Ihren Adapter anfordern . Schlechte Nachrichten, in diesem Fall gibt es keine Animation.quelle
Es gibt einige Diskussionen zu diesem Thema
Obwohl wir es oft sehen,
POSITION_NONE
scheint die Verwendung nicht der richtige Weg zu sein, da sie in Bezug auf das Gedächtnis sehr ineffizient ist.Hier in dieser Frage sollten wir Alvaros Ansatz in Betracht ziehen :
Hier ist eine SO-Antwort mit Code, der auf dieser Idee basiert
quelle
Ich habe ein ähnliches Programm gemacht. Ich hoffe, dies würde Ihnen helfen. In der ersten Aktivität können vier Rasterdaten ausgewählt werden. Bei der nächsten Aktivität gibt es einen Ansichtspager, der zwei obligatorische Seiten enthält. Außerdem werden 4 weitere Seiten angezeigt, die entsprechend den ausgewählten Rasterdaten sichtbar sind.
Es folgt die Hauptaktivität MainActivity
Hier sind TabFragment1, TabFragment2 usw. Fragmente, die auf dem Viewpager angezeigt werden sollen. Und ich zeige die Layouts nicht an, da sie außerhalb des Bereichs dieses Projekts liegen.
MainActivity beabsichtigt, Main2Activity Main2Activity
ViewPagerAdapter Viewpageradapter.class
Layout für main2activity acticity_main2.xml
Hoffe das würde jemandem helfen ... Klicken Sie bitte auf die Schaltfläche, wenn dies Ihnen geholfen hat
quelle
Hier ist eine alternative Lösung für diese Frage. Mein Adapter:
Code zum Entfernen und dynamischen Hinzufügen
Nach dem Rat von Peri Hartman begann es zu funktionieren, nachdem ich den ViewPager-Adapter auf null gesetzt und den Adapter erneut eingesetzt hatte, nachdem die Ansichten entfernt worden waren. Vorher zeigte die Seite 0 nicht den Listeninhalt.
Vielen Dank.
quelle
Ich habe eine benutzerdefinierte PagerAdapters-Bibliothek erstellt , um Elemente in PagerAdapters dynamisch zu ändern.
Mithilfe dieser Bibliothek können Sie Elemente dynamisch wie folgt ändern.
Die Thils-Bibliothek unterstützt auch von Fragmenten erstellte Seiten.
quelle
Zum Entfernen können Sie dies direkt verwenden:
fragment
ist das Fragment, das Sie entfernen möchten.quelle
Ich finde eine gute Lösung für dieses Problem. Mit dieser Lösung kann es funktionieren und Fragmente müssen nicht neu erstellt werden.
Mein zentraler Punkt ist:
Quellcode
Code ist in meinem Github Gist .
quelle