打开包含片段的活动时崩溃

3

• 我正在创建两个fragment,测试“Fragment间通信”模式:

• FragmentA 包含一个 ListView,FragmentB 包含一个 TextView。

在竖屏模式下:MainActivity 包含 FragmentA(listview),如果用户点击其中的一个项目,则会移动到 AnotherActivity,其中包含带有一些文本的 FragmentB(textview)。

• 在横屏模式下: MainActivity 包含了 FragmentA B

• 横屏模式下正常工作,但是在纵向模式下,如果我点击某个项目,它就会崩溃。

FragmentA.java:

public class FragmentA extends Fragment implements OnItemClickListener {
    ListView list;
    Communicator comm;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        return inflater.inflate(R.layout.fragment_layout_a, container, false);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onActivityCreated(savedInstanceState);
        list = (ListView) getActivity().findViewById(R.id.listView1);
        ArrayAdapter adapter = ArrayAdapter.createFromResource(getActivity(),
                R.array.titles, android.R.layout.simple_list_item_1);
        list.setAdapter(adapter);
        list.setOnItemClickListener(this);

        Log.d("this", "Done setting listview");
    }

    @Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
        // TODO Auto-generated method stub
        comm.respone(arg2);
    }

    void setCommunicator(Communicator c) {
        comm = c;
    }

    public interface Communicator {
        public void respone(int index);
    }
}

FragmentB.java:

    public class FragmentB extends Fragment {

    TextView display;
    String[] data;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub

        return inflater.inflate(R.layout.fragment_layout_b, container, false);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        display = (TextView) getActivity().findViewById(R.id.textView1);
        Resources res = getResources();
        data = res.getStringArray(R.array.detail);
        Log.d("this", "Fragment B created ");
        super.onActivityCreated(savedInstanceState);

    }

    void changeText(int index) {

        display.setText(data[index]);
        Log.d("this", "changing text");
    }
}

MainActivity.java:

 public class MainActivity extends Activity implements FragmentA.Communicator {

    FragmentA f1;
    FragmentB f2;
    FragmentManager manager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        manager = getFragmentManager();
        f1 = (FragmentA) manager.findFragmentById(R.id.fragment1);
        f1.setCommunicator(this);

        Log.d("this", "setCommunicator");

    }

    @Override
    public void respone(int index) {
        // TODO Auto-generated method stub

        f2 = (FragmentB) manager.findFragmentById(R.id.fragment2);
        Log.d("this", "f2 referenced from Main");
        if (f2 != null && f2.isVisible())// landscape
        {
            f2.changeText(index);
        } else // portrait
        {
            Intent i = new Intent(this, AnotherActivity.class);
            i.putExtra("index", index);
            startActivity(i);
        }
    }

}

AnotherActivity.java:

public class AnotherActivity extends Activity {
    FragmentB f2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_another);

        Log.d("this", "Another Activity");
        f2 = (FragmentB) getFragmentManager().findFragmentById(R.id.fragment2);
        Log.d("this","fragment2 in Another Activity");
        Intent i = getIntent();
        int index = i.getIntExtra("index", 0);
        Log.d("this", "Get intent extras");
        if (f2 != null)
        {
            f2.changeText(index);
            Log.d("this", "changing text in Another Activity");
        }
    }

}

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.fragmentdemo_2.MainActivity" >

    <fragment
        android:id="@+id/fragment1"
        android:name="com.example.fragmentdemo_2.FragmentA"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

activity_another.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.fragmentdemo_2.AnotherActivity" >

    <fragment
        android:id="@+id/fragment2"
        android:name="com.example.fragmentdemo_2.FragmentB"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true" />

</RelativeLayout>

fragment_layout_a.xml

<?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" >

    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:background="#addbb3"
        android:layout_alignParentTop="true" >
    </ListView>

</RelativeLayout>

fragment_layout_b.xml

<?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" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:text="..."
        android:background="#22c936"
        android:textAppearance="?android:attr/textAppearanceLarge" />

</RelativeLayout>

清单文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.fragmentdemo_2"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="17" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".AnotherActivity"
            android:label="@string/title_activity_another" >
            <intent-filter>
                <action android:name="android.intent.action.ANOTHERACTIVITY" />

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

</manifest>

• 日志记录:

