打开活动包含片段时崩溃

时间:2014-09-30 04:29:29

标签: java android listview android-fragments nullpointerexception

•所以我正在创建2个片段,测试“片段间通信”模式:

•FragmentA包含ListView,FragmentB包含TextView。

在纵向模式下:MainActivity包含FragmentA(列表视图),如果用户单击某个项目,则移至包含FragmentB(textview)的AnotherActivity,其中包含一些文本..

•在lanescape模式下: MainActivity 包含 FragmentA B ..

•我的lanescape模式工作正常,在纵向模式下,如果我点击一个项目,它就会崩溃。

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>

•Logcat:

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”的Logcat:

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的新手)

1 个答案:

答案 0 :(得分: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");
    }

}