微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Android片段在方向更改时创建了两次

我有这个奇怪的问题,我的列表片段被创建两次,一次当super.oncreate被调用父活动,一次当setContentView被调用在同一个父活动.这是一个简单的应用程序,我使用不同的布局为纵向和横向.

这是主要的活动:

private HeadlinesFragment headlines;

@Override
public void onCreate(Bundle savedInstanceState) {
    Log.w("MainActivity","Before super.onCreate: " + this.toString());
    super.onCreate(savedInstanceState);
    Log.w("MainActivity","Before setContentView: " + this.toString());
    setContentView(R.layout.news_articles);

    //check to see if its portrait
    if (findViewById(R.id.fragment_container) != null) {
        if(getSupportFragmentManager().findFragmentById(R.id.fragment_container) == null) {
            headlines = new HeadlinesFragment();
            getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,headlines).commit();
        }
    }
}

这里是layout-land文件夹中的news_articles:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">

<fragment android:name="com.example.android.fragments.HeadlinesFragment"
          android:id="@+id/headlines_fragment"
          android:layout_weight="1"
          android:layout_width="0dp"
          android:layout_height="match_parent" />

<fragment android:name="com.example.android.fragments.ArticleFragment"
          android:id="@+id/article_fragment"
          android:layout_weight="2"
          android:layout_width="0dp"
          android:layout_height="match_parent" />

这里是layout_articles在layout文件夹(为纵向)

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />

这里是两次头条碎片

public class HeadlinesFragment extends ListFragment {
OnHeadlineselectedListener mCallback;

// The container Activity must implement this interface so the frag can deliver messages
public interface OnHeadlineselectedListener {
    /** Called by HeadlinesFragment when a list item is selected */
    public void onArticleSelected(int position);
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.w("HeadlinesFragment","inside onCreate: " + this.toString());

    // We need to use a different list item layout for devices older than Honeycomb
    int layout = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ?
            android.R.layout.simple_list_item_activated_1 : android.R.layout.simple_list_item_1;

    // Create an array adapter for the list view,using the Ipsum headlines array
    setlistadapter(new ArrayAdapter<String>(getActivity(),layout,Ipsum.Headlines));
}

@Override
public void onStart() {
    super.onStart();

    // When in landscape layout,set the listview to highlight the selected list item
    // (We do this during onStart because at the point the listview is available.)
    if (getFragmentManager().findFragmentById(R.id.article_fragment) != null) {
        getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
    }
}

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);

    // This makes sure that the container activity has implemented
    // the callback interface. If not,it throws an exception.
    try {
        mCallback = (OnHeadlineselectedListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
                + " must implement OnHeadlineselectedListener");
    }
}


@Override
public void onCreateOptionsMenu(Menu menu,MenuInflater inflater) {
    // Todo Auto-generated method stub
    super.onCreateOptionsMenu(menu,inflater);
}

@Override
public void onDestroy() {
    Log.w("HeadlinesFragment","inside onDestroy: " + this.toString());
    super.onDestroy();
}
}

这里是文章片段

public class ArticleFragment extends Fragment {
final static String ARG_POSITION = "position";
int mCurrentPosition = 0;

@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
    Log.w("ArticleFragment","inside onCreateView: " + this.toString());

    if (savedInstanceState != null) {
        mCurrentPosition = savedInstanceState.getInt(ARG_POSITION);
    }

    // Inflate the layout for this fragment
    View view = inflater.inflate(R.layout.article_view,container,false);
    return view;
}

@Override
public void onStart() {
    super.onStart();
    Bundle args = getArguments();
    if (args != null) {
        // Set article based on argument passed in
        updateArticleView(args.getInt(ARG_POSITION));
    } else if (mCurrentPosition != -1) {
        // Set article based on saved instance state defined during onCreateView
        updateArticleView(mCurrentPosition);
    }
}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

    // Save the current article selection in case we need to recreate the fragment
    outState.putInt(ARG_POSITION,mCurrentPosition);
}