09-30 11:38:40.406: E/AndroidRuntime(14991): FATAL EXCEPTION: main
09-30 11:38:40.406: E/AndroidRuntime(14991): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.fragmentdemo_2/com.example.fragmentdemo_2.AnotherActivity}: java.lang.NullPointerException
09-30 11:38:40.406: E/AndroidRuntime(14991):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2245)
09-30 11:38:40.406: E/AndroidRuntime(14991):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2295)
09-30 11:38:40.406: E/AndroidRuntime(14991):    at android.app.ActivityThread.access$700(ActivityThread.java:150)
09-30 11:38:40.406: E/AndroidRuntime(14991):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1280)
09-30 11:38:40.406: E/AndroidRuntime(14991):    at android.os.Handler.dispatchMessage(Handler.java:99)
09-30 11:38:40.406: E/AndroidRuntime(14991):    at android.os.Looper.loop(Looper.java:137)
09-30 11:38:40.406: E/AndroidRuntime(14991):    at android.app.ActivityThread.main(ActivityThread.java:5279)
09-30 11:38:40.406: E/AndroidRuntime(14991):    at java.lang.reflect.Method.invokeNative(Native Method)
09-30 11:38:40.406: E/AndroidRuntime(14991):    at java.lang.reflect.Method.invoke(Method.java:511)
09-30 11:38:40.406: E/AndroidRuntime(14991):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
09-30 11:38:40.406: E/AndroidRuntime(14991):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
09-30 11:38:40.406: E/AndroidRuntime(14991):    at dalvik.system.NativeStart.main(Native Method)
09-30 11:38:40.406: E/AndroidRuntime(14991): Caused by: java.lang.NullPointerException
09-30 11:38:40.406: E/AndroidRuntime(14991):    at com.example.fragmentdemo_2.FragmentB.changeText(FragmentB.java:38)
09-30 11:38:40.406: E/AndroidRuntime(14991):    at com.example.fragmentdemo_2.AnotherActivity.onCreate(AnotherActivity.java:27)
09-30 11:38:40.406: E/AndroidRuntime(14991):    at android.app.Activity.performCreate(Activity.java:5267)
09-30 11:38:40.406: E/AndroidRuntime(14991):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1097)
09-30 11:38:40.406: E/AndroidRuntime(14991):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2209)
09-30 11:38:40.406: E/AndroidRuntime(14991):    ... 11 more

• 使用“this”过滤器的日志记录:

09-29 22:02:16.098: D/this(7795): setCommunicator
09-29 22:02:16.098: D/this(7795): Done setting listview
09-29 22:02:36.848: D/this(7795): f2 referenced from Main
09-29 22:02:36.948: D/this(7795): Another Activity
09-29 22:02:36.948: D/this(7795): fragment2 in Another Activity
09-29 22:02:36.948: D/this(7795): Get intent extras

请帮忙,提前感谢!(我是Java-Android的新手)


2
请在您的logcat中发布异常消息和堆栈跟踪。 (不要使用“this”进行过滤。)它将准确显示导致NullPointerException的代码行。 - Code-Apprentice
正确格式化和缩进的代码将更易于理解,您也会更快地得到响应。请格式化您的代码。 - Mohan Krishna
这不是正确的多窗格布局方式。在开始之前,请查看http://developer.android.com/design/patterns/multi-pane-layouts.html。阅读说明... - Harsha Vardhan
问题在这里 FragmentB.java:38,看一下代码...或者在这里发布那一行。 - RajaReddy PolamReddy
GrIsHu:我在onActivityCreated方法中初始化了TextView,但是当我把初始化放在onCreateView中时,结果是一样的。 - Vinh Dat Ha
显示剩余12条评论
1个回答

0
问题在于您没有遵循片段和活动的正确层次结构。加载片段后,您始终可以访问片段的视图和方法。
在您的情况下,您间接地从 MainActivity 传递值到 FragmentA,并从 FragmentA 打开 AnotherActivity,其中包含您的 FragmentB。在您的情况下,您尝试使用 Intent 从一个片段向另一个片段传递值,这不是有效的方法。您始终可以通过 Bundle 在片段之间传递值并从 Bundle 中获取它。请查看我的更改,现在它已经起作用了。根据您的需求进行相关更改。
只需在所有类中进行以下更改即可。

