•所以我正在创建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的新手)
答案 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");
}
}