@Override
public void onDestroy() {
    Log.w("ArticleFragment","inside onDestroy: " + this.toString());
    super.onDestroy();
}

}

这个问题的细节是这样的:

1)以纵向方向启动应用程序
2)setContentView被调用,并且news_articles被加载,但是其中包含了fragment_container.
3)headlinesfragment被创建//到目前为止正常行为
4)将方向改为景观
5)主动性被破坏 – >标题碎片被摧毁
6)super.oncreate on mainactivity被称为
7)创建标题片段
8)setcontentview的主动性被称为
9)另一个headlinefragment被创建//问题

我已经放置了日志,可以在上面的代码中看到,这里是当我以纵向模式启动应用程序时的输出,我改为横向.

W/MainActivity(6925): Before super.onCreate: MainActivity@41d81238
W/MainActivity(6925): Before setContentView: MainActivity@41d81238
W/HeadlinesFragment(6925): inside onCreate: HeadlinesFragment{41d8d4d8 #0 id=0x7f050001}
W/MainActivity(6925): inside onDestroy: MainActivity@41d81238
W/HeadlinesFragment(6925): inside onDestroy: HeadlinesFragment{41d8d4d8 # 0id=0x7f050001}
W/MainActivity(6925): Before super.onCreate: MainActivity@41ea6258
W/HeadlinesFragment(6925): inside onCreate: HeadlinesFragment{41ea7290 #0 id=0x7f050001}
W/MainActivity(6925): Before setContentView: MainActivity@41ea6258
W/HeadlinesFragment(6925): inside onCreate: HeadlinesFragment{41eb1f30 #1 id=0x7f050002}
W/ArticleFragment(6925): inside onCreateView: ArticleFragment{41eb5f20 #2 id=0x7f050003}

我希望我已经清楚了我的代码和日志,在我看来,super.oncreate和setcontentview都创建了一个头条碎片;至少我想.

我的问题是为什么会创建2个头条碎片实例,以及如何避免这种情况.

非常感谢任何有关这方面的帮助

解决方法

在您的活动的onCreate中,您可以检查savedInstanceState包的状态.如果它不为空,则表示发生配置更改(在您的情况下,屏幕方向更改),并且您不需要重新创建片段.

你正在做的另一个错误是你试图用findFragmentById来检索你的片段.而不是传递Fragment id,而是给它附加到Fragment的View的id,这是不同的(这就是为什么我猜这是总是返回null)的原因.

正确的实现将更像是这样(这是你的Activity):

//check to see if its portrait
    if (findViewById(R.id.fragment_container) != null) {
        if(savedInstanceState == null) {
            headlines = new HeadlinesFragment();
            getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,headlines,FRAGMENT_TAG_STRING).commit(); // Use tags,it's simpler to deal with
        } else {
            headlines = getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG_STRING);
        } 
   }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


这篇“android轻量级无侵入式管理数据库自动升级组件怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定...
今天小编给大家分享一下Android实现自定义圆形进度条的常用方法有哪些的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文...
这篇文章主要讲解了“Android如何解决字符对齐问题”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Android...
这篇文章主要介绍“Android岛屿数量算法怎么使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Android岛屿数量算...
本篇内容主要讲解“Android如何开发MQTT协议的模型及通信”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Andro...
本文小编为大家详细介绍“Android数据压缩的方法是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“Android数据压缩的方法是什么”文章能帮助大家解决疑惑...
这篇“Android怎么使用Intent传大数据”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅...
本文小编为大家详细介绍“Android事件冲突怎么解决悬浮窗拖拽问题”,内容详细,步骤清晰,细节处理妥当,希望这篇“Android事件冲突怎么解决悬浮窗拖拽问题”文...
这篇文章主要介绍了Android拼接如何实现动态对象的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Android拼接如何实现动态对象文...
今天小编给大家分享一下Android全面屏适配怎么实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下...