MainActivity.java

public class MainActivity extends Activity {

    FragmentA f1;
    FragmentB f2;
    FragmentManager manager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        manager = getFragmentManager();
        f1 = (FragmentA) manager.findFragmentById(R.id.fragment1);
        Log.d("this", "setCommunicator");

    }

   /* @Override
    public void respone(int index) {
        // TODO Auto-generated method stub

        f2 = (FragmentB) manager.findFragmentById(R.id.fragment2);
        Log.d("this", "f2 referenced from Main");
        if (f2 != null && f2.isVisible())// landscape
        {
            f2.changeText(index);
        } else // portrait
        {
            Intent i = new Intent(this, AnotherActivity.class);
            i.putExtra("index", index);
            startActivity(i);
        }
    }*/

}

FragmentA.java

public class FragmentA extends Fragment implements OnItemClickListener {
    ListView list;
    Communicator comm;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        return inflater.inflate(R.layout.fragment_layout_a, container, false);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onActivityCreated(savedInstanceState);
        list = (ListView) getActivity().findViewById(R.id.listView1);
        ArrayAdapter adapter = ArrayAdapter.createFromResource(getActivity(),
                R.array.titles, android.R.layout.simple_list_item_1);
        list.setAdapter(adapter);
        list.setOnItemClickListener(this);

        Log.d("this", "Done setting listview");
    }

    @Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
        // TODO Auto-generated method stub
         Intent i = new Intent(FragmentA.this.getActivity(), AnotherActivity.class);
         i.putExtra("index", arg2);
         startActivity(i);
    }

    void setCommunicator(Communicator c) {
        comm = c;
    }

    public interface Communicator {
        public void respone(int index);
    }
}

AnotherActivity.java

public class AnotherActivity extends Activity {
    FragmentB f2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_another);

        FragmentManager mang = getFragmentManager();
        Log.d("this", "Another Activity");

        Log.d("this", "fragment2 in Another Activity");
        Intent i = getIntent();
        int index = i.getIntExtra("index", 0);
        Bundle bund = new Bundle();
        bund.putInt("val", index);
        f2 = (FragmentB) mang.findFragmentById(R.id.fragment2);
        f2.changeText(index);
        Log.d("this", "Get intent extras");

    }

}

FragmentB.java

public class FragmentB extends Fragment {

    TextView display;
    String[] data;
    int val;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        View m_view;
        m_view = inflater.inflate(R.layout.fragment_layout_b, container, false);

        display = (TextView) m_view.findViewById(R.id.textView1);
        Resources res = getActivity().getResources();
        data = res.getStringArray(R.array.titles);
        Log.d("this", "Fragment B created ");
        return m_view;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        // TODO Auto-generated method stub

        super.onActivityCreated(savedInstanceState);

    }

    public void changeText(int index) {
        val=getActivity().getIntent().getIntExtra("index",0);
        display.setText(data[val]);
        Log.d("this", "changing text");
    }

}

仍然崩溃了 以下是一些日志: 09-30 12:17:33.812: E/AndroidRuntime(23532): FATAL EXCEPTION: main 09-30 12:17:33.812: E/AndroidRuntime(23532): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.fragmentdemo_2/com.example.fragmentdemo_2.AnotherActivity}: java.lang.NullPointerException 09-30 12:17:33.812: E/AndroidRuntime(23532): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2245) - Vinh Dat Ha
是的,我做了!在这里,以防我做错:<activity android:name=".AnotherActivity" android:label="@string/title_activity_another" > <intent-filter> <action android:name="android.intent.action.ANOTHERACTIVITY" /> - Vinh Dat Ha
将您的 changeText 方法更改为 public void - GrIsHu
请尝试调试您的代码,并告诉我它究竟在哪里崩溃了?告诉我 FragmentBAnotherActivity 文件中的行号:fragmentdemo_2.FragmentB.changeText(FragmentB.java:38)fragmentdemo_2.AnotherActivity.onCreate(AnotherActivity.java:27) - GrIsHu
fragmentB中的第38行是display.setText(data[index]); --- 我认为问题可能出在onCreate()方法中使用getActivity()初始化TextView上,但我不知道该如何处理...调试发现第38行出现了Nullpointerexception - fragmentB - Vinh Dat Ha
显示剩余7条评论

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