努力理解Android碎片和设备旋转

努力理解Android碎片和设备旋转,android,android-fragments,Android,Android Fragments,我构建了一个非常简单的Android应用程序,其中有一个用于添加片段的按钮和一个用于托管片段的线性布局。当设备旋转时,碎片将恢复到正确的布局中。它起作用了 但是,如果我在具有更复杂用户界面的活动中复制上述简单应用程序的代码,则当设备旋转时,片段将消失。从日志消息中,我无法理解原因 这是包含片段线性布局的布局 这是我写过的最长的问题,我希望有人有足够的耐心读到最后 该活动有两个字段,我用于附加片段实例: 当用户使用此侦听器点击按钮时,将创建新片段: addPacketIV = (ImageView

我构建了一个非常简单的Android应用程序,其中有一个用于添加片段的按钮和一个用于托管片段的线性布局。当设备旋转时,碎片将恢复到正确的布局中。它起作用了

但是,如果我在具有更复杂用户界面的活动中复制上述简单应用程序的代码,则当设备旋转时,片段将消失。从日志消息中,我无法理解原因

这是包含片段线性布局的布局

这是我写过的最长的问题,我希望有人有足够的耐心读到最后

该活动有两个字段,我用于附加片段实例:

当用户使用此侦听器点击按钮时,将创建新片段:

addPacketIV = (ImageView) findViewById(R.id.addPacketIV);
        addPacketIV.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                addNewPacketFragment();
            }
});

protected void addNewPacketFragment() {
        Log.d(TAG, "");
        int currentFragmentIndex= fragmentIndex++;
        String tagForFragment = FRAGMENT_TAG + currentFragmentIndex;
        Log.d(TAG, "\n** Creating new Packet Editor TAG= " + tagForFragment);
        addPacketEditor(tagForFragment);
}

protected void addPacketEditor(String fragmentTag) {
   if(fragmentTag == null) {
     Log.d(TAG, "Received a null fragmentTag - should never happen!");
     return;
   }

   PacketEditorFragment fragment = (PacketEditorFragment)
                getSupportFragmentManager().findFragmentByTag(fragmentTag);

   if(fragment == null) {
       Log.d(TAG, "No fragment found for tag " + fragmentTag + " - create new one");
       fragment = PacketEditorFragment.newInstance();
       fragment.setRetainInstance(true);
       getSupportFragmentManager()
               .beginTransaction()
               .add(R.id.packetsFragmentContainer, fragment, fragmentTag)
               .commit();
            Log.d(TAG, "New fragment created and added to linear layout: " + fragmentTag);
   } else {
       Log.d(TAG, "Fragment " + fragmentTag + " already attached to this activity");
   }

   Log.d(TAG, "Adding this fragment to allFragments: " + fragment.getTag());
   allFragments.add(fragment);

   Log.d(TAG, "Printing fragments:");
   int nFrags = allFragments.size();
   for(int i=0; i<nFrags; i++) {
      Log.d(TAG, "Fragment " + i + " - tag " + allFragments.get(i).getTag());
   }

   Log.d(TAG, "Num of attached fragment allFragments.size(): " + allFragments.size());
   Log.d(TAG, "Num of attached fragment packetContainer.childCount(): " + packetFragmentContainerVG.getChildCount());
} // addPacketEditor
这是onRestoreInstanceState:

以下是添加其他两个片段时打印的日志消息:

添加了三个片段:您可以从红色背景色中识别它们

此时设备旋转,调用onSaveInstanceState

。。。调用onRestoreInstanceState

即使看起来一切正常,也只显示了三个片段中的两个,特别是第二个片段

事实上,当设备再次旋转时,您可以看到出现了一些问题

如您所见,三个片段中有两个现在有空标记。在两次旋转之间什么也没有发生:根本没有用户交互

如果设备再次旋转,则不会显示碎片

如果你还在读书,那么请注意,当你访问意大利时,你将得到一份免费的比萨饼和啤酒

如果你能解决这个问题,那么我还将在当地最好的餐厅之一提供晚餐——但你必须先来意大利


注:请原谅自动补全(语言设置为意大利语)带来的拼写错误。我可以纠正它们,但它们与本问题中讨论的问题无关。

@bwegs既然你来了,也许值得提供一个答案:-我们可以看一些图片来了解情况吗?@bwegs Ok,我将准备屏幕截图。@bwegs我添加了屏幕截图。不幸的是,我对这方面了解不够,无法告诉您问题出在哪里,但是如果您还没有阅读Android开发文档,那么这可能会很有用-
addPacketIV = (ImageView) findViewById(R.id.addPacketIV);
        addPacketIV.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                addNewPacketFragment();
            }
});

protected void addNewPacketFragment() {
        Log.d(TAG, "");
        int currentFragmentIndex= fragmentIndex++;
        String tagForFragment = FRAGMENT_TAG + currentFragmentIndex;
        Log.d(TAG, "\n** Creating new Packet Editor TAG= " + tagForFragment);
        addPacketEditor(tagForFragment);
}

