在onSavedInstance之后无法执行此操作

时间:2016-10-26 05:58:38

标签: android android-fragments savestate

当屏幕旋转发生时,我一直面临着这个问题。我已经看到了堆栈溢出的所有类似帖子,但没有运气。

这是我的活动,有两个片段NEwsList和NewsDetails 单击列表中的项目时将调用NewsDetails片段。

public class MainActivity extends AppCompatActivity implements OnNewsItemClicked, PresenterLocator {


@Bind(R.id.news_list_fragment)
FrameLayout listFragmentContainer;

@Nullable
@Bind(R.id.news_details_fragment)
FrameLayout newsDetailsContainer;

private boolean isTablet;
private NewsScreenPresenter presenter;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ButterKnife.bind(this);
    isTablet = newsDetailsContainer == null ? false : true;

    presenter = (NewsScreenPresenter) getLastCustomNonConfigurationInstance();
    if (presenter == null) {
        presenter = new NewsScreenPresenter(new NewsRetrofitGateway(), this);
    }

    if (savedInstanceState == null) {
        attachListFragment();
    }
}

private void attachListFragment() {
    Fragment listFragment = new NewsListFragment();
    Bundle bundle = new Bundle();
    bundle.putBoolean(NewsListFragment.IS_TABLET, isTablet);
    listFragment.setArguments(bundle);

    FragmentManager manager = getSupportFragmentManager();
    FragmentTransaction transaction = manager.beginTransaction();
    transaction.replace(R.id.news_list_fragment, listFragment);
    transaction.commit();
}

@Override
public Object onRetainCustomNonConfigurationInstance() {
    return presenter;
}

@Override
public void onNewsItemClicked(String title, String summary, String picUrl, String storyUrl) {
    if (!isFinishing()) {
        Fragment fragment = new NewsDetailFragment();
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        fragment.setArguments(NewsDetailFragment.buildArguments(title, summary, picUrl, storyUrl));
        if (!isTablet) {
            transaction.add(R.id.news_list_fragment, fragment);
            transaction.addToBackStack(null);
            transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        } else {
            transaction.replace(R.id.news_details_fragment, fragment);
        }
        transaction.commit();
    }
}

@Override
public NewsScreenPresenter getPresenter() {
    return presenter;
}}

NewsListFramgment

public class NewsListFragment extends Fragment implements NewsScreenView {

public static final String IS_TABLET = "is_tablet";
private NewsScreenPresenter presenter;

@Bind(R.id.progressBar)
LinearLayout progressBar;

@Bind(R.id.recycler_view)
RecyclerView recyclerView;

private boolean isTablet;
private PresenterLocator locator;

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    locator = (PresenterLocator) context;
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View listView = inflater.inflate(R.layout.new_list_layout, null);
    ButterKnife.bind(this, listView);
    return listView;

}

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    recyclerView.setHasFixedSize(true);
    LinearLayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
    recyclerView.setLayoutManager(mLayoutManager);

    isTablet = getArguments().getBoolean(IS_TABLET);
}

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

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    presenter = locator.getPresenter();
    presenter.onViewCreated(this);
}

@Override
public void showProgressBar() {
    progressBar.setVisibility(View.VISIBLE);
}

@Override
public void hideProgress() {
    if (progressBar.getVisibility() == View.VISIBLE) {
        progressBar.setVisibility(View.GONE);
    }
}

@Override
public void populateNewsInList(final NewsResponseMapper news) {
    NewsListAdapter adapter = new NewsListAdapter(news, new OnRecycleItemClick() {
        @Override
        public void onItemClick(int position) {
            presenter.onItemClick(position);
        }
    });
    recyclerView.setAdapter(adapter);

    if (isTablet) {
        presenter.onItemClick(0);
    }
}

@Override
public void showError(String errorMsg) {
    Toast.makeText(getActivity(), errorMsg, Toast.LENGTH_LONG).show();
}

interface OnRecycleItemClick {
    void onItemClick(int position);
}

NewsDetialsFragment

public class NewsDetailFragment extends Fragment {

public static final String STORY_URL = "storyURL";
public static final String TITLE = "title";
public static final String SUMMARY = "summary";
public static final String IMAGE_URL = "imageURL";

private BrowserNavigation browserNavigation;

@Bind(R.id.title)
TextView titleView;
@Bind(R.id.summary_content)
TextView summaryView;
@Bind(R.id.news_image)
DraweeView imageView;


public static Bundle buildArguments(String title, String summary,
                                    String picUrl, String storyUrl) {
    Bundle bundle = new Bundle();
    bundle.putString(TITLE, title);
    bundle.putString(SUMMARY, summary);
    bundle.putString(IMAGE_URL, picUrl);
    bundle.putString(STORY_URL, storyUrl);
    return bundle;
}

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setRetainInstance(true);
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View detailsView = inflater.inflate(R.layout.activity_detail, null);
    ButterKnife.bind(this, detailsView);
    return detailsView;
}

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    Bundle extras = getArguments();
    String storyURL = extras.getString(STORY_URL);
    String title = extras.getString(TITLE);
    String summary = extras.getString(SUMMARY);
    String imageURL = extras.getString(IMAGE_URL);

    browserNavigation = new BrowserNavigation(getActivity(), storyURL);

    titleView.setText(title);
    summaryView.setText(summary);

    DraweeController draweeController = Fresco.newDraweeControllerBuilder()
            .setImageRequest(ImageRequest.fromUri(Uri.parse(imageURL)))
            .setOldController(imageView.getController()).build();
    imageView.setController(draweeController);

}

@OnClick(R.id.full_story_link)
public void fullStoryClicked() {
    browserNavigation.navigate();
}

通过查看代码,您可以理解我正在关注MVP架构,当我看到NewsListFragment并旋转设备时,我正在使用onRetianCustomNonConfiguration()回调将活动者保存在活动中,以免再次调用服务器再次获取新闻列表。 一切都按预期工作正常,但是在旋转之后,每当我尝试单击列表中的项目以显示DetailsFragment(onNewsItemClick())时,它就会崩溃并发生非法状态异常"无法在OnSavedInstanceState"之后执行此操作。

有人能指出我在这里犯的错误吗?

FATAL EXCEPTION: main
                                                                           Process: news.agoda.com.technewssample, PID: 24160
                                                                           java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
                                                                               at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1493)
                                                                               at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1511)
                                                                               at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:638)
                                                                               at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:617)
                                                                               at news.agoda.com.sample.presentation.MainActivity.onNewsItemClicked(MainActivity.java:96)
                                                                               at news.agoda.com.sample.NewsScreenPresenter.onItemClick(NewsScreenPresenter.java:55)
                                                                               at news.agoda.com.sample.presentation.NewsListFragment$1.onItemClick(NewsListFragment.java:89)
                                                                               at news.agoda.com.sample.presentation.NewsListAdapter$1.onClick(NewsListAdapter.java:76)
                                                                               at android.view.View.performClick(View.java:4785)
                                                                               at android.view.View$PerformClick.run(View.java:19888)
                                                                               at android.os.Handler.handleCallback(Handler.java:739)
                                                                               at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                               at android.os.Looper.loop(Looper.java:135)
                                                                               at android.app.ActivityThread.main(ActivityThread.java:5276)
                                                                               at java.lang.reflect.Method.invoke(Native Method)
                                                                               at java.lang.reflect.Method.invoke(Method.java:372)
                                                                               at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:911)
                                                                               at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:706)

0 个答案:

没有答案