如何在方向更改时保留所选微调器/下拉项的状态?

时间:2013-11-26 05:12:33

标签: android android-layout android-fragments android-spinner android-orientation

我在我的代码中使用了一个微调器下拉列表,其中我有4到5个动态填充的值,比如我将“apples”设置为默认值,我从下拉列表中选择“oranges”并将我的屏幕旋转到横向肖像,它会返回默认的“苹果”以及与之关联的视图。如何保存状态,以便当我选择“橙子”并旋转到横向时,它会填充所选值/保持在相同的选定状态,保持视图完整/填充在与所选值对应的纵向模式中选择的视图。这是我用于相同的适配器代码:

public class MarketsSpinnerAdapter extends CustomRowAdapter<AdapterRow> {


    private List<AdapterRow> mRenderList;

    public MarketsSpinnerAdapter(final Context context, final List<AdapterRow> renderList) {
        super(context);


        mRenderList = new ArrayList<AdapterRow>();
        mRenderList.addAll(renderList);
    }

    @Override
    protected void setEntries(final List<AdapterRow> renderList) {
        mRenderList = renderList;
    }

    @Override
    protected List<AdapterRow> getEntries() {
        return mRenderList;
    }

    @Override
    public View getDropDownView(final int position, final View convertView, final ViewGroup parent) {
        return getEntries().get(position).getDropDownView(mContext, convertView);
    }

}

相应片段中的相应用法:

 private void populateCategoryRows(final Cursor cursor) {
            mCategories.clear();
            mAllCategories.clear();
            cursor.moveToPosition(-1);
            Map<String, String> categoryParentNames = new HashMap<String, String>();

            int selectedPosition = 0;
            String previousHeader = "";
            String previousAllHeader = "";

            while (cursor.moveToNext()) {
                final int categoryLevel = cursor.getInt(cursor.getColumnIndex(MarketsCategory.Columns.LEVEL));
                final String categoryName = cursor.getString(cursor.getColumnIndex(MarketsCategory.Columns.NAME));
                final String categoryDisplayName = cursor.getString(cursor.getColumnIndex(MarketsCategory.Columns.DISPLAY_NAME));

                if (categoryLevel == 1) {
                    categoryParentNames.put(categoryName, categoryDisplayName);
                }
            }

            cursor.moveToPosition(-1);
            while (cursor.moveToNext()) {
                final int categoryLevel = cursor.getInt(cursor.getColumnIndex(MarketsCategory.Columns.LEVEL));
                final boolean categoryIsDefault = cursor.getInt(cursor.getColumnIndex(MarketsCategory.Columns.IS_DEFAULT)) == 1;
                final boolean categoryIsSelected = cursor.getInt(cursor.getColumnIndex(MarketsCategory.Columns.IS_SELECTED)) == 1;
                final String categoryParent = cursor.getString(cursor.getColumnIndex(MarketsCategory.Columns.PARENT));
                final String categoryName = cursor.getString(cursor.getColumnIndex(MarketsCategory.Columns.NAME));
                final String categoryDisplayName = cursor.getString(cursor.getColumnIndex(MarketsCategory.Columns.DISPLAY_NAME));


                if (categoryLevel == 2 ) {
                    String categoryParentDisplayName = categoryParentNames.get(categoryParent);
                        if (!categoryParent.equals(previousHeader)) {
                            if (categoryIsSelected) {

                                mCategories.add(new CategoryHeader(categoryParentDisplayName));
                                previousHeader = categoryParent;
                            }
                        }

                        if (!categoryParent.equals(previousAllHeader)) {
                            mAllCategories.add(new CategoryHeader(categoryParentDisplayName));
                            previousAllHeader = categoryParent;
                        }

                        if (categoryIsSelected) {
                            mCategories.add(new SpinnerMarketCategoryRow(categoryName, categoryDisplayName, categoryParent));
                        }
                        mAllCategories.add(new MarketsCategoryCheckableRow(categoryName, categoryDisplayName, categoryIsSelected, categoryIsDefault));

                        if(categoryIsDefault){
                            selectedPosition = mCategories.size()-1;
                        }
                }
            }

            mSpinnerAdapter = new MarketsSpinnerAdapter(Application.getAppContext(), mCategories);
            headerView.setSpinnerAdapter(mSpinnerAdapter);
            headerView.setSpinnerSelectedItemPosition(selectedPosition);
        }
        if (selectedItem instanceof SpinnerMarketCategoryRow) {
            selectedCategory = (SpinnerMarketCategoryRow) mSpinnerAdapter.getItem(position);
        } else {
            if (mSpinnerAdapter.getCount() - 1 >= position + 1) {
                selectedCategory = (SpinnerMarketCategoryRow) mSpinnerAdapter.getItem(position + 1);
            } else {
                selectedCategory = (SpinnerMarketCategoryRow) mSpinnerAdapter.getItem(position - 1);
            }
        }

        final MarketsFragment parentFragment = (MarketsFragment) getParentFragment();
        parentFragment.onCategorySelected(selectedCategory.getCategoryName(), selectedCategory.getCategoryParentName());
    }
