为什么在横向到纵向切换后显示空屏幕后从详细活动中回退?

问题描述 投票:1回答:2

下面是我正在使用的MainActivity类。代码检查手机是横向还是纵向。如果它是纵向的,它将仅显示主活动中的主要片段(主要片段是main_activity.xml文件中的静态片段)。然后,如果单击“配方”,它将打开具有其自己的片段的详细活动。如果手机处于横向模式,它将并排显示主片段和细节片段。一切都很完美,但是当我按照下面的步骤操作时,我会得到一个白色的屏幕,而不是主要的活动:

程序:

  1. 切换到风景
  2. 切换回肖像
  3. 选择一个项目并等待详细活动打开
  4. 按下
  5. 这里取代主活动窗口,我得到一个白色的屏幕

如果我不切换到横向,只是从肖像模式开始,一切都很好。看起来像切换到横向做了导致问题的事情,我无法弄清楚是什么。任何有关正在发生的事情或在哪里寻找的提示都将非常感激。

public class MainActivity extends AppCompatActivity implements RecipesFragment.OnRecipeClickListener {

    private String RECIPE_PARCEL_KEY;
    private boolean mTwoPane;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        RECIPE_PARCEL_KEY = getString(R.string.ParcelKey_RecipeParcel);
        if (findViewById(R.id.linearLayoutTwoPane) != null) {
            mTwoPane = true;
            if (savedInstanceState == null) {
                RecipeFragment recipeFragment = new RecipeFragment();
                FragmentManager fragmentManager = getSupportFragmentManager();
                fragmentManager.beginTransaction()
                        .add(R.id.recipeFrameForTwoPane, recipeFragment)
                        .commit();
            }
        } else {
            mTwoPane = false;
        }
    }

    @Override
    public void OnRecipeClick(Recipe recipe) {
        if (mTwoPane) {
            RecipeFragment recipeFragment = new RecipeFragment();
            recipeFragment.setRecipe(recipe);
            FragmentManager fragmentManager = getSupportFragmentManager();
            fragmentManager.beginTransaction()
                    .replace(R.id.recipeFrameForTwoPane, recipeFragment)
                    .commit();
        } else {
            Class destinationClass = DetailActivity.class;
            Intent intentToStartDetailActivity = new Intent(this, destinationClass);
            intentToStartDetailActivity.putExtra(RECIPE_PARCEL_KEY, recipe);
            startActivity(intentToStartDetailActivity);
        }
    }
}

编辑:在下面添加RecipeFragment的代码:

public class RecipeFragment extends Fragment {

    private Recipe mRecipe;
    @BindView(R.id.tv_recipeName) TextView recipeNameTextView;

    public RecipeFragment(){
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.recipe_fragment,container,false);
        ButterKnife.bind(this,view);
        if(mRecipe!=null) {
            recipeNameTextView.setText(mRecipe.getName());
        }else{
            recipeNameTextView.setText(getString(R.string.messageSelectARecipe));
        }
        return view;
    }

    public void setRecipe(Recipe recipe){
        mRecipe = recipe;
    }
}

编辑:我按照@ mt0s的建议,为片段和活动创建了不同的背景颜色,最后将问题缩小到我的recyclerview适配器代码中的一行。我的适配器代码如下。在Qazxswpoi线上的loadInBackground()里面,我得到一个Fragment RecipesFragment {96e9b6a}没有附加到Activity异常。我不明白为什么我得到这个例外以及解决这个问题的最佳方法是什么。我是否在正确的片段方法中放置了正确的代码(即OnCreate vs OnActivityCreated vs OnCreateView vs)?

URL url = new URL(getString(R.string.URL_RecipeJSON));
android android-fragments android-activity android-fragmentactivity android-lifecycle
2个回答
1
投票

我终于找到了问题和解决方案。问题是public class RecipesFragment extends Fragment implements RecipeAdapter.RecipeAdapterOnClickHandler, LoaderManager.LoaderCallbacks<ArrayList<Recipe>> { @BindView(R.id.rv_recipes) RecyclerView mRecyclerView; private RecipeAdapter mRecipeAdapter; private static final int LOADER_ID = 1000; private static final String TAG = "RecipesFragment"; private OnRecipeClickListener mOnRecipeClickListener; public RecipesFragment(){ } public interface OnRecipeClickListener { void OnRecipeClick(Recipe recipe); } @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.recipes_fragment, container, false); ButterKnife.bind(this, view); LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false); mRecyclerView.setLayoutManager(layoutManager); mRecyclerView.setHasFixedSize(true); mRecipeAdapter = new RecipeAdapter(this); mRecyclerView.setAdapter(mRecipeAdapter); return view; } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); } @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); getLoaderManager().initLoader(LOADER_ID, null, this); } @Override public void onPause() { super.onPause(); } @Override public void onResume() { super.onResume(); } @Override public void OnClick(Recipe recipe) { mOnRecipeClickListener.OnRecipeClick(recipe); } @Override public void onAttach(Context context) { super.onAttach(context); try{ mOnRecipeClickListener = (OnRecipeClickListener) context; } catch (ClassCastException e){ Log.e(TAG, "onAttach: Host activity class must implement OnRecipeClickListener."); } } @Override public Loader<ArrayList<Recipe>> onCreateLoader(int i, Bundle bundle) { return new AsyncTaskLoader<ArrayList<Recipe>>(getActivity()) { @Override protected void onStartLoading() { super.onStartLoading(); forceLoad(); } @Override public ArrayList<Recipe> loadInBackground() { String response; ArrayList<Recipe> recipes = null; try { URL url = new URL(getString(R.string.URL_RecipeJSON)); //***I get an exception here*** response = NetworkUtils.getResponseFromHttpUrl(url, getActivity()); recipes = RecipeJsonUtils.getRecipeFromJson(getActivity(), response); } catch (Exception e) { Log.e(TAG, "loadInBackground: " + e.getMessage()); } return recipes; } }; } @Override public void onLoadFinished(Loader<ArrayList<Recipe>> loader, ArrayList<Recipe> recipes) { mRecipeAdapter.setRecipeData(recipes); } @Override public void onLoaderReset(Loader<ArrayList<Recipe>> loader) { } } 类中的onStartLoading()匿名类中的AsyncTaskLoader会在每次恢复片段时被调用,无论封闭的Loader是否被调用。这导致了问题。我需要控制何时调用RecipesFragment,我只希望它被调用当且仅当初始化或重新启动封闭的Loader时。因此,我在片段的onStartLoading()中销毁了装载器并在onPause()重新启动它。因此,我将以下代码添加到onResume()类:

RecipesFragment

我还从@Override public void onPause() { super.onPause(); getLoaderManager().destroyLoader(LOADER_ID); } @Override public void onResume() { super.onResume(); getLoaderManager().restartLoader(LOADER_ID, null, this); } 中删除了initLoader()。这样,每次恢复(或创建)片段时都会调用onCreate()。我尝试了这个,它解决了我的问题。


0
投票

当您从横向切换到纵向或相反时,Android OS会破坏您的活动并再次重新创建它。这可能会引发你的问题

© www.soinside.com 2019 - 2024. All rights reserved.