在过去的几天里,我一直在拼命尝试使用一个简单的片段(我使用两次)构建一个Android应用程序。我想将片段的EditText-boxes的内容传递给新活动。我只是无法弄清楚如何从片段中获取这些内容。到目前为止我所拥有的是:
我有edit_text_fragment.xml
:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<EditText
android:id="@+id/my_edit_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="my hint" />
</LinearLayout>
和相应的MyEditTextFragment.java
:
public class MyEditTextFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.edit_text_fragment, container, false);
return view;
}
}
然后我在我的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">
<fragment
android:id="@+id/detailfragment_placeholder"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
class="com.example.fragmenttester5.MyEditTextFragment" />
<fragment
android:id="@+id/detailfragment_placeholder2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
class="com.example.fragmenttester5.MyEditTextFragment" />
<Button
android:id="@+id/submit_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Submit all of it" />
</LinearLayout>
在我的MainActivity中,我将按钮连接到一个新活动:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button submitButton = (Button) findViewById(R.id.submit_button);
submitButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v){
Intent intent = new Intent(MainActivity.this, OtherActivity.class);
intent.putExtra("result1", "the_result_from_the_first_editText");
intent.putExtra("result2", "the_result_from_the_second_editText");
startActivity(intent);
}
});
}
}
我想我现在需要在Fragment中定义某种界面,但我找不到如何。我阅读了几个示例和教程(如this one),但它们对我毫无意义。我不明白给出的代码,我只是不明白如何根据我的用例调整它。
所以我的问题;任何人都可以帮我从活动中获取片段的内容吗?这个例子非常受欢迎,因为我只是在这里碰到我的头。
答案 0 :(得分:14)
你是对的,这是将数据从片段传递到活动的标准方法。
基本上你定义了一个Activity实现的Listener
接口,而Activity将自己注册为一个带有Fragment的监听器。
这是一个简单的例子:
<强>片段强>
class MyFragment extends Fragment {
interface Listener {
public void somethingHappenedInFragment(Object... anyDataYouWantToPassToActivity);
}
private Listener mListener;
public void setListener(Listener listener) {
mListener = listener;
}
// ... your code ...
// Now here you pass the data to the activity
mListener.somethingHappenedInFragment(some, data);
// ... more of your code
}
<强>活动强>
public MyActivity extends Activity implements MyFragment.Listener {
// ... your code ...
// creating the Fragment
MyFragment f = new MyFragment();
// register activity as listener
f.setListener(this);
// ... more of your code
// implementation of MyFragment.Listener interface
@Override
public void somethingHappenedInFragment(Object... anyDataYouWantToPassToActivity) {
// here you have the data passed from the fragment.
for (Object o : anyDataYouWantToPassToActivity {
System.out.println(o.toString();
}
}
}
答案 1 :(得分:4)
在较高的层面上,您通常需要使用Fragments解决两个任务。第一种是将数据从活动传递到片段。第二种是将数据从片段传递到活动。
一个Activity知道它创建它们后包含哪些片段,因此很容易以这种方式进行通信 - 只需调用Fragment本身的方法。但反过来并非如此;碎片可能会附加到任意数量的随机活动,因此它不知道任何关于它的父级。
解决方案是实现Activity实现的接口,Fragment知道如何与之通信。这样,你的片段有一些它知道如何与之交谈的东西。这里有一些具体的代码示例:http://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity
(特别是,请查看“创建活动的事件回调”代码示例)。
答案 2 :(得分:2)
因此,如果事件发生在 Activity
中,您将创建一个与Fragment
交谈的界面。对于这种情况,您只需在Fragment
可以调用的Activity
中创建一个可访问的方法。所以
public class MyEditTextFragment extends Fragment {
private EditText mEditText;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.edit_text_fragment, container, false);
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mEditText = (EditText) getView().findViewById(R.id.my_edit_text);
}
public Editable getText() {
return mEditText.getText();
}
}
然后
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final MyEditTextFragment fragment1 = (MyEditTextFragment)
getFragmentManager().findFragmentById(R.id.detailfragment_placeholder);
final MyEditTextFragment fragment2 = (MyEditTextFragment)
getFragmentManager().findFragmentById(R.id.detailfragment_placeholder2);
Button submitButton = (Button) findViewById(R.id.submit_button);
submitButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v){
String firstResult = fragment1.getText().toString();
String secondResult = fragment2.getText().toString();
Intent intent = new Intent(MainActivity.this, OtherActivity.class);
intent.putExtra("result1", firstResult);
intent.putExtra("result2", secondResult);
startActivity(intent);
}
});
}
}
这假设您在Fragment
中分配了FragmentTransaction
个标记。请务必检查null Fragments
(为简洁起见省略)
答案 3 :(得分:0)
活动将从Fragment
中的updateDetail()方法接收数据//// Activity
public class RssfeedActivity extends Activity implements MyListFragment.OnItemSelectedListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rssfeed);
Button btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("Annv - Fragment", "onClick here");
}
});
}
// if the wizard generated an onCreateOptionsMenu you can delete
// it, not needed for this tutorial
@Override
public void onRssItemSelected(String link) {
// DetailFragment fragment = (DetailFragment) getFragmentManager()
// .findFragmentById(R.id.detailFragment);
// if (fragment != null && fragment.isInLayout()) {
// fragment.setText(link);
// }
// Intent start = new Intent(this, RssfeedSecondActivity.class);
// startActivity(start);
DetailFragment fragment = (DetailFragment) getFragmentManager()
.findFragmentById(R.id.detailFragment);
if (fragment != null && fragment.isInLayout()) {
fragment.setText(link);
}
}
}
/// Fragment
public class MyListFragment extends Fragment {
private OnItemSelectedListener listener;
private OnItemStartActivityListener listenerStartAct;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_rsslist_overview,
container, false);
Button button = (Button) view.findViewById(R.id.button1);
Log.d("Annv - Fragment", "run on " + getActivity().toString());
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
updateDetail();
}
});
return view;
}
public interface OnItemSelectedListener {
public void onRssItemSelected(String link);
}
public interface OnItemStartActivityListener {
public void onRssStartActivity(String link);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof OnItemSelectedListener) {
Log.d("Annv - Fragment", "activity " + activity.getLocalClassName());
listener = (OnItemSelectedListener) activity;
} else if (activity instanceof OnItemStartActivityListener) {
Log.d("Annv - Fragment", "activity " + activity.getLocalClassName());
listenerStartAct = (OnItemStartActivityListener) activity;
} else {
throw new ClassCastException(activity.toString()
+ " must implemenet MyListFragment.OnItemSelectedListener");
}
}
// May also be triggered from the Activity
public void updateDetail() {
// create fake data
// String newTime = String.valueOf(System.currentTimeMillis());
// // Send data to Activity
// listenerStartAct.onRssItemSelected(newTime);
if (getActivity() instanceof OnItemSelectedListener) {
listener.onRssItemSelected("start start");
} else {
String newTime = String.valueOf(System.currentTimeMillis());
listenerStartAct.onRssStartActivity(newTime);
}
}
}