Android TabsAdapter mit ActionbarSherlock
Ich bin mit ActionbarSherlock mit einem SherlockListFragment, die LoaderManager.LoaderCallbacks.
In meinem ApplicationActivity onCreate-Methode ich bin mit
setContentView(R.layout.application);
festlegen der layout-funktioniert Super.
Ich bin initialisieren der actionbar, wie so
ActionBar bar = getSupportActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
bar.setDisplayHomeAsUpEnabled(false);
bar.setDisplayShowTitleEnabled(true);
//users event list
bar.addTab(bar.newTab()
.setTag("event_list")
.setText(getString(R.string.list_events_header))
.setTabListener(new TabListener<EventListFragment>(
this, getString(R.string.list_events_header), EventListFragment.class, null)));
Innerhalb der ApplicationActivity, ich habe einen AsyncTask, das dauert ein paar Sekunden zum laden auf die erste öffnen, und wenn Sie manuell regeneriert die API - was bedeutet, dass ich brauchen, um sicherzustellen, dass ich ein update der Listenansicht auf das fragment instanziiert oben, was ich zu tun in der onPostExecute-Methode, hier ist, wie ich das tun:
//update the events fragment
EventListFragment fragment = (EventListFragment) getSupportFragmentManager().findFragmentById(R.string.list_events_header);
if(fragment != null) {
//restart the loader for this fragment, refreshing the listview
getSupportLoaderManager().restartLoader(0, null, fragment);
}
DAS ALLES FUNKTIONIERT
Nun, ich wollte in einem TabsAdapter, um die Lust auf swiping-tabs, die ich getan habe, und es funktioniert, aber den letzten Teil habe ich erwähnt, über die onPostExecute, funktioniert nicht 🙁
Dies ist mein TabsAdapter:
package com.lateral.app.ui;
import java.util.ArrayList;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.ActionBar.Tab;
public class APPTabsAdapter extends FragmentPagerAdapter implements
ActionBar.TabListener, ViewPager.OnPageChangeListener {
private final Context mContext;
private final ActionBar mActionBar;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
static final class TabInfo {
private final Class<?> clss;
private final Bundle args;
TabInfo(Class<?> _class, Bundle _args) {
clss = _class;
args = _args;
}
}
public APPTabsAdapter(ApplicationActivity activity, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mActionBar = activity.getSupportActionBar();
mViewPager = pager;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public APPTabsAdapter(EventActivity activity, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mActionBar = activity.getSupportActionBar();
mViewPager = pager;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
TabInfo info = new TabInfo(clss, args);
tab.setTag(info);
tab.setTabListener(this);
mTabs.add(info);
mActionBar.addTab(tab);
notifyDataSetChanged();
}
@Override
public int getCount() {
return mTabs.size();
}
@Override
public Fragment getItem(int position) {
TabInfo info = mTabs.get(position);
return Fragment.instantiate(mContext, info.clss.getName(), info.args);
}
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
}
public void onPageSelected(int position) {
mActionBar.setSelectedNavigationItem(position);
}
public void onPageScrollStateChanged(int state) {
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Object tag = tab.getTag();
for (int i = 0; i < mTabs.size(); i++) {
if (mTabs.get(i) == tag) {
mViewPager.setCurrentItem(i);
}
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
}
Dies ist meine aktuelle onCreate-Methode aus der ApplicationActivity
mViewPager = new ViewPager(this);
mViewPager.setId(R.id.pager);
setContentView(mViewPager);
ActionBar bar = getSupportActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
bar.setDisplayHomeAsUpEnabled(false);
bar.setDisplayShowTitleEnabled(true);
mTabsAdapter = new APPTabsAdapter(this, mViewPager);
//users event list
mTabsAdapter.addTab(bar.newTab()
.setTag("event_list")
.setText(getString(R.string.list_events_header))
.setTabListener(new TabListener<EventListFragment>(
this, getString(R.string.list_events_header), EventListFragment.class, null)), EventListFragment.class, null);
- Und das ist das update das ich gemacht, um meine onPostExecute-Methode in der ApplicationActivity
//update the events fragment
EventListFragment fragment = (EventListFragment) mTabsAdapter.getItem(0);
if(fragment != null) {
//restart the loader for this fragment, refreshing the listview
getSupportLoaderManager().restartLoader(0, null, fragment);
}
Grundsätzlich, wenn es versucht, um mein onPostExecute-code
Bekomme ich eine NullPointerException aus meiner cursorAdapter innerhalb der fragment.. aber es fand sich das fragment..
BEARBEITEN -- Angeforderten Code
public Loader<Cursor> onCreateLoader(int loaderId, Bundle args) {
Log.d(TAG, "onCreateLoader");
return new EventCursorLoader(getActivity());
}
public static final class EventCursorLoader extends SimpleCursorLoader {
Context mContext;
public EventCursorLoader(Context context) {
super(context);
Log.d("EventCursorLoader", "Constructor");
mContext = context;
}
@Override
public Cursor loadInBackground() {
Log.d("EventCursorLoader", "loadInBackground");
EventsDataSource datasource = new EventsDataSource(mContext, ((ApplicationActivity)mContext).getDbHelper());
SharedPreferences app_preferences = PreferenceManager.getDefaultSharedPreferences(mContext);
long userId = app_preferences.getLong("authenticated_user_id", 0);
return datasource.getAllEvents(userId);
}
}
- Nur um klar zu sein, ist der Aufruf getSupportLoaderManager() abstürzt? Sie erwähnen, erhalten Sie eine NPE gibt einen crash. Wenn Sie abstürzt, hier ist es relevant sein könnte, um uns zu zeigen, die onCreateLoader () - Methode.
- Aktualisiert meine Frage, gehören die angeforderte Methode
Du musst angemeldet sein, um einen Kommentar abzugeben.
Versuch zum abrufen der loader hier ist einfach die falsche Idee, der Zweck ist, um die Daten zu aktualisieren. Nachdem ich einige Graben ich habe festgestellt, dass ich benachrichtigt Sie mehr als 1 set Inhalt Ladung in meine Anbieter mit
welche benachrichtigt, es zu ändern und erfrischt, alle dieser code kann gelöscht und ersetzt mit einer einzigen Zeile.
Wenn Sie noch die
Activity
'sLoaderManager
verwalten Sie IhreFragment
s Lader... Mach das nicht. DieActivity
'sLoaderManager
verwaltet Lader über IhreActivity
's* lifecycle - ... nicht IhrFragment
's. IhreFragment
wird wahrscheinlich versuchen, Zugriff auf eineLoader
dass dieActivity
noch nicht initialisiert, noch nicht.Ich hatte exakt das gleiche problem vor ein paar Tagen, während eines hackaton 🙂
Es stellt sich heraus, dass getItem() nicht zurück, das fragment, die Sie angelegt, aber Instanzierung eines neuen. Im Grunde ist das die Methode, die aufgerufen werden, um die Initiale Erstellung der Fragmente. Das ist, warum Sie finden, dessen Mitglied leer.
Ich war ein bisschen in Eile, aber ich denke, mit dieser Lösung gibt es keine Möglichkeit, den Fragmenten aus der Aktivität.
Jedoch die Problemumgehung, die für mich gearbeitet war, war ein Verweis auf die Fragmente in der Aktivität, wenn Sie erstellt wurden.
Etwas wie
in Ihrem fragment und
innerhalb Ihrer Aktivität.
Sollten Sie dann verwenden, getEventListFragment() anstatt mit der getItem () - Methode des Adapters.
Wenn Sie möchten, um zu sehen, der ganze code, den ich schrieb (und insbesondere der Teil, den Sie benötigen), können Sie es hier
https://github.com/moodeque/moodeque-android/tree/master/src/main/java/com/whiterabbit/hackitaly/Activities
Den container Aktivität ist InVenueActivity , in der Erwägung, dass die beiden Fragmente sind die, die in den Registerkarten.