【问题标题】:MapView messed up my fragment transactions?MapView 搞砸了我的片段交易?
【发布时间】:2016-11-03 21:58:29
【问题描述】:

我有一个带有地图视图的片段。我可以从操作栏中打开另一个片段(称为 listfragment),它工作正常。但是,如果我旋转屏幕,然后尝试打开 listfragment,它不会加载,而是 mapview 会按时闪烁(视图中的地图变为空白,然后再次出现)。如果我尝试通过单击操作栏上的 menuitem 再次加载 listfragment,应用程序会崩溃并显示

java.lang.IllegalStateException:已添加片段:

加载片段的MainActivity部分:

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        mNewTrackFragment = (NewTrackFragment) getFragmentManager()
                .findFragmentByTag(TAG_NEW_TRACK_FRAGMENT);
        if (mNewTrackFragment == null) {
            mNewTrackFragment = NewTrackFragment.newInstance();
        }
        FragmentManager fragmentManager = getFragmentManager();
        fragmentManager.beginTransaction()
                .add(R.id.fragment_container, mNewTrackFragment)
                .commit();
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        if (id == R.id.action_track_list) {
            if (null == mTrackListFragment) {
                mTrackListFragment = TrackListFragment.newInstance();
            }
            FragmentManager fragmentManager = getFragmentManager();
            fragmentManager.beginTransaction()
                    .replace(R.id.fragment_container, mTrackListFragment, TAG_TRACK_LIST_FRAGMENT)
                    .addToBackStack(null)
                    .commit();

            return true;
        }

带有 MapView 的 NewTrackFragment 的一部分:

    public NewTrackFragment() {
}

public static NewTrackFragment newInstance() {
    NewTrackFragment fragment = new NewTrackFragment();
    return fragment;
}

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

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_new_track, container, false);

    mTrackTitleTV = (TextView) view.findViewById(R.id.tv_track_title);
    mDistanceTV = (TextView) view.findViewById(R.id.tv_distance);
    mElapsedTimeTV = (TextView) view.findViewById(R.id.tv_elapsed_time);
    mSpeedTV = (TextView) view.findViewById(R.id.tv_speed);
    mAscentTV = (TextView) view.findViewById(R.id.tv_ascent);
    mDescentTV = (TextView) view.findViewById(R.id.tv_descent);
    mAltitudeTV = (TextView) view.findViewById(R.id.tv_altitude);
    mStartStopFab = (FloatingActionButton) view.findViewById(R.id.fab_startstop);
    mMapView = (MapView) view.findViewById(R.id.new_track_mapview);

    setupMapView(savedInstanceState);

    return view;
}

private void setupMapView(Bundle savedInstanceState) {
    mMapView.onCreate(savedInstanceState);
    mMapView.getMapAsync(this);
}

我在谷歌上搜索了一些关于它的信息,但没有发现任何类似的信息。

【问题讨论】:

    标签: android android-fragments android-mapview


    【解决方案1】:

    这里有几个问题。现在,您没有将TAG_NEW_TRACK_FRAGMENT 作为标签传递给onCreate 内的add。因此,您将添加一个没有关联标记的NewTrackFragment 实例,因此对findFragmentByTag 的调用将始终返回null。本质上,您每次旋转设备时都会创建一个NewTrackFragment 的新实例。这不好,因为FragmentManager 的状态会在设备旋转期间保留,这意味着它仍会保留您添加到其中的每个Fragment。因为您无条件调用add,所以FragmentManager 最终会持有NewTrackFragment 的多个实例。

    话虽如此,您应该做的是将标签添加到add 的调用中,并且只有在您知道FragmentManager 当前没有保留NewTrackFragment 的实例时才调用add

    mNewTrackFragment = (NewTrackFragment) getFragmentManager()
                    .findFragmentByTag(TAG_NEW_TRACK_FRAGMENT);
            if (mNewTrackFragment == null) {
                mNewTrackFragment = NewTrackFragment.newInstance();
                FragmentManager fragmentManager = getFragmentManager();
                fragmentManager.beginTransaction()
                        .add(R.id.fragment_container, mNewTrackFragment, TAG_NEW_TRACK_FRAGMENT)
                        .commit();
            }
    

    您可能也想对您的TrackListFragment 做类似的事情:

    if (id == R.id.action_track_list) {
                FragmentManager fragmentManager = getFragmentManager();
                mTrackListFragment = (TrackListFragment) fragmentManager.findFragmentByTag(TAG_TRACK_LIST_FRAGMENT);
                if (null == mTrackListFragment) {
                    mTrackListFragment = TrackListFragment.newInstance();
                    fragmentManager.beginTransaction()
                            .replace(R.id.fragment_container, mTrackListFragment, TAG_TRACK_LIST_FRAGMENT)
                            .addToBackStack(null)
                            .commit();
                }
    }
    

    【讨论】:

    • 感谢您的回答,它解决了我的问题。由于其他错误,我早些时候搞砸了我的片段交易。实施您的解决方案再次设置正确:)
    猜你喜欢
    • 1970-01-01
    • 2011-03-10
    • 2018-04-02
    • 2012-05-04
    • 1970-01-01
    • 1970-01-01
    • 2014-03-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多