0

我遇到了这个问题,当我更改设备的方向时,由于某种原因,与我的 ListFragment 关联的 ListView 的屏幕表示被保留,并且新的 ListView 在其下方膨胀。为了给你一些背景信息,我正在创建一个非常简单的应用程序,其目的是测试我创建的一些 DAO 对象。我更愿意发布一些截图来描述我的应用程序正在经历的行为,但不幸的是,我目前的声誉太低了。

我能描述的最好的情况是,当我将设备的方向从纵向更改为横向(反之亦然)时,它会膨胀一个全新的 ListView 而不会缩小前一个。我已经研究了几天了,老实说,我很难过。你们可以提供的任何帮助将不胜感激。

这是 ListFragment 的代码:

package edu.uark.csce.mobile.healthyshopper;

import android.app.ListFragment;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.CursorLoader;
import android.content.Loader;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;

/**
 * A fragment representing a list of Items.
 * <p />
 * <p />
 * Activities containing this fragment MUST implement the {@link Callbacks}
 * interface.
 */
public class ViewFragment extends ListFragment implements
        LoaderCallbacks<Cursor> {
    // Class Fields:
    private static final String TAG = "healthyshopper.ViewFragment";
    private static final int MAIN_DB_LOADER = 0;

    // In the final application, any query to the main database needs to return
    // at least these fields:
    private final String[] NECESSARY_COLUMNS = { DAOContentProvider.FOOD_DES,
            DAOContentProvider.FOOD_CALORIES, DAOContentProvider.FOOD_FAT,
            DAOContentProvider.FOOD_CARBS, DAOContentProvider.FOOD_PROTEIN };

    private final String FROM[] = {DAOContentProvider.FOOD_GROUP, DAOContentProvider.FOOD_DES,
             DAOContentProvider.FOOD_MANUFAC, DAOContentProvider.FOOD_PROTEIN,
             DAOContentProvider.FOOD_FAT, DAOContentProvider.FOOD_CARBS,
             DAOContentProvider.FOOD_CALORIES, DAOContentProvider.FOOD_SERV_SIZE};
    private final int TO[] = {R.id.fd_group, R.id.shrt_desc, 
                    R.id.manufac, R.id.protein, 
                    R.id.fat, R.id.carb,
                    R.id.cal, R.id.amt};
    private int threadMode;
    private int queryType;
    private int foodGroupId;
    private CursorLoader loader;
    private SimpleCursorAdapter listAdapter;

    // Preference Option Constants:
    private int UI_THREAD = 0;
    private int BRANCHED_THREAD = 1;
    private int ALL_ROWS = 0;
    private int SPECIFIC_FD_GROUP = 1;
    private int LIMITED_ROWS = 2;

    private OnFragmentInteractionListener mListener;

    /**
     * Mandatory empty constructor for the fragment manager to instantiate the
     * fragment (e.g. upon screen orientation changes).
     */
    public ViewFragment() {
    }

    /***************************************
     * Life cycle callbacks:
     */

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.e(TAG, "in onCreate()");
        setRetainInstance(true);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState){
        super.onActivityCreated(savedInstanceState);
        if(savedInstanceState == null){
            listAdapter = new SimpleCursorAdapter(getActivity(), R.layout.list_node, null, FROM, TO, 0);
            setListAdapter(listAdapter);
        }
    }

    @Override
    public void onStart(){
        super.onStart();
    }

    @Override
    public void onResume(){
        super.onResume();

        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity()
                .getApplicationContext());

        Log.d(TAG, preferences.getString("THREADING_MODE", "BLANK"));

        //Load testing preferences:
        threadMode = Integer.valueOf(preferences.getString("THREADING_MODE","0"));
        queryType = Integer.valueOf(preferences.getString("QUERY_TYPE", "0"));
        foodGroupId = Integer.valueOf(preferences.getString("FOOD_GROUP", "0")); // Default

        if (threadMode == BRANCHED_THREAD) {
            loader = (CursorLoader) getLoaderManager().initLoader(
                    MAIN_DB_LOADER, null, this);
        } else {
            String[] projection = null;
            String selection = null;
            if (queryType == SPECIFIC_FD_GROUP) {
                Log.d(TAG, "Query Type: " + (getResources().getStringArray(R.array.query_type_select))[queryType]);
                selection = DAOContentProvider.FOOD_GROUP + " = " + foodGroupId;
            } else if (queryType == LIMITED_ROWS) {
                projection = NECESSARY_COLUMNS;
            }
            /*This is for testing only.  Ordinarily, you should NEVER perform Db operations on the UI thread.*/
            listAdapter.swapCursor(getActivity().getContentResolver().query(
            DAOContentProvider.CONTENT_URI, projection, selection, null, null));
        }
    }

    @Override
    public void onPause(){
        super.onPause();

    }

    @Override 
    public void onStop(){
        super.onStop();
    }

    @Override 
    public void onDestroyView(){
        super.onDestroyView();
        Log.e(TAG, "in onDestroyView()");
        setListAdapter(null);
        listAdapter.swapCursor(null);
        listAdapter = null; 

    }

    @Override
    public void onDestroy(){
        super.onDestroy();
    }

    @Override
    public void onDetach(){
        super.onDetach();
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);

        if (null != mListener) {
        }
    }

    /**
     * This interface must be implemented by activities that contain this
     * fragment to allow an interaction in this fragment to be communicated to
     * the activity and potentially other fragments contained in that activity.
     * <p>
     * See the Android Training lesson <a href=
     * "http://developer.android.com/training/basics/fragments/communicating.html"
     * >Communicating with Other Fragments</a> for more information.
     */
    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        public void onFragmentInteraction(String id);
    }

    /**
     * LoaderManager Callbacks;
     */

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        switch (id) {
        case MAIN_DB_LOADER:
            String[] projection = null;
            String selection = null;
            if (queryType == SPECIFIC_FD_GROUP) {
                Log.d(TAG,
                        "Query Type: "
                                + (getResources()
                                        .getStringArray(R.array.query_type_select))[queryType]);
                selection = DAOContentProvider.FOOD_GROUP + " = " + foodGroupId;
            } else if (queryType == LIMITED_ROWS) {
                projection = NECESSARY_COLUMNS;
            }
            return new CursorLoader(getActivity(),
                    DAOContentProvider.CONTENT_URI, projection, selection,
                    null, null);
        default:
            return null;
        }
    }

    @Override
    public void onLoadFinished(Loader<Cursor> arg0, Cursor arg1) {
        listAdapter.swapCursor(arg1);
        listAdapter.notifyDataSetChanged();
    }

    @Override
    public void onLoaderReset(Loader<Cursor> arg0) {
        listAdapter.swapCursor(null);
        listAdapter.notifyDataSetChanged();
    }

}

这是其相关活动的代码:

package edu.uark.csce.mobile.healthyshopper;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class TestingActivity extends Activity implements ViewFragment.OnFragmentInteractionListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_testing);
        ViewFragment list = new ViewFragment();
        getFragmentManager().beginTransaction().add(R.id.test_layout, list).commit();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.testing, menu);
        return true;
    }

    @Override
    public void onFragmentInteraction(String id) {
        // TODO Auto-generated method stub

    }

}
4

1 回答 1

1

setRetainInstance(true);在你的片段中使用。这使得片段在重新创建活动时被保留和重用。

您可以在此问题中阅读更详细的描述:进一步了解 setRetainInstance(true)

于 2013-11-09T00:15:07.150 回答