使用兼容性包以Fragments为目标2.2。

重新编码活动以在应用程序中使用片段后,我无法进行方向更改/状态管理,因此我创建了一个具有单个FragmentActivity和单个Fragment的小型测试应用程序。

来自方向更改的日志很奇怪,有多个对片段OnCreateView的调用。

我显然丢失了一些东西-例如分离片段并重新附加它而不是创建新实例,但是我看不到任何文档来表明我要去哪里。

任何人都可以告诉我我在做什么错。 谢谢

方向更改后,日志如下。

Initial creation
12-04 11:57:15.808: D/FragmentTest.FragmentTestActivity(3143): onCreate
12-04 11:57:15.945: D/FragmentTest.FragmentOne(3143): OnCreateView
12-04 11:57:16.081: D/FragmentTest.FragmentOne(3143): OnCreateView->SavedInstanceState null


Orientation Change 1
12-04 11:57:39.031: D/FragmentTest.FragmentOne(3143): onSaveInstanceState
12-04 11:57:39.031: D/FragmentTest.FragmentTestActivity(3143): onCreate
12-04 11:57:39.031: D/FragmentTest.FragmentOne(3143): OnCreateView
12-04 11:57:39.031: D/FragmentTest.FragmentOne(3143): OnCreateView->SavedInstanceState not null
12-04 11:57:39.031: D/FragmentTest.FragmentOne(3143): OnCreateView
12-04 11:57:39.167: D/FragmentTest.FragmentOne(3143): OnCreateView->SavedInstanceState null


Orientation Change 2
12-04 11:58:32.162: D/FragmentTest.FragmentOne(3143): onSaveInstanceState
12-04 11:58:32.162: D/FragmentTest.FragmentOne(3143): onSaveInstanceState
12-04 11:58:32.361: D/FragmentTest.FragmentTestActivity(3143): onCreate
12-04 11:58:32.361: D/FragmentTest.FragmentOne(3143): OnCreateView
12-04 11:58:32.361: D/FragmentTest.FragmentOne(3143): OnCreateView->SavedInstanceState not null
12-04 11:58:32.361: D/FragmentTest.FragmentOne(3143): OnCreateView
12-04 11:58:32.361: D/FragmentTest.FragmentOne(3143): OnCreateView->SavedInstanceState not null
12-04 11:58:32.498: D/FragmentTest.FragmentOne(3143): OnCreateView
12-04 11:58:32.498: D/FragmentTest.FragmentOne(3143): OnCreateView->SavedInstanceState null

主要活动(FragmentActivity)

public class FragmentTestActivity extends FragmentActivity {
/** Called when the activity is first created. */

private static final String TAG = "FragmentTest.FragmentTestActivity";


FragmentManager mFragmentManager;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Log.d(TAG, "onCreate");

    mFragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();

    FragmentOne fragment = new FragmentOne();

    fragmentTransaction.add(R.id.fragment_container, fragment);
    fragmentTransaction.commit();
}

和碎片

public class FragmentOne extends Fragment {

private static final String TAG = "FragmentTest.FragmentOne";

EditText mEditText;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    Log.d(TAG, "OnCreateView");

    View v = inflater.inflate(R.layout.fragmentonelayout, container, false);

    // Retrieve the text editor, and restore the last saved state if needed.
    mEditText = (EditText)v.findViewById(R.id.editText1);

    if (savedInstanceState != null) {

        Log.d(TAG, "OnCreateView->SavedInstanceState not null");

        mEditText.setText(savedInstanceState.getCharSequence("text"));
    }
    else {
        Log.d(TAG,"OnCreateView->SavedInstanceState null");
    }
    return v;
}

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

    Log.d(TAG, "FragmentOne.onSaveInstanceState");

    // Remember the current text, to restore if we later restart.
    outState.putCharSequence("text", mEditText.getText());
}

表现

<uses-sdk android:minSdkVersion="8" />

<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >
    <activity
        android:label="@string/app_name"
        android:name=".activities.FragmentTestActivity" 
        android:configChanges="orientation">
        <intent-filter >
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

===============>>#1 票数:182 已采纳

您正在将片段一个接一个地分层。

发生配置更改时,旧的Fragment在重新创建时会将其自身添加到新的Activity中。 大多数时候,这是后方的巨大痛苦。

您可以通过使用相同的片段而不是重新创建一个片段来阻止发生错误。 只需添加以下代码:

