我正在创建app,其中我必须动态添加3个片段,每个片段应占用相同的空间。为此,我使用的是LayoutParams,但它不起作用,它给出了Java.lang.NullPointerException。 请帮我解决错误。
片段类
public class HeaderFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.timetable_activity, container, false);
}
}
主要活动
public class TimeTableActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.timetable_activity);
super.onCreate(savedInstanceState);
if (findViewById(R.id.fragment_layout) != null) {
if (savedInstanceState != null) {
return;
}
// Create an instance of ExampleFragment
HeaderFragment firstFragment = new HeaderFragment();
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 1);
firstFragment.getView().setLayoutParams(params);
BodyFragment secondFragment = new BodyFragment();
secondFragment.getView().setLayoutParams(params);
FooterFragment thirdFragment = new FooterFragment();
thirdFragment.getView().setLayoutParams(params);
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_layout, firstFragment).commit();
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_layout, secondFragment).commit();
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_layout, thirdFragment).commit();
}
}
}
Main Activty.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id = "@+id/fragment_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context=".MainActivity" >
</LinearLayout>
Logcat说明
01-02 02:17:58.572: E/AndroidRuntime(1688): FATAL EXCEPTION: main
01-02 02:17:58.572: E/AndroidRuntime(1688): Process: com.deiontech.masjidtimetableapp, PID: 1688
01-02 02:17:58.572: E/AndroidRuntime(1688): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.deiontech.masjidtimetableapp/com.deiontech.masjidtimetableapp.TimeTableActivity}: java.lang.NullPointerException
01-02 02:17:58.572: E/AndroidRuntime(1688):at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
01-02 02:17:58.572: E/AndroidRuntime(1688): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
01-02 02:17:58.572: E/AndroidRuntime(1688): at android.app.ActivityThread.access$800(ActivityThread.java:135)
01-02 02:17:58.572: E/AndroidRuntime(1688): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
01-02 02:17:58.572: E/AndroidRuntime(1688): at android.os.Handler.dispatchMessage(Handler.java:102)
01-02 02:17:58.572: E/AndroidRuntime(1688): at android.os.Looper.loop(Looper.java:136)
01-02 02:17:58.572: E/AndroidRuntime(1688): at android.app.ActivityThread.main(ActivityThread.java:5017)
01-02 02:17:58.572: E/AndroidRuntime(1688): at java.lang.reflect.Method.invokeNative(Native Method)
01-02 02:17:58.572: E/AndroidRuntime(1688): at java.lang.reflect.Method.invoke(Method.java:515)
01-02 02:17:58.572: E/AndroidRuntime(1688): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
01-02 02:17:58.572: E/AndroidRuntime(1688): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
01-02 02:17:58.572: E/AndroidRuntime(1688): at dalvik.system.NativeStart.main(Native Method)
01-02 02:17:58.572: E/AndroidRuntime(1688): Caused by: java.lang.NullPointerException
01-02 02:17:58.572: E/AndroidRuntime(1688): at com.deiontech.masjidtimetableapp.TimeTableActivity.onCreate(TimeTableActivity.java:27)
01-02 02:17:58.572: E/AndroidRuntime(1688): at android.app.Activity.performCreate(Activity.java:5231)
01-02 02:17:58.572: E/AndroidRuntime(1688): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
01-02 02:17:58.572: E/AndroidRuntime(1688): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
01-02 02:17:58.572: E/AndroidRuntime(1688): ... 11 more
答案 0 :(得分:0)
试试这个:
XML:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragment_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:weightSum="3"
tools:context=".MainActivity" >
<LinearLayout
android:id="@+id/first"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal" >
</LinearLayout>
<LinearLayout
android:id="@+id/second"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal" >
</LinearLayout>
<LinearLayout
android:id="@+id/third"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal" >
</LinearLayout>
</LinearLayout>
爪哇:
@Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.timetable_activity);
super.onCreate(savedInstanceState);
if (findViewById(R.id.fragment_layout) != null) {
if (savedInstanceState != null) {
return;
}
// Create an instance of ExampleFragment
HeaderFragment firstFragment = new HeaderFragment();
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 1);
firstFragment.getView().setLayoutParams(params);
BodyFragment secondFragment = new BodyFragment();
secondFragment.getView().setLayoutParams(params);
FooterFragment thirdFragment = new FooterFragment();
thirdFragment.getView().setLayoutParams(params);
getSupportFragmentManager().beginTransaction()
.add(R.id.first, firstFragment).commit();
getSupportFragmentManager().beginTransaction()
.add(R.id.second, secondFragment).commit();
getSupportFragmentManager().beginTransaction()
.add(R.id.third, thirdFragment).commit();
}
答案 1 :(得分:0)
在您的活动onCreate()
中,您正在创建一个新片段并立即尝试访问其视图:
HeaderFragment firstFragment = new HeaderFragment();
...
firstFragment.getView().setLayoutParams(params);
这不起作用,因为当片段附加到活动时,布局会膨胀,而你正在进行多行操作:
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_layout, firstFragment).commit();
请记住,将片段附加到活动是异步的,因此只需重新排列onCreate()
中的语句就无法解决问题。您应该在片段的onViewCreated()
中设置布局参数(如果您只需要修改片段的视图)或onAttach()
(如果您需要访问父活动的视图层次结构)。
我想建议您通过布局实例化片段来完全避免这种情况。例如:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
...
tools:context=".MainActivity" >
<fragment android:name="fully.qualified.path.to.HeaderFragment"
android:id="@+id/first_fragment"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp" />
<fragment android:name="fully.qualified.path.to.HeaderFragment"
android:id="@+id/second_fragment"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp" />
<fragment android:name="fully.qualified.path.to.HeaderFragment"
android:id="@+id/third_fragment"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp" />
</LinearLayout>