4

LoaderManager.LoaderCallbacksを実装するSherlockListFragmentでActionbarSherlockを使用しています。

私が使用しているApplicationActivityonCreateメソッドで

setContentView(R.layout.application);

レイアウトを設定するには-うまく機能します。

私はそのようにアクションバーを初期化しています

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) {
    }
}

これは、ApplicationActivityから更新されたonCreateメソッドです。

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

これは、ApplicationActivityのonPostExecuteメソッドに対して行った更新です。

// 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コードを実行しようとしたとき

フラグメント内のcursorAdapterからNullPointerExceptionが発生しますが、フラグメントが見つかりました。

ここに画像の説明を入力してください

編集-要求されたコード

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

3 に答える 3

2

ここでローダーを取得しようとするのは、データを更新することを目的としているため、単に間違った考えです。掘り下げてみたところ、プロバイダーで複数のコンテンツの読み込みを通知できることがわかりました。

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

変更を通知して更新するため、このコードはすべて削除して1行に置き換えることができます。

于 2012-09-26T16:27:07.623 に答える
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;
}

あなたの活動の中で。

次に、アダプタのgetItem()メソッドを使用する代わりに、getEventListFragment()を使用する必要があります。

私が書いたコード全体(特に必要な部分)を見たい場合は、ここで確認できます

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

コンテナアクティビティはInVenueActivityですが、2つのフラグメントはタブに含まれているフラグメントです。

于 2012-07-24T18:15:36.133 に答える
0

まだActivity'sを使用しLoaderManagerてsローダーを管理している場合Fragmentは、そうしないでください。は、Activity'のライフサイクルLoaderManager全体でローダーを管理します...あなたの'ではありませActivityFragment。おそらく、まだ初期化されていないにFragmentアクセスしようとしています。LoaderActivity

于 2012-07-24T17:37:51.423 に答える