protected void addPacketEditor(String fragmentTag) {
   if(fragmentTag == null) {
     Log.d(TAG, "Received a null fragmentTag - should never happen!");
     return;
   }

   PacketEditorFragment fragment = (PacketEditorFragment)
                getSupportFragmentManager().findFragmentByTag(fragmentTag);

   if(fragment == null) {
       Log.d(TAG, "No fragment found for tag " + fragmentTag + " - create new one");
       fragment = PacketEditorFragment.newInstance();
       fragment.setRetainInstance(true);
       getSupportFragmentManager()
               .beginTransaction()
               .add(R.id.packetsFragmentContainer, fragment, fragmentTag)
               .commit();
            Log.d(TAG, "New fragment created and added to linear layout: " + fragmentTag);
   } else {
       Log.d(TAG, "Fragment " + fragmentTag + " already attached to this activity");
   }

   Log.d(TAG, "Adding this fragment to allFragments: " + fragment.getTag());
   allFragments.add(fragment);

   Log.d(TAG, "Printing fragments:");
   int nFrags = allFragments.size();
   for(int i=0; i<nFrags; i++) {
      Log.d(TAG, "Fragment " + i + " - tag " + allFragments.get(i).getTag());
   }

   Log.d(TAG, "Num of attached fragment allFragments.size(): " + allFragments.size());
   Log.d(TAG, "Num of attached fragment packetContainer.childCount(): " + packetFragmentContainerVG.getChildCount());
} // addPacketEditor
@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    Log.d(TAG, "onSaveInstanceState called");
    Log.d(TAG, "packetContainer.childCount() " + packetFragmentContainerVG.getChildCount());

    // Store the index for future fragments
    outState.putInt(KEY_STATE_FRAGMENT_INDEX, fragmentIndex);
    Log.d(TAG, "Saved current fragment index: " + fragmentIndex);

    int nPackets = allFragments.size();


    // Store the number of packet fragments
    outState.putInt(KEY_STATE_N_PACKET_EDITORS, nPackets);
    Log.d(TAG, "onSaveInstanceState: " +  nPackets + " packets");

    // for each attached fragment store its tag
    for(int i=0; i<nPackets; i++) {
        String fragmentTag = allFragments.get(i).getTag();
        Log.d(TAG, "Saving fragment " + i +") " + fragmentTag);
        outState.putString(KEY_STATE_PACKET_FRAGMENT + i, fragmentTag);
    } // for
} // onSaveInstanceState
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    Log.d(TAG, "onRestoreInstanceState");
    fragmentIndex = savedInstanceState.getInt(KEY_STATE_FRAGMENT_INDEX);
    Log.d(TAG, "Restored index for fragments: " + fragmentIndex);
    restorePacketEditors(savedInstanceState);
}

protected void restorePacketEditors(Bundle savedInstanceState) {
    int nSavedPackets = savedInstanceState.getInt(KEY_STATE_N_PACKET_EDITORS);
    Log.d(TAG, "Restoring packets, number: " + nSavedPackets);
    for(int i = 0; i<nSavedPackets; i++) {
        String fragmentTag = savedInstanceState.getString(KEY_STATE_PACKET_FRAGMENT+i);
        Log.d(TAG, i+") has tag " + fragmentTag);
        addPacketEditor(fragmentTag);
    }
} // restorePacketEditors
No fragment found for tag tag_10000 - create new one
New fragment created and added to linear layout: tag_10000
Adding this fragment to allFragments: tag_10000
Printing fragments:
Fragment 0 - tag tag_10000
Num of attached fragment allFragments.size(): 1
Num of attached fragment packetContainer.childCount(): 0
No fragment found for tag tag_10001 - create new one
New fragment created and added to linear layout: tag_10001
Adding this fragment to allFragments: tag_10001
Printing fragments:
Fragment 0 - tag tag_10000
Fragment 1 - tag tag_10001
Num of attached fragment allFragments.size(): 2
Num of attached fragment packetContainer.childCount(): 1
No fragment found for tag tag_10002 - create new one
New fragment created and added to linear layout: tag_10002
Adding this fragment to allFragments: tag_10002
Printing fragments:
Fragment 0 - tag tag_10000
Fragment 1 - tag tag_10001
Fragment 2 - tag tag_10002
Num of attached fragment allFragments.size(): 3
Num of attached fragment packetContainer.childCount(): 2
onSaveInstanceState called
packetContainer.childCount() 3
Saved current fragment index: 10003
onSaveInstanceState: 3 packets
Saving fragment 0) tag_10000
Saving fragment 1) tag_10001
Saving fragment 2) tag_10002
OnStop called
onRestoreInstanceState
Restored index for fragments: 10003
Restoring packets, there are: 3
0) has tag tag_10000
Fragment tag_10000 already attached to this activity
Adding this fragment to allFragments: tag_10000
Printing fragments:
Fragment 0 - tag tag_10000
Num of attached fragment allFragments.size(): 1
Num of attached fragment packetContainer.childCount(): 3
1) has tag tag_10001
Fragment tag_10001 already attached to this activity
Adding this fragment to allFragments: tag_10001
Printing fragments:
Fragment 0 - tag tag_10000
Fragment 1 - tag tag_10001
Num of attached fragment allFragments.size(): 2
Num of attached fragment packetContainer.childCount(): 3
2) has tag tag_10002
Fragment tag_10002 already attached to this activity
Adding this fragment to allFragments: tag_10002
Printing fragments:
Fragment 0 - tag tag_10000
Fragment 1 - tag tag_10001
Fragment 2 - tag tag_10002
Num of attached fragment allFragments.size(): 3
Num of attached fragment packetContainer.childCount(): 3
There are 3 fragments
0) tag_10000
1) tag_10001
2) tag_10002
onSaveInstanceState called
Saved current fragment index: 10003
onSaveInstanceState: 3 packets
Saving fragment 0) null
Saving fragment 1) tag_10001
Saving fragment 2) null
OnStop called