使用权重参数动态创建片段

时间:2014-01-02 09:20:16

标签: java android dynamic android-fragments

我正在创建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

2 个答案:

答案 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>