1

问题描述

我正在编写使用它的应用程序,fragmentsViewPager可以在下面看到我的FragmentPagerAdapter. 我只是想知道这是正确的写作方式FragmentPagerAdapter吗?因为在某些情况下,当我调用getActivity()片段时,它会返回null

public class FragmentAdapter extends FragmentPagerAdapter {

/* Fragments */
private Fragments[] mFragments;

/**
 * Constructor.
 * @param fm
 */
public FragmentAdapter(FragmentManager fm) {
    super(fm);

    /* Initialize Fragments. */
    mFragments = Fragments.values();
}

public enum Fragments {

    Favorites(App.getStringByResId(R.string.favorites), new FragmentFavorites()),
    Categories(App.getStringByResId(R.string.categories), new FragmentCategories()),
    YellowPages(App.getStringByResId(R.string.yellow_pages), new FragmentYellowPages());


    /**
     * Constructor.
     * @param title Fragment title.
     * @param fragment Fragment object.
     */
    Fragments(String title, BaseListFragment fragment) {
        this.mTitle = title;
        this.mFragment = fragment;
    }

    /* Fragment Title Text. */
    private String mTitle;
    /* Fragment */
    private BaseListFragment mFragment;

    /**
     * Get Fragment Title.
     * @return Title.
     */
    public String getTitle() {
        return mTitle;
    }

    /**
     * Get Fragment 
     * @return Fragment.
     */
    public BaseListFragment getFragment() {
        return mFragment;
    }
};

@Override
public CharSequence getPageTitle(int position) {
    return mFragments[position].getTitle();
}

@Override
public Fragment getItem(int position) {
    return mFragments[position].getFragment();
}

@Override
public int getCount() {
    return mFragments.length;
};

};

已编辑

从主要活动我称之为这段代码。这是对的吗 ?在这种情况下,大多数情况下getActivity()返回 null。

/* Call Search function for the given fragment. */
Fragments.values()[tabControl.getCurrentItem()].getFragment().search(tv.getText().toString());

分段

public class FragmentFavorites extends BaseListFragment {

    final static String TAG = FragmentFavorites.class.getSimpleName();

    /* Controllers. */
    ListView lvFavorites;
    TextView tvInfo;

    /* Simple Cursor Adapter. */
    SimpleCursorAdapter scAdapter;

    /* This member keep current database language, every time then onResume method called
     * application must check if database language was changed, if language changed application 
     * must update list view by creating new adapter. */
    String language;

    /* This flag shows that new favorite was added and list need to be updated. */
    boolean newFavoriteAdded = false;

    boolean canUpdateOnSearch = false;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View favoritesPagesView = inflater.inflate(R.layout.fragment_favorites, container, false);

        Log.i(TAG, "onCreateView( )");

        /* Initialize Controllers. */
        tvInfo = (TextView) favoritesPagesView.findViewById(R.id.tvNoFavoritesText);
        lvFavorites = (ListView) favoritesPagesView.findViewById(android.R.id.list);

