我正在计划一个信使应用程序,它包含几个方面:
在智能手机上,一次只能有一个激活,但平板电脑应该有一个带有快捷方式的侧边栏(在会话视图中显示联系人列表,在显示设置类别列表的设置中)。
据我所知,这些区域将是片段,可插入一个或多个活动中。
所以我开始创建一个具有以下布局的活动(res / main.xml):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<fragment
android:id="@id/main_fragment_focus"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
和相应的平板电脑布局:(layout-large-land / main.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<fragment
android:id="@id/main_fragment_sidebar"
android:layout_width="@dimen/main_sidebar_width"
android:layout_height="match_parent" />
<fragment
android:id="@id/main_fragment_content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
到目前为止,这么好。至少就我的想法而言。 所以我创建了一个简单的活动;我正在使用ActionBarSherlock,因为我想提供与API Level 5 +的兼容性:
package com.pm.messenger;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.util.Log;
import com.actionbarsherlock.app.SherlockFragmentActivity;
public class PMMessengerActivity extends SherlockFragmentActivity {
// -------------------------------------------------------------------------
FragmentManager fragmentManager = null;
// -------------------------------------------------------------------------
public void onCreate(Bundle savedInstanceState) {
// ---------------------------------------------------------------------
super.onCreate(savedInstanceState);
// ---------------------------------------------------------------------
fragmentManager = getSupportFragmentManager();
// ---------------------------------------------------------------------
if (savedInstanceState == null) {
// -----------------------------------------------------------------
// -----------------------------------------------------------------
}
else {
// -----------------------------------------------------------------
// -----------------------------------------------------------------
}
// ---------------------------------------------------------------------
Log.d(getClass().getSimpleName(), "no problem before setContentView");
setContentView(R.layout.main);
Log.d(getClass().getSimpleName(), "no problem after setContentView");
// ---------------------------------------------------------------------
}
// -------------------------------------------------------------------------
}
执行此操作后,我的应用程序立即崩溃。首先我想,这是因为我没有提供任何FragmentManager-FragmentTransactions,但后来我注意到(在插入Log.d-Lines之后)在调用SetContentView时发生了崩溃。
的logcat-输出:
01-24 16:58:26.728: I/ActivityManager(667): START {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.pm.messenger/.pmMessengerActivity bnds=[912,542][1008,638]} from pid 877
01-24 16:58:26.748: D/dalvikvm(26431): Late-enabling CheckJNI
01-24 16:58:26.758: I/ActivityManager(667): Start proc com.pm.messenger for activity com.pm.messenger/.pmMessengerActivity: pid=26431 uid=10009 gids={3003, 1015}
01-24 16:58:26.778: E/jdwp(26431): Failed sending reply to debugger: Broken pipe
01-24 16:58:26.778: D/dalvikvm(26431): Debugger has detached; object registry had 1 entries
01-24 16:58:26.788: D/OpenGLRenderer(877): Flushing caches (mode 1)
01-24 16:58:26.828: D/pmMessengerActivity(26431): no problem before setContentView
01-24 16:58:26.858: D/AndroidRuntime(26431): Shutting down VM
01-24 16:58:26.858: W/dalvikvm(26431): threadid=1: thread exiting with uncaught exception (group=0x40a3e1f8)
01-24 16:58:26.868: D/OpenGLRenderer(877): Flushing caches (mode 0)
01-24 16:58:26.868: E/AndroidRuntime(26431): FATAL EXCEPTION: main
01-24 16:58:26.868: E/AndroidRuntime(26431): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.pm.messenger/com.pm.messenger.pmMessengerActivity}: android.view.InflateException: Binary XML file line #7: Error inflating class fragment
01-24 16:58:26.868: E/AndroidRuntime(26431): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
01-24 16:58:26.868: E/AndroidRuntime(26431): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
01-24 16:58:26.868: E/AndroidRuntime(26431): at android.app.ActivityThread.access$600(ActivityThread.java:123)
01-24 16:58:26.868: E/AndroidRuntime(26431): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
01-24 16:58:26.868: E/AndroidRuntime(26431): at android.os.Handler.dispatchMessage(Handler.java:99)
01-24 16:58:26.868: E/AndroidRuntime(26431): at android.os.Looper.loop(Looper.java:137)
01-24 16:58:26.868: E/AndroidRuntime(26431): at android.app.ActivityThread.main(ActivityThread.java:4424)
01-24 16:58:26.868: E/AndroidRuntime(26431): at java.lang.reflect.Method.invokeNative(Native Method)
01-24 16:58:26.868: E/AndroidRuntime(26431): at java.lang.reflect.Method.invoke(Method.java:511)
01-24 16:58:26.868: E/AndroidRuntime(26431): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
01-24 16:58:26.868: E/AndroidRuntime(26431): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
01-24 16:58:26.868: E/AndroidRuntime(26431): at dalvik.system.NativeStart.main(Native Method)
01-24 16:58:26.868: E/AndroidRuntime(26431): Caused by: android.view.InflateException: Binary XML file line #7: Error inflating class fragment
01-24 16:58:26.868: E/AndroidRuntime(26431): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:697)
01-24 16:58:26.868: E/AndroidRuntime(26431): at android.view.LayoutInflater.rInflate(LayoutInflater.java:739)
01-24 16:58:26.868: E/AndroidRuntime(26431): at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
01-24 16:58:26.868: E/AndroidRuntime(26431): at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
01-24 16:58:26.868: E/AndroidRuntime(26431): at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
01-24 16:58:26.868: E/AndroidRuntime(26431): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:251)
01-24 16:58:26.868: E/AndroidRuntime(26431): at com.actionbarsherlock.internal.ActionBarSherlockNative.setContentView(ActionBarSherlockNative.java:119)
01-24 16:58:26.868: E/AndroidRuntime(26431): at com.actionbarsherlock.app.SherlockFragmentActivity.setContentView(SherlockFragmentActivity.java:262)
01-24 16:58:26.868: E/AndroidRuntime(26431): at com.pm.messenger.pmMessengerActivity.onCreate(pmMessengerActivity.java:48)
01-24 16:58:26.868: E/AndroidRuntime(26431): at android.app.Activity.performCreate(Activity.java:4465)
01-24 16:58:26.868: E/AndroidRuntime(26431): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
01-24 16:58:26.868: E/AndroidRuntime(26431): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
01-24 16:58:26.868: E/AndroidRuntime(26431): ... 11 more
01-24 16:58:26.868: E/AndroidRuntime(26431): Caused by: java.lang.NullPointerException: name == null
01-24 16:58:26.868: E/AndroidRuntime(26431): at java.lang.VMClassLoader.findLoadedClass(Native Method)
01-24 16:58:26.868: E/AndroidRuntime(26431): at java.lang.ClassLoader.findLoadedClass(ClassLoader.java:354)
01-24 16:58:26.868: E/AndroidRuntime(26431): at java.lang.ClassLoader.loadClass(ClassLoader.java:491)
01-24 16:58:26.868: E/AndroidRuntime(26431): at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
01-24 16:58:26.868: E/AndroidRuntime(26431): at android.support.v4.app.Fragment.instantiate(Fragment.java:381)
01-24 16:58:26.868: E/AndroidRuntime(26431): at android.support.v4.app.Fragment.instantiate(Fragment.java:359)
01-24 16:58:26.868: E/AndroidRuntime(26431): at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:262)
01-24 16:58:26.868: E/AndroidRuntime(26431): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:669)
01-24 16:58:26.868: E/AndroidRuntime(26431): ... 22 more
01-24 16:58:26.868: W/ActivityManager(667): Force finishing activity com.pm.messenger/.pmMessengerActivity
01-24 16:58:27.408: W/ActivityManager(667): Activity pause timeout for ActivityRecord{410d8c98 com.pm.messenger/.pmMessengerActivity}
现在我想,这次崩溃是因为我没有在XML中静态提供任何片段类, BUT 我不想使用它,我想以动态的方式实现这一点
当我必须在XML中静态提供类时,我想我还需要多个Activiti(如LoginActivity,SignupActivity,ContactListActivity,ConversationActivity)但是......停止,这可能不对,因为那时我的片段松散了有权存在imho。
就我的理解而言,片段是我的应用程序中唯一的一部分,它实现了一系列功能,例如当天的活动;这些将嵌入到管理后台堆栈的容器活动中。
那么我逻辑中的错误在哪里? 我应该使用带有FrameView的布局而不是片段吗?不知道。
此外,我没有找到任何用于动态片段管理的任何好的,可理解的,记录良好的资源。
答案 0 :(得分:1)
您的具体错误是由于您正试图给不存在的片段充气,显然。对于动态片段,您应该在静态布局中放置FrameLayout,并在运行时将片段放入这些帧中。这是布局的一个例子:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<View
android:id="@+id/anchor"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_centerInParent="true" />
<FrameLayout
android:id="@+id/top_left"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_above="@+id/anchor"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_toLeftOf="@+id/anchor">
</FrameLayout>
<FrameLayout
android:id="@+id/top_right"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_above="@+id/anchor"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_toRightOf="@+id/anchor">
</FrameLayout>
<FrameLayout
android:id="@+id/bottom_left"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_below="@+id/anchor"
android:layout_toLeftOf="@+id/anchor">
</FrameLayout>
<FrameLayout
android:id="@+id/bottom_right"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_below="@+id/anchor"
android:layout_toRightOf="@+id/anchor">
</FrameLayout>
</RelativeLayout>
这恰好在网格中放置了四个相同大小的FrameLayouts。您可以在运行时添加片段:
Fragment levelsF = Fragment.instantiate(this,
LevelsFragment.class.getName());
Fragment waveF = Fragment.instantiate(this,
WaveFragment.class.getName());
Fragment lightF = Fragment.instantiate(this,
LightPlayerFragment.class.getName());
Fragment keyboardF = Fragment.instantiate(this,
KBFragment.class.getName());
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.top_left, levelsF);
ft.add(R.id.top_right, waveF);
ft.add(R.id.bottom_left, lightF);
ft.add(R.id.bottom_right, keyboardF);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.commit();
getSupportFragmentManager().executePendingTransactions();
如果您不想要静态片段,请不要在xml中引用它们。
答案 1 :(得分:0)
Android为其API提供了精彩的文档。它清楚地解释了Fragment类的生命周期和方法。希望这可以帮助。 Fragments Documentation