Android的TabsAdapter与ActionbarSherlock [英] Android TabsAdapter with ActionbarSherlock
问题描述
我使用的 ActionbarSherlock 与 SherlockListFragment 实现的 LoaderManager.LoaderCallbacks
在我ApplicationActivity onCreate方法我现在用
的setContentView(R.layout.application);
要设置布局 - 伟大工程。
我初始化像这样的动作条
动作条酒吧= getSupportActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayOptions(0,ActionBar.DISPLAY_SHOW_TITLE);
bar.setDisplayHomeAsUpEnabled(假);
bar.setDisplayShowTitleEnabled(真);//用户事件列表
bar.addTab(bar.newTab()
.setTag(EVENT_LIST)
.setText(的getString(R.string.list_events_header))
.setTabListener(新TabListener< EventListFragment>(
对此,的getString(R.string.list_events_header),EventListFragment.class,NULL)));
在ApplicationActivity,我有一个AsyncTask的,需要一个几秒钟的初始开路负载,当手动刷新对API - 这意味着我必须确保我上面实例化的片段,更新的ListView其中我在onPostExecute方法,这里是我如何做到这一点:
//更新的事件片段
EventListFragment片段=(EventListFragment)getSupportFragmentManager()findFragmentById(R.string.list_events_header)。
如果(片段!= NULL){
//重新启动加载器为这个片段,刷新列表视图
。getSupportLoaderManager()restartLoader(0,空,片段);
}
这一切工作
现在,我希望把在TabsAdapter拿到看中刷卡标签,这是我所做的,和它的作品,但最后部分,我提到了onPostExecute,不工作:(
这是我的TabsAdapter:
包com.lateral.app.ui;进口的java.util.ArrayList;进口android.content.Context;
进口android.os.Bundle;
进口android.support.v4.app.Fragment;
进口android.support.v4.app.FragmentPagerAdapter;
进口android.support.v4.app.FragmentTransaction;
进口android.support.v4.view.ViewPager;进口com.actionbarsherlock.app.ActionBar;
进口com.actionbarsherlock.app.ActionBar.Tab;公共类APPTabsAdapter扩展FragmentPagerAdapter工具
ActionBar.TabListener,ViewPager.OnPageChangeListener {
私人最终上下文mContext;
私人最终动作条mActionBar;
私人最终ViewPager mViewPager;
私人最终的ArrayList< TabInfo> mTabs =新的ArrayList< TabInfo>(); 静态final类TabInfo {
私人最终级<> CLSS;
私人最终捆绑ARGS; TabInfo(类<> _class,捆绑_args){
CLSS = _class;
ARGS = _args;
}
} 公共APPTabsAdapter(ApplicationActivity活动,ViewPager寻呼机){
超级(activity.getSupportFragmentManager());
mContext =活动;
mActionBar = activity.getSupportActionBar();
mViewPager =寻呼机;
mViewPager.setAdapter(本);
mViewPager.setOnPageChangeListener(本);
} 公共APPTabsAdapter(EventActivity活动,ViewPager寻呼机){
超级(activity.getSupportFragmentManager());
mContext =活动;
mActionBar = activity.getSupportActionBar();
mViewPager =寻呼机;
mViewPager.setAdapter(本);
mViewPager.setOnPageChangeListener(本);
} 公共无效addTab(ActionBar.Tab标签,类<> CLSS,捆绑参数){
TabInfo信息=新TabInfo(CLSS,参数);
tab.setTag(信息);
tab.setTabListener(本);
mTabs.add(信息);
mActionBar.addTab(标签);
notifyDataSetChanged();
} @覆盖
公众诠释的getCount(){
返回mTabs.size();
} @覆盖
公共片段的getItem(INT位置){
TabInfo信息= mTabs.get(位置);
返回Fragment.instantiate(mContext,info.clss.getName(),info.args);
} 公共无效onPageScrolled(INT位置,浮positionOffset,
INT positionOffsetPixels){
} 公共无效使用onPageSelected(INT位置){
mActionBar.setSelectedNavigationItem(位置);
} 公共无效onPageScrollStateChanged(INT状态){
} 公共无效onTabSelected(标签选项卡,FragmentTransaction英尺){
对象标记= tab.getTag();
的for(int i = 0; I< mTabs.size();我++){
如果(mTabs.get(ⅰ)==标签){
mViewPager.setCurrentItem(ⅰ);
}
}
} 公共无效onTabUnselected(标签选项卡,FragmentTransaction英尺){
} 公共无效onTabReselected(标签选项卡,FragmentTransaction英尺){
}
}
这是从我的ApplicationActivity更新onCreate方法
mViewPager =新ViewPager(本);
mViewPager.setId(R.id.pager);的setContentView(mViewPager);动作条酒吧= getSupportActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayOptions(0,ActionBar.DISPLAY_SHOW_TITLE);
bar.setDisplayHomeAsUpEnabled(假);
bar.setDisplayShowTitleEnabled(真);mTabsAdapter =新APPTabsAdapter(这一点,mViewPager);//用户事件列表
mTabsAdapter.addTab(bar.newTab()
.setTag(EVENT_LIST)
.setText(的getString(R.string.list_events_header))
.setTabListener(新TabListener< EventListFragment>(
对此,的getString(R.string.list_events_header),EventListFragment.class,NULL)),EventListFragment.class,NULL);
这是我在ApplicationActivity我onPostExecute方法进行更新
//更新的事件片段
EventListFragment片段=(EventListFragment)mTabsAdapter.getItem(0);
如果(片段!= NULL){
//重新启动加载器为这个片段,刷新列表视图
。getSupportLoaderManager()restartLoader(0,空,片段);
}
基本上,当它试图运行我onPostExecute code
我从片段中我的CursorAdapter一个NullPointerException异常..但它发现片段。
修改 - 请求code
公共装载机<&光标GT; onCreateLoader(INT loaderId,捆绑参数){
Log.d(TAGonCreateLoader); 返回新EventCursorLoader(getActivity());
}公共静态最后一类EventCursorLoader扩展SimpleCursorLoader { 上下文mContext; 公共EventCursorLoader(上下文的背景下){
超级(上下文); Log.d(EventCursorLoader,构造); mContext =背景;
} @覆盖
公共光标loadInBackground(){
Log.d(EventCursorLoader,loadInBackground); EventsDataSource数据源=新EventsDataSource(mContext,((ApplicationActivity)mContext).getDbHelper()); 共享preferences APP_ preferences = preferenceManager.getDefaultShared preferences(mContext);
长的用户id = APP_ preferences.getLong(authenticated_user_id,0); 返回datasource.getAllEvents(用户ID);
}
}
试图在这里找回装载机简直是错误的想法,因为目的是为了刷新数据。做一些挖掘,我发现我可以在我的供应商使用notify超过1套内容加载后
的getContext()getContentResolver()有NotifyChange(URI,空)。
该通知的变化和刷新它
,这一切code可以被删除,取而代之的是一行。
I am using ActionbarSherlock with a SherlockListFragment that implements LoaderManager.LoaderCallbacks.
In my ApplicationActivity onCreate method I am using
setContentView(R.layout.application);
to set the layout -- works great.
I am initializing the actionbar like 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)));
Within the ApplicationActivity, I have an AsyncTask that takes a couple of seconds to load on initial open, and when manually refreshed against the API - which means that I need to make sure I update the ListView on the fragment instantiated above, which I do in the onPostExecute method, here is how I do that:
// 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);
}
THIS ALL WORKS
Now, I wanted to put in a TabsAdapter to get the fancy swiping tabs, which I've done, and it works, but the last part I mentioned about the onPostExecute, doesnt work :(
This is my 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) {
}
}
This is my updated onCreate method from the 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);
And this is the update I made to my onPostExecute method in the 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);
}
Basically, when it attempts to run my onPostExecute code
I get a NullPointerException from my cursorAdapter within the fragment.. but it found the fragment..
EDIT -- Requested 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);
}
}
Attempting to retrieve the loader here is simply the wrong idea, as the purpose is to refresh the data. After doing some digging I found that I can notify more than 1 set of content load in my provider using
getContext().getContentResolver().notifyChange(uri, null);
which notifies it of change and refreshes, all this code can be deleted and replaced with a single line.
这篇关于Android的TabsAdapter与ActionbarSherlock的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!