我已阅读this手册,也阅读了this本书。 developer.android.com说我应该通过活动实现沟通。但是这本书说我可以使用setTargetFragment()并手动调用onActivityResult()来获取其他片段的目标片段。每种方法都有效,但哪种方法正确?什么是setTargetFrament(),如果我不能用它来与其他片段进行通信?
答案 0 :(得分:2)
setTargetFrament()和getTargetFrament()可以在一个启动另一个片段的片段的上下文中使用。第一个片段可以将其自身作为对第二个片段的引用:
MyFragment newFrag = new MyFragment();
newFrag.setTargetFragment(this, 0);
getFragmentManager().beginTransaction().replace(R.id.frag_one, newFrag).commit();
现在newFrag可以使用getTargetFrament()
直接从oldFrag检索oldFrag和访问方法。
然而,这并不是建议在通常情况下使用的东西。
片段之间的通信推荐方式是通过父活动来完成的,如docs所述:
Often you will want one Fragment to communicate with another,
for example to change the content based on a user event.
All Fragment-to-Fragment communication is done through the associated Activity.
Two Fragments should never communicate directly.
以下是一个例子:
主要活动的布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<FrameLayout
android:id="@+id/frag_one"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<FrameLayout
android:id="@+id/frag_two"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
活动:
public class MainActivity extends Activity
{
private MyFragment f1;
private MyFragment f2;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Bundle b1 = new Bundle();
b1.putString("name", "Fragment One");
f1 = MyFragment.createNew(b1);//we create a new fragment instance
f1.setOnReceiveListener(new MyFragment.ReceiveListener()//we create a new ReceiveListener and pass it to the fragment
{
@Override
public void recv(String str)
{
//f1 has sent data to the activity, the activity passes forward to f2
f2.send(str);
}
});
//we attach the fragment to the activity
getFragmentManager().beginTransaction().add(R.id.frag_one, f1, "frag_one").commit();
//we repeat the above process for the second fragment
Bundle b2 = new Bundle();
b2.putString("name", "Fragment Two");
f2 = MyFragment.createNew(b2);
f2.setOnReceiveListener(new MyFragment.ReceiveListener()
{
@Override
public void recv(String str)
{
f1.send(str);
}
});
getFragmentManager().beginTransaction().add(R.id.frag_two, f2, "frag_two").commit();
}
}
片段布局:
<?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" >
<Button
android:id="@+id/frag_btn"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_alignParentTop="true"/>
<TextView
android:id="@+id/frag_txt"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_below="@+id/frag_btn"
android:textSize="10sp"/>
</RelativeLayout>
片段类:
public class MyFragment extends Fragment
{
private ReceiveListener recv_list;
private Button btn;
private TextView txt;
//static factory function that creates new fragments
public static MyFragment createNew(Bundle b)
{
MyFragment f = new MyFragment();
f.setArguments(b);
return f;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.fragment, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
btn = (Button) view.findViewById(R.id.frag_btn);
txt = (TextView) view.findViewById(R.id.frag_txt);
//we retrieve the passed arguments (in this case the name)
Bundle b = getArguments();
final String name = b.getString("name");
btn.setText(name);
btn.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
if(null != recv_list)
{
//now we pass the data to the parent activity
recv_list.recv(name + " says hello!");
}
}
});
}
//the activity passes data to the fragment using this method
public void send(String s)
{
txt.append(s + "\n");
}
//helper method that will set the listener
public void setOnReceiveListener(ReceiveListener l)
{
recv_list = l;
}
//the declaration of the listener
public interface ReceiveListener
{
public void recv(String str);
}
}