        return favoritesPagesView;

    } /* onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) */


    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        Log.i(TAG, "onCreate( )");

        /* Tell the framework to try to keep this fragment around
           during a configuration change. */
        setRetainInstance(true);

        /* Get context, if context is null set default language "English". */
        final Context context = getActivity();
        if (context != null) {

            Log.wtf(TAG, "onCreate(Context is null, set default language \"en\".)");

            /* Set language when fragment first created, default language is "English". */
            SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
            language = preferences.getString(Preferences.LANGUAGE, Preferences.EN);
        }
        else language = Preferences.EN;

    } /* onCreate(Bundle savedInstanceState) */


    @Override
    public void onActivityCreated(Bundle savedInstanceState) {

        super.onActivityCreated(savedInstanceState);

        Log.i(TAG, "onActivityCreated( )");

        ListView listView = getListView();
        /* Set on item click listener */ 
        listView.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View v, int position, long id) {
                Cursor cursor = (Cursor)adapterView.getAdapter().getItem(position);
                final String _id = cursor.getString(cursor.getColumnIndex("_id"));
                Log.i(TAG, "onItemClick(_id = " + _id + ")");

                /* Get current selected language. */
                final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
                final String lang = preferences.getString(Preferences.LANGUAGE, "en");

                ActionDialog dialog = new ActionDialog(getActivity());

                dialog.setFavoriteRemovedListener(new OnActionDialogListeners() {

                    @Override
                    public void onFavoriteRemoved() {
                        /* Get Saved favorites from the preferences, if there are no favorites return form onResume. */
                        final String favorites = preferences.getString(Preferences.FAVORITE, null);

                        /* Update favorites adapter with new favorite contacts. */
                        updateAdapterIfNeeded(lang, favorites, true);
                    }

                    @Override
                    public void onFavoriteAdded() { /* Not used... */ }

                });

                dialog.setID(_id);
                dialog.setDeleteFavorite(true);
                dialog.setTitle(cursor.getString(cursor.getColumnIndex(String.format("name_%s", language))));
                dialog.setPhone(cursor.getString(cursor.getColumnIndex("telephones")));
                dialog.show();
            }
        });

    } /* onActivityCreated(Bundle savedInstanceState) */


    @Override
    public void onResume() {

        super.onResume();

        Log.i(TAG, "onResume( )");

        /* Check if database current language was changed. */
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
        final String currentLanguage = preferences.getString(Preferences.LANGUAGE, Preferences.EN);

        /* Get Saved favorites from the preferences, if there are no favorites return form onResume. */
        final String favorites = preferences.getString(Preferences.FAVORITE, null);
        if (favorites == null || favorites.length() == 0) {
            /* Hide List View and show Text View. */
            Log.i(TAG, "There are no saved favorites in the preferences.");
            lvFavorites.setVisibility(View.GONE);
            tvInfo.setVisibility(View.VISIBLE);
            tvInfo.setText(getActivity().getString(R.string.no_selected_favorites));
            return;
        }


        if (!currentLanguage.equalsIgnoreCase(language)) {

            Log.i(TAG, "onResume(Database language was changed.)");

            /* Update language with changed one. */
            language = currentLanguage;

            /* Update Adapter, do not pay attention if it is already created or no. */
            updateAdapterIfNeeded(currentLanguage, favorites, true);
        } 
        else if (newFavoriteAdded) {

            Log.i(TAG, "onResume(New favorite was added to the list, update needed");

            /* Update adapter as new favorite was added. */
            updateAdapterIfNeeded(currentLanguage, favorites, true);

            newFavoriteAdded = false;
        }
        else {
            /* Update Adapter only in the case if no adapter is created (This will create new adapter) */
            updateAdapterIfNeeded(currentLanguage, favorites, false);
        }

    } /* void onResume() */


    /**
     * This function update Simple Cursor Adapter in the case if it is needed or
     * cursor adapter is not created yet.
     * 
     * @param currentLanguage Current language of database.
     * @param forceUpdate if true adapter will be updated in any case; otherwise it will
     *        not be updated.
     */
    void updateAdapterIfNeeded(final String lang, final String favs, final boolean forceUpdate) {

        Log.i(TAG, String.format("updateAdapterIfNeeded(%s, %b)", lang, forceUpdate));

        /* Show "Favorites" list view and hide Info text view. */
        lvFavorites.setVisibility(View.VISIBLE);
        tvInfo.setVisibility(View.GONE);

        if (forceUpdate || scAdapter == null) {

            /* Preparing Adapter Settings. */
            final int[] to = new int[]{ R.id.tvContactTitle, R.id.tvContactTelephone };
            final String[] from = new String[] { String.format("name_%s", lang), "telephones" };

            /* Get Contacts from the SQLite Database. */
            final Cursor cursor = DataBaseManager.instance().getAllFavorites(favs, lang);

            Log.i(TAG, "updateAdapterIfNeeded(Creating new Adapter ...)");
            /* Create New Simple Cursor Adapter, even if it is already exists. */
            scAdapter = new  FragmentCursorAdapter(getActivity(), R.layout.contact_row, cursor, from, to, 0);
            Log.i(TAG, "updateAdapterIfNeeded(Adapter was successfully created ...)");

            /* Set Adapter to the list. */
            this.setListAdapter(scAdapter);
        }

    } /* updateAdapterIfNeeded(final String currentLanguage, boolean forceUpdate) */


    void updateAdapterOnSearch(final String tts, final String lang, final String favs) {

        Log.i(TAG, String.format("updateAdapterOnSearch(%s, %s)", tts, lang));

        /* Show "Favorites" list view and hide Info text view. */
        lvFavorites.setVisibility(View.VISIBLE);
        tvInfo.setVisibility(View.GONE);

        /* Preparing Adapter Settings. */
        final int[] to = new int[]{ R.id.tvContactTitle, R.id.tvContactTelephone };
        final String[] from = new String[] { String.format("name_%s", lang), "telephones" };

        /* Get Contacts from the SQLite Database. */
        final Cursor cursor = DataBaseManager.instance().getSearchedFavorites(favs, lang, tts);
        if (cursor.getCount() == 0) {
            lvFavorites.setVisibility(View.GONE);
            tvInfo.setVisibility(View.VISIBLE);
            tvInfo.setText(String.format(getActivity().getString(R.string.no_companies_were_found), tts));
        }

        Log.i(TAG, "updateAdapterOnSearch(Creating new Adapter ...)");
        /* Create New Simple Cursor Adapter, even if it is already exists. */
        scAdapter = new  FragmentCursorAdapter(getActivity(), R.layout.contact_row, cursor, from, to, 0);
        Log.i(TAG, "updateAdapterOnSearch(Adapter was successfully created ...)");

        /* Set Adapter to the list. */
        this.setListAdapter(scAdapter);

    } /* updateAdapterOnSearch(final String tts, final String lang) */


    @Override
    public void search(final String tts) {

            final Context context = getActivity();

        Log.i(TAG, String.format("search(%s)", tts));

        /* Get application context. */
        if (context == null) {
            Log.wtf(TAG, "search(Search can't be completed as context is null)");
            return;
        }

        /* Get Database current language. */
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        if (preferences == null) {
            Log.w(TAG, "search(Search can't be completed as preferences object is null)");
            return;
        }


        /* Get language from the preferences */
        final String lang = preferences.getString(Preferences.LANGUAGE, Preferences.EN);

        /* Get Saved favorites from the preferences, if there are no favorites return form onResume. */
        final String favorites = preferences.getString(Preferences.FAVORITE, null);

        /* If user search for the text. */
        if (tts != null && tts.length() != 0) {
            updateAdapterOnSearch(tts, lang, favorites);

            canUpdateOnSearch = true; 
        }

        if ((tts == null || tts.length() == 0) && canUpdateOnSearch) {
            /* In this case all contacts will be shown in the list view. */
             updateAdapterIfNeeded(lang, favorites, true);

            canUpdateOnSearch = false;
        }

    } /* search(final String tts) */


    public void newFavoriteAdded(final boolean value) {

        Log.i(TAG, String.format("newFavoriteAdded(%b)", value));

        newFavoriteAdded = value;
    }



};
4

1 回答 1

4

您应该只在调用Fragment.onActivityCreated()getActivity()内部或之后调用,这样 Activity 永远不会是,如examplenull

这也是另一种可能发生空活动的情况,当您在片段内启动线程并getActivity()在用户已经关闭片段时调用。

new Thread() {
    @Override
    public void run() {
        // long operations goes here
        // user decided to close fragment
        Activity activity = getActivity();
        // here 'activity' is null because fragment is destroyed
        }
}.start();  
于 2013-06-17T06:33:47.030 回答