如何使用Fragment处理屏幕方向变化?

7

我现在有两个片段,一个处理纵向模式,另一个处理横向模式。但问题是,当从纵向旋转到横向然后再返回纵向时,它不会显示与第一个纵向模式相同的内容。是否有任何代码可以解决这个问题?

此代码位于片段持有者中:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.frag_holder);

    FragmentManager fm = getSupportFragmentManager();

    final Fragment fragment = Frag.newInstance(); //Portrait layout
    final Fragment fragment2 = Frag2.newInstance(); //Landscape layout

    int orientation = getResources().getConfiguration().orientation; //check whether is it portrait or landscape


    if(orientation == Configuration.ORIENTATION_PORTRAIT){
        Fragment fragTAG = fm.findFragmentByTag(TAG_P);
        if(fragTAG == null){
            Log.i("test","test");
                fm.beginTransaction()
                        .replace(R.id.fragPlaceHolder, fragment, TAG_P)
                        .commit(); //Portrait
        }
        else{
            fm.beginTransaction().replace(R.id.fragPlaceHolder,fragTAG).commit();
        }

    }
    if(orientation == Configuration.ORIENTATION_LANDSCAPE){
        Fragment fragTAG = fm.findFragmentByTag(TAG_L);
        if(fragTAG == null){
                fm.beginTransaction()
                        .replace(R.id.fragPlaceHolder, fragment2, TAG_L)
                        .commit(); //Landscape
        }
        else{
            fm.beginTransaction().replace(R.id.fragPlaceHolder,fragTAG).commit();
        }
    }

}

}


你需要首先发布导致问题的代码。 - jaibatrik
你问题的唯一真正解决方案是:你不应该为不同的屏幕方向创建不同的片段。这不是 Android 的工作方式。 - Xaver Kapeller
@Xaver Kapeller,那么有没有其他方法可以做到这一点,并且得到相同的结果。我只是希望在旋转时两个方向上显示相同的内容。 - Zheng Xian
@Zheng 是的,有的。正如我之前所说:不要为不同的方向使用不同的片段。这是导致你问题的原因。只需使用一个片段来处理两个方向,并利用Android的资源限定符系统在方向改变时更改资源,如布局等。 - Xaver Kapeller
4个回答

6
第一步:在你的活动中添加配置更改
    <activity android:name=".ui.createtasks.CreateTaskActivity"
        android:configChanges="orientation|screenSize|keyboardHidden" > </activity>

第二步: 将您编辑的文本值添加到onSaveInstanceState中。
 @Override
public void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
     outState.putCharSequence(KEY_TITLE, et_text.getText().toString());
 }

第三步: 通过 onViewStateRestored 获取您保存的编辑文本值。
    @Override
public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
    super.onViewStateRestored(savedInstanceState);

    String savedTitle = null;
    if (savedInstanceState != null) {
        savedTitle = savedInstanceState.getString(KEY_TITLE);
        et_text.setText(savedTitle);

    }

}

抱歉,这是清单而不是活动(第1步:在您的清单中添加配置更改)。 第1步:在您的清单中添加配置更改。 - Sanaullah
当您针对每个方向具有不同的布局时,这并不实用。在清单中设置android:configChanges将防止活动重新创建,并且相应的布局不会加载。 - hiddeneyes02

1
你可以在两个Fragment的onCreate()方法中调用setRetainInstance(True),或者创建一个无UI的headless-Fragment来缓存数据。第三个选择是使用onSaveInstanceState(Bundle outState)来缓存数据,并在onCreateView()方法中通过使用Bundle savedInstanceState重新显示数据。

我尝试了第一个,但当手机旋转回纵向布局时,它会破坏第一次的纵向布局。你所说的无界面片段是什么意思? - Zheng Xian
这里的建议都是不正确的。setRetainInstance() 不是为了保留数据,而是在实际需要时保留 Fragment 实例。除此之外,这对于该操作员来说行不通,因为他针对每个方向都有不同的 Fragment,并且可能只有一个 Fragment 附加到每个方向上。如果未附加,则 Activity 无法保留 Fragment 的实例。没有 UI 的 Fragment 违背了首先拥有 Fragment 的目的,绝对不要这样做。当然,在这种情况下它也不能解决任何问题。 - Xaver Kapeller
唯一真正的答案是你的第三个选项。如果做得正确,这将在很大程度上自动发生。唯一真正的解决方案不是为不同的方向而有两个不同的“Fragment”。这才是问题的根源。 - Xaver Kapeller

1
当活动旋转时,活动将关闭并重新打开,onDestroy和onCreate方法会被调用。 如果您想在其他旋转中保存数据并重新加载它,则可以使用onSaveInstanceState方法:
protected void onSaveInstanceState(Bundle outState)

for example:

@Override
public void onSaveInstanceState(Bundle outState)
{
    super.onSaveInstanceState(outState);
    outState.putString("name", "David");
    outState.putInt("age", 17);
}

在onCreate方法中重新加载数据。保留HTML格式。
@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    …
    if(savedInstanceState != null)
    {
         savedInstanceState.getString("name");
         savedInstanceState.getInt("age");
    }
}

0
在清单文件中添加代码。
<activity
        android:name=".file_name"//add your activity name
        android:label="label" //add label
        android:configChanges="orientation|screenSize|keyboardHidden"
        android:theme="@style/AppTheme.NoActionBar" />

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接