在方向更改时保持 Fragment 的状态但替换其布局
Keep state of Fragment on Orientation change but replace its layout
我有一个 Activity(它是应用程序的启动器),它有一个 ViewPager 作为选项卡之间的导航菜单。
在这个 ViewPager 中,我有不同类型的片段。
目前,我没有自己处理方向变化,所以 Activity 在我旋转设备时会重新创建。 (这表现得很好,但由于加载时间长和用户体验差,我不想再次加载整个 activity)。
对于特定的 Fragment,我有 2 种布局(一种用于纵向,一种用于横向)。
我需要的是保持 activity 和片段的状态,但要在方向更改时替换片段布局。我的问题是它在横向布局中比在纵向布局中有更多的视图,所以我不知道如何处理它。
我试过 configChanges,但显然它不会改变我的布局。
我尝试膨胀纵向和横向布局并将它们替换在 onConfigurationChanged 上的 FrameLayout 容器内,但它似乎也不起作用。
如何处理需要加载不同布局同时保持片段状态不变的情况?这可能吗?
这种事情的正确做法是什么?
我有这样的情况,通过setLayout方法在改变屏幕方向时加载不同的布局;
public class SampleFragment extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mRoot = inflater.inflate(R.layout.fragment_layout, null);
return mRoot;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
this.init();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
this.setLayout();
}
private void init() {
this.setLayout();
}
private void setLayout() {
View view = null;
int orientation = mResources.getConfiguration().orientation;
if (orientation == Configuration.ORIENTATION_LANDSCAPE)
view = mInflater.inflate(R.layout.segment_dettaglio_evento_land, null);
else if (orientation == Configuration.ORIENTATION_PORTRAIT)
view = mInflater.inflate(R.layout.segment_dettaglio_evento, null);
if (orientation == Configuration.ORIENTATION_LANDSCAPE || orientation == Configuration.ORIENTATION_PORTRAIT) {
ViewGroup viewGroup = (ViewGroup) mRoot.findViewById(R.id.dettaglio_evento_root);
viewGroup.removeAllViews();
viewGroup.addView(view, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
this.initComponent();
}
}
private void initComponent() {
if (mResult == null)
retrieveData();
else
populateWithDetail();
}
}
fragment_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/dettaglio_evento_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/dettaglio_evento_background"
android:orientation="vertical" >
</LinearLayout>
我还有一个变量 mResult,其中包含从网络请求中保留的数据,因此如果它为空,我将发出请求,否则填充视图。
我有一个 Activity(它是应用程序的启动器),它有一个 ViewPager 作为选项卡之间的导航菜单。 在这个 ViewPager 中,我有不同类型的片段。
目前,我没有自己处理方向变化,所以 Activity 在我旋转设备时会重新创建。 (这表现得很好,但由于加载时间长和用户体验差,我不想再次加载整个 activity)。
对于特定的 Fragment,我有 2 种布局(一种用于纵向,一种用于横向)。
我需要的是保持 activity 和片段的状态,但要在方向更改时替换片段布局。我的问题是它在横向布局中比在纵向布局中有更多的视图,所以我不知道如何处理它。
我试过 configChanges,但显然它不会改变我的布局。 我尝试膨胀纵向和横向布局并将它们替换在 onConfigurationChanged 上的 FrameLayout 容器内,但它似乎也不起作用。
如何处理需要加载不同布局同时保持片段状态不变的情况?这可能吗? 这种事情的正确做法是什么?
我有这样的情况,通过setLayout方法在改变屏幕方向时加载不同的布局;
public class SampleFragment extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mRoot = inflater.inflate(R.layout.fragment_layout, null);
return mRoot;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
this.init();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
this.setLayout();
}
private void init() {
this.setLayout();
}
private void setLayout() {
View view = null;
int orientation = mResources.getConfiguration().orientation;
if (orientation == Configuration.ORIENTATION_LANDSCAPE)
view = mInflater.inflate(R.layout.segment_dettaglio_evento_land, null);
else if (orientation == Configuration.ORIENTATION_PORTRAIT)
view = mInflater.inflate(R.layout.segment_dettaglio_evento, null);
if (orientation == Configuration.ORIENTATION_LANDSCAPE || orientation == Configuration.ORIENTATION_PORTRAIT) {
ViewGroup viewGroup = (ViewGroup) mRoot.findViewById(R.id.dettaglio_evento_root);
viewGroup.removeAllViews();
viewGroup.addView(view, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
this.initComponent();
}
}
private void initComponent() {
if (mResult == null)
retrieveData();
else
populateWithDetail();
}
}
fragment_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/dettaglio_evento_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/dettaglio_evento_background"
android:orientation="vertical" >
</LinearLayout>
我还有一个变量 mResult,其中包含从网络请求中保留的数据,因此如果它为空,我将发出请求,否则填充视图。