Android的TabsAdapter与ActionbarSherlock [英] Android TabsAdapter with ActionbarSherlock

查看:281
本文介绍了Android的TabsAdapter与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信息= mTab​​s.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< mTab​​s.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