@Override
    public void showResults(final Uri uri) {
        LayoutUtils.showResults(getView(), headerView.getSpinnerId());
        headerView.setVisibility(View.VISIBLE);
    }

    @Override
    public void showNoResults(final Uri uri) {
        final MarketsFragment parentFragment = (MarketsFragment) getParentFragment();
        parentFragment.hideSpinner();
        //LayoutUtils.showNoResult(getView(), headerView.getSpinnerId());
    }

    @Override
    public void onDismiss(DialogInterface dialog) {
        headerView.setSelected(false);
    }
    @Override
    public void onNothingSelected(IcsAdapterView<?> parent) {
    }

有什么想法吗?

谢谢!

2 个答案:

答案 0 :(得分:22)

你可以这样做......

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putInt("yourSpinner", yourSpinner.getSelectedItemPosition());
    // do this for each or your Spinner
    // You might consider using Bundle.putStringArray() instead
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // initialize all your visual fields        
    if (savedInstanceState != null) {
        yourSpinner.setSelection(savedInstanceState.getInt("yourSpinner", 0));
        // do this for each of your text views
    }
}

希望这有帮助

答案 1 :(得分:0)

如果设备的配置(由Resources.Configuration类定义)发生更改,则显示用户界面的任何内容都需要更新以匹配该配置,因此Activity除非另行指定,配置更改(例如屏幕方向,语言,输入设备等的更改)将导致您的当前活动被破坏,通过 onPause(),onStop()的正常Activity lifecycle process,以及适当的onDestroy()

如果活动位于前台或用户可见,则在该实例中调用 onDestroy()后,将创建活动的新实例,其中包含 savedInstanceState 上一个实例是从onSaveInstanceState(Bundle)生成的。

这样做是因为任何应用程序资源(包括布局文件)都可以根据任何配置值进行更改。在某些特殊情况下(就像你的,如果我正确的话,如果你只有当前用户界面上的微调器/下拉菜单,你不需要经历完整的活动生命周期),你可能想要绕过基于的活动重启一种或多种配置更改。这是通过其清单中的 android:configChanges 属性完成的,并且/或者您也可以使用 onSaveInstanceState(Bundle) ,当活动被销毁并从中重新创建时,它是调用者begening。

您只需两种方法来解决此问题_

1_

  
      
    1.   
    2. 在您的Activity标记的Manifest文件中添加 android:configChanges =“orientation”
    3.   
  •   
 <?xml version="1.0" encoding="utf-8"?>
 <manifest ...
 >
 <application ...
   >      
    <activity
        android:name="SpinnerActivity"
        android:configChanges="orientation" >
         <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
 </application>

 </manifest>
  
      
  • 2,覆盖 onConfigurationChanged ,当您的活动正在运行时,当设备配置发生变化时,系统会调用该
  • 。   
 @Override
 public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    int orientation = newConfig.orientation;

    switch (orientation) {
    case Configuration.ORIENTATION_LANDSCAPE:
        // do what you want when user is in LANDSCAPE
        break;

    case Configuration.ORIENTATION_PORTRAIT:
        // do what you want when user is in PORTRAIT
        break;
    }

}

2_

使用put方法在onSaveInstanceState()中存储值:

protected void onSaveInstanceState(Bundle savedInstanceState) {
    super.onSaveInstanceState(savedInstanceState);
    //Put your spinner values to restore later...
    savedInstanceState.putLong("yourSpinnerValKey", yourSpinner.getSelectedItemPosition());
}

恢复onCreate()中的值:

public void onCreate(Bundle savedInstanceState) {
    if (savedInstanceState!= null) {
     //get your values to restore...
        value = savedInstanceState.getLong("param");
    }
}

这肯定会解决您的问题,并且在屏幕方向改变时不会刷新您的微调器。我希望这会对你和所有人有所帮助! :)