安卓设置碎片

5

我正在尝试将设置片段添加到我的Android应用程序中。因此,我添加了一个XML文件和这个活动:

public class SettingsActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Display the fragment as the main content.
    getFragmentManager().beginTransaction()
            .replace(android.R.id.content, new SettingsFragment())
            .commit();
}

public static class SettingsFragment extends PreferenceFragment {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Load the preferences from an XML resource
        addPreferencesFromResource(R.xml.preferences);
    }
}
}

它被从主活动的onOptionsItemSelected函数调用:
if (id == R.id.action_settings) {
        Intent intent = new Intent(this, SettingsActivity.class);
        startActivity(intent);
        return true;
    }

所以,现在当我尝试从菜单打开这个活动时,它会强制关闭并在控制台中出现以下错误:
Force-removing child win Window{4190a9a8 u0 PopupWindow:418fc208} from container         Window{418dd448 u0 org.name.app/org.name.app.MainActivity}
Failed looking up window
java.lang.IllegalArgumentException: Requested window android.os.BinderProxy@423b1fc0 does not exist
        at com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:7934)
        at com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:7925)
        at com.android.server.wm.WindowState$DeathRecipient.binderDied(WindowState.java:1047)
        at android.os.BinderProxy.sendDeathNotice(Binder.java:493)
        at dalvik.system.NativeStart.run(Native Method)
2个回答

4
你正在替换一个以前从未添加的片段...
getFragmentManager().beginTransaction()
            .replace(android.R.id.content, new SettingsFragment())
            .commit();

尝试

            .add(android.R.id.content, new SettingsFragment())

但正确的代码应该是(伪代码)

  1. 按ID或标签查找片段
  2. 如果未找到片段,则创建一个。

您可以在网络和stackoverflow上找到大量示例。 ;)

更新好的,这里有一些样本代码供您使用。

假设:您对多个片段使用相同的活动,因此需要恢复现有的片段或创建新的片段。

FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
Fragment newFragment = fm.findFragmentByTag("Some_Tag");
if (newFragment == null) {
     newFragment = SomeFragment.newInstance(); //create a new frag
}
// Find the old one to know if we have to replace or simply add to this container
Fragment oldFragment = fm.findFragmentById(R.id.content_container);
if (oldFragment != null) {
    ft.replace(R.id.content_container, newFragment, "Some_Tag");
} else {
    ft.add(R.id.content_container, newFragment, "Some_Tag");
}
// optionally use a nice transition
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
// …and to the backstack if you wish…
ft.addToBackStack(null).commit();

如果您只需要简单的版本而不需要任何花哨的东西...
FragmentManager fm = getSupportFragmentManager();//if using support lib
Fragment fragment = fm.findFragmentById(R.id.your_container);
if (fragment == null) {
   fragment = YourFragment.newInstance();
   fm.beginTransaction()
   .add(R.id.your_container, fragment, "some_tag_if_you_wish_to_use_find_by_tag_later")
   .commit();
}

只有当容器中没有该片段时,才会添加该片段。否则无需执行任何操作,因为容器已经包含了你的片段。 :)

我用添加函数替换了替换函数,但仍然无法正常工作。我需要找到旧的片段并将其替换为新的吗?或者我做错了什么? - ovmcit5eoivc4

1
错误信息表明活动层次结构存在问题。尝试将MainActivity设置为SettingsActivity的父级。我使用的是与您相同的代码,除了我提到的父级关系;这对我有用。
您可以像这样设置父级关系:
<activity
            android:name="some.package.SettingsActivity"
            android:label="@string/activity_name_settings"
            android:parentActivityName="some.package.MainActivity" >
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="some.package.MainActivity" />
</activity>

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