4

Я использую ActionBarSherlock с SherlockListFragment, который реализует LoaderManager.LoaderCallbacks.Android TabsAdapter с ActionBarSherlock

В моем методе ApplicationActivity OnCreate Я использую

setContentView(R.layout.application); 

установить макет - отлично работает.

Я инициализация ActionBar как так

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

В ApplicationActivity, у меня есть AsyncTask, что занимает несколько секунд, чтобы загрузить на первоначальном открытом, и когда обновлять вручную против API - это значит, что я необходимо убедиться, что я обновить ListView на фрагменте реализованным выше, что я делаю в методе onPostExecute, вот как я могу это сделать:

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

эТО ВСЕ РАБОТАЕТ

Теперь я хотел бы поставить в TabsAdapter, чтобы получить фантазии ударяя вкладки, которые я сделал, и он работает, но последняя часть я уже упоминал о onPostExecute, не работает :(

Это мой 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) { 
    } 
} 

Это мой обновленный OnCreate метод из 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); 

И это обновление, которое я сделал мой метод onPostExecute в 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); 
} 

В основном, когда он пытается запустить мой onPostExecute код

я получаю NullPointerException от моего CursorAdapter в пределах фрагмента .. но он нашел фрагмент ..

enter image description here

EDIT - запрошенный код

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

Просто, чтобы быть ясным, вызов getSupportLoaderManager() сбой? Вы упомянули, что вы получаете NPE, который указывает на сбой. Если вы ругаетесь здесь, может оказаться актуальным показать нам метод onCreateLoader(). –

+0

Обновлен мой вопрос, чтобы включить запрошенный метод – Rabbott

ответ

2

Попытка получить загрузчик здесь - это просто неправильная идея, поскольку целью является обновление данных. После выполнения некоторого копания я обнаружил, что я могу предупредить более 1 набор нагрузки контента в моем провайдере с использованием

getContext().getContentResolver().notifyChange(uri, null); 

который уведомляет его изменения и освежает, весь этот код может быть удален и заменен на одной линии.

0

Если вы все еще используете ActivityLoaderManager для управления вашими погрузчиками Fragment ... не делайте этого. ActivityLoaderManager управляет погрузчиками по вашему Activity's * жизненный цикл ... не ваш Fragment. Вероятно, ваш Fragment пытается получить доступ к Loader, который еще не инициализирован Activity.

0

Я имел точно такую ​​же проблему, пару дней назад, во время Хакатона :-)

Оказывается, что GetItem() не возвращает фрагмент, который вы создали, но экземпляр нового. В основном это метод, вызываемый для изначально создания фрагментов. Вот почему вы находите свой член пустым.

Я был немного в спешке, но я думаю, что с этим решением нет доступа к фрагментам из активности.

Однако обходной путь, который работал для меня, заключался в том, чтобы установить ссылку на фрагменты в действии, когда они были созданы.

Что-то вроде

@Override 
public void onActivityCreated(Bundle savedInstanceState) { 
    super.onActivityCreated(savedInstanceState); 
    ((ApplicationActivity)getActivity()).setEventListFragment(this); 
} 

внутри вашего фрагмента и

EventListFragment getEventListFragment(){ 
    return mEventListFragment; 
} 

public void setEventListFragment(EventListFragment m){ 
    mEventListFragment = m; 
} 

внутри вашей деятельности.

Вы должны использовать getEventListFragment() вместо использования метода getItem() адаптера.

Если вы хотите увидеть весь код, который я написал (и особенно той части, которую нужно), вы можете проверить его здесь

https://github.com/moodeque/moodeque-android/tree/master/src/main/java/com/whiterabbit/hackitaly/Activities

Контейнер активность InVenueActivity, в то время как два фрагмента содержащихся в вкладках.

Смежные вопросы