if (savedInstanceState == null) {
    // only create fragment if activity is started for the first time
    mFragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();

    FragmentOne fragment = new FragmentOne();

    fragmentTransaction.add(R.id.fragment_container, fragment);
    fragmentTransaction.commit();
} else {        
    // do nothing - fragment is recreated automatically
}

不过请注意:如果尝试从Fragment内访问“活动视图”,则会发生问题,因为生命周期会发生细微变化。 (从片段获取父活动的视图并不容易)。

===============>>#2 票数:83

引用这本书 ,“为确保一致的用户体验,当由于配置更改而重新启动Activity时,Android会保留Fragment布局和相关的后向堆栈。” (第124页)

解决该问题的方法是,首先检查Fragment back堆栈是否已被填充,然后仅在尚未填充时才创建新的片段实例:

@Override
public void onCreate(Bundle savedInstanceState) {

        ...    

    FragmentOne fragment = (FragmentOne) mFragmentManager.findFragmentById(R.id.fragment_container); 

    if (fragment == null) {
        FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
        fragmentTransaction.add(R.id.fragment_container, new FragmentOne());
        fragmentTransaction.commit();
    }
}

===============>>#3 票数:10

如您所见,在方向更改后将调用活动的onCreate()方法。 因此,请勿在活动方向更改后执行添加片段的FragmentTransaction。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (savedInstanceState==null) {
        //do your stuff
    }
}

片段应该并且必须保持不变。

===============>>#4 票数:4

您可以使用onSaveInstanceState() @Override FragmentActivity。 请确保不要在方法中调用super.onSaveInstanceState()

===============>>#5 票数:0

我们应该始终尝试防止nullpointer异常,因此我们必须首先在saveinstance方法中检查捆绑包信息。 有关简短说明,请查看此博客链接

public static class DetailsActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (getResources().getConfiguration().orientation
            == Configuration.ORIENTATION_LANDSCAPE) {
            // If the screen is now in landscape mode, we can show the
            // dialog in-line with the list so we don't need this activity.
            finish();
            return;
        }

        if (savedInstanceState == null) {
            // During initial setup, plug in the details fragment.
            DetailsFragment details = new DetailsFragment();
            details.setArguments(getIntent().getExtras());
            getFragmentManager().beginTransaction().add(android.R.id.content, details).commit();
        }
    } 
}

===============>>#6 票数:0

更改配置后,框架将为您创建该片段的新实例并将其添加到活动中。 所以代替这个:

FragmentOne fragment = new FragmentOne();

fragmentTransaction.add(R.id.fragment_container, fragment);

做这个:

if (mFragmentManager.findFragmentByTag(FRAG1_TAG) == null) {
    FragmentOne fragment = new FragmentOne();

    fragmentTransaction.add(R.id.fragment_container, fragment, FRAG1_TAG);
}

请注意,除非您调用setRetainInstance(true),否则该框架会在方向更改时添加一个FragmentOne的新实例,在这种情况下,它将添加FragmentOne的旧实例。

===============>>#7 票数:-1

如果您只是做一个项目,那么项目经理说您需要实现屏幕切换功能,但是您不想屏幕切换加载不同的布局(可以创建布局和布局端口系统。

您将自动确定屏幕状态,加载相应的布局),由于需要重新初始化活动或片段,用户体验不好,不能直接在屏幕上切换,我指的是? Url = YgNfP-vHy-Nuldi7YHTfNet3AtLdN-w__O3z1wLOnzr3wDjYo7X7PYdNyhw8R24ZE22xiKnydni7R0r35s2fOLcHOiLGYT9Qh_fjqtytJki&wd = eqa0001 = 25924

前提是您的布局使用权重的方式来布局layout_weight,如下所示:

<LinearLayout
Android:id= "@+id/toplayout"
Android:layout_width= "match_parent"
Android:layout_height= "match_parent"
Android:layout_weight= "2"
Android:orientation= "horizontal" >

所以我的方法是,在屏幕切换时,不需要加载视图文件的新布局,而是在onConfigurationChanged动态权重中修改布局,请执行以下步骤:1首先设置:activity属性中的AndroidManifest.xml:android:configChanges =“ keyboardHidden | orientation | screenSize”为了防止屏幕切换,请避免重新加载,以便能够在onConfigurationChanged 2中监视onConfigurationChanged方法中的重写活动或片段。

