下面是我正在使用的 MainActivity 类。该代码检查手机是横向还是纵向。如果它是纵向的,它将只显示主要 Activity 中的主要 fragment (主要 fragment 是 main_activity.xml 文件中的静态 fragment )。然后,如果单击“食谱”,它将打开一个带有自己 fragment 的详细 Activity 。如果手机处于横向模式,它将并排显示主要 fragment 和细节 fragment 。一切正常,但是当我按照以下步骤操作时,我得到的是白屏而不是主要 Activity :
程序:
- 切换到横向
- 切换回纵向
- 选择一个项目并等待详细 Activity 打开
- 按回
- 这里不是主 Activity 窗口,而是白屏
如果我不切换到横向,而只是从纵向模式开始,一切都很好。似乎切换到横向会导致问题,我无法弄清楚是什么。任何关于正在发生的事情或在哪里寻找的提示都将不胜感激。
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 的建议,为 fragment 和 Activity 创建了不同的背景颜色,最后将问题缩小到我的 recyclerview 适配器代码中的一行。我的适配器代码如下。在 loadInBackground()
行 URL url = new URL(getString(R.string.URL_RecipeJSON));
中,我得到一个 Fragment RecipesFragment{96e9b6a}未附加到 Activity 异常。我不明白为什么我会收到此异常以及解决此问题的最佳方法是什么。我是否在正确的 fragment 方法中放置了正确的代码(即 OnCreate 与 OnActivityCreated 与 OnCreateView 等)?
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) {
}
}
最佳答案
我终于想通了问题和解决办法。问题是 RecipesFragment
类中的 AsyncTaskLoader
匿名类中的 onStartLoading()
每次 fragment 恢复时调用是否包含Loader 是否被调用。这导致了问题。我需要控制何时调用 onStartLoading()
并且我只希望它被调用 当且仅当正在初始化或重新启动封闭的 Loader 时。因此,我在 fragment 的 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);
}
我还从 onCreate()
中删除了 initLoader()
。这样,每次恢复(或创建) fragment 时,都会调用 onStartLoading()
。我试过了,它解决了我的问题。
关于android - 为什么在横向到纵向切换后从详细 Activity 中按回显示空白屏幕?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48008780/