@Override
Public void onConfigurationChanged (Configuration newConfig) {
    Super.onConfigurationChanged (newConfig);
    SetContentView (R.layout.activity_main);
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        //On the layout / / weight adjustment
        LinearLayout toplayout = (LinearLayout) findViewById (R.id.toplayout);
        LinearLayout.LayoutParams LP = new LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0, 2.0f);
        Toplayout.setLayoutParams (LP);
        LinearLayout tradespace_layout = (LinearLayout) findViewById(R.id.tradespace_layout);
        LinearLayout.LayoutParams LP3 = new LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0, 2.8f);
        Tradespace_layout.setLayoutParams (LP3);
    }
    else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT)
    {
        //On the layout / / weight adjustment
        LinearLayout toplayout = (LinearLayout) findViewById (R.id.toplayout);
        LinearLayout.LayoutParams LP = new LayoutParams (LinearLayout.LayoutParams.MATCH_PARENT, 0, 2.8f);
        Toplayout.setLayoutParams (LP);
        LinearLayout tradespace_layout = (LinearLayout) findViewById (R.id.tradespace_layout);
        LinearLayout.LayoutParams LP3 = new LayoutParams (LinearLayout.LayoutParams.MATCH_PARENT, 0, 2.0f);
        Tradespace_layout.setLayoutParams (LP3);
    }
}

  ask by MartinS translate from so

未解决问题?本站智能推荐:

3回复

方向更改后,片段中的getActivity()为null

我有一个startActivityForResult,片段和方向更改的问题。 我从一个片段调用startActivityForResult(),然后打开附加了片段的第二个活动。 在第二个活动中,当我改变方向并返回第一个活动时,则调用onActivityResult(fragment方法)
1回复

方向更改后,Volley响应处理程序取消对话框片段

当我的“ Activity发出Volley请求时,我将显示一个带有对话框片段的对话框。 在响应处理程序(这是Activity的非静态内部类)中,我使用以下命令关闭对话框片段: 除非我旋转设备,否则一切正常。 如果方向更改完成后返回响应,则MyActivity.this已被破坏。
2回复

活动和片段生命周期和方向变化

我一直有非常奇怪的问题Fragments和方向更改已导致强制关闭而不遵循逻辑模式。 我创建了一个简单的Activity和Fragment生命周期调试应用程序,它通过报告对logcat的调用来简单地实现Activity生命周期和Fragment生命周期的每一步。 以下是TestActi
2回复

片段方向变化-比横向测试更好

在“风景”模式下,我有两个由一个活动控制并利用两个片段的FrameLayout。 在“肖像”模式下,我有一个由“一个活动”控制的FrameLayout,在选择“线条”时,我调用了另一个活动以使用细节片段显示细节 在“肖像”详细信息活动中,我对onCreate()方法中的方向进行了以下检查
2回复

android:应用程序崩溃,如果方向在子活动中发生变化

我的主要活动处理纵向模式的变化就好了。 但是,如果我通过startActivityForResult()启动一个非常简单的活动并在完成它之前切换到纵向模式,我的主要活动会崩溃,因为它的一些变量设置为null。 看起来我的服务连接没有重新创建。 我试着手动调用doUnbindServic
1回复

Android:始终以纵向启动“活动”,但可以识别方向变化

我想始终以纵向方向开始新的活动/意图(即使设备横向放置) 如果我使用setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 活动被锁定为人像,但我想识别方向的变化。 所以我想我必须打电话给setReque
1回复

Android-片段生命周期

这个问题已经在这里有了答案: 片段和父母活动的生命周期在一起 2个答案 据我了解, Android片段是Android Activity的一部分。 碎片生命周期是否也与活动相同。 我对此事非常困惑。 请有人帮我。 谢谢!!!
1回复

在后台活动方向发生变化

第一个活动(锁定的肖像方向)有2个按钮,可同时打开第二个活动,但A按钮以纵向打开它,而B按钮以横向打开它。 问题在于,当B按钮打开第二个活动( 处于对话框配置并且第一个活动显示在背景中 )时,第一个活动会随着第二个活动改变方向,从而重新启动。 问题是,A)我可以阻止第一次活动改变方向
2回复

检测片段之间的变化方向

我有 Fragment A已经addToBackStack() 。 Fragment B不是addToBackStack() 。 当我在Fragment A 。 我可以使用onSaveInstanceState和onViewStateRestored方法检测更改方向。
5回复

分割活动中的生命周期

在许多网站中,我看到片段必须始终嵌入到活动中,并且片段的生命周期直接受到宿主活动的生命周期的影响-暂停活动时,其中的所有片段以及活动被销毁时也是如此。所有片段。 但是,在那里也写到了我们可以在不同的活动中重用片段-但是从上方看,如果我们转到另一个活动,则片段将被销毁。 我还缺少什么,或者