我很擅长使用Fragments。
我只是想构建一个使用Fragments的简单示例应用程序。我的方案是,我有两个活动,每个活动中有一个片段。第一个片段有一个edittext和一个按钮。第二个片段有一个textview。当我在edittext中输入名称并单击按钮时,第二个片段中的textview应显示在第一个片段的edittext中输入的名称。
我能够将第一个片段的值发送到其活动,然后从该活动发送到第二个活动。现在我如何在第二个片段中使用此值。
这是Java代码:::
package com.example.fragmentexample;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class Fragment_1 extends Fragment{
OnFragmentChangedListener mCallback;
// Container Activity must implement this interface
public interface OnFragmentChangedListener {
public void onButtonClicked(String name);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mCallback = (OnFragmentChangedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnHeadlineSelectedListener");
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.fragment_fragment_1, container, false);
final EditText edtxtPersonName_Fragment = (EditText) view.findViewById(R.id.edtxtPersonName);
Button btnSayHi_Fragment = (Button) view.findViewById(R.id.btnSayHi);
btnSayHi_Fragment.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
String name = edtxtPersonName_Fragment.getText().toString();
FragmentManager fm = getFragmentManager();
Fragment_2 f2 = (Fragment_2) fm.findFragmentById(R.id.fragment_content_2);
Activity activity = getActivity();
if(activity != null)
{
Toast.makeText(activity, "Say&ing Hi in Progress...", Toast.LENGTH_LONG).show();
}
if(f2 != null && f2.isInLayout())
{
f2.setName(name);
}
else
{
mCallback.onButtonClicked(name);
}
}
});
return view;
}
}
MainActivity.Java
package com.example.fragmentexample;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Choreographer.FrameCallback;
import android.view.Menu;
public class MainActivity extends Activity implements Fragment_1.OnFragmentChangedListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
@Override
public void onButtonClicked(String name) {
// TODO Auto-generated method stub
Intent i = new Intent(this, SecondActivity.class);
i.putExtra("", name);
startActivity(i);
}
}
SecondActivity.Java
package com.example.fragmentexample;
import android.app.Activity;
import android.os.Bundle;
public class SecondActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Bundle b = getIntent().getExtras();
Fragment_2 f2 = new Fragment_2();
f2.setArguments(b);
}
}
Fragment_2.Java
package com.example.fragmentexample;
import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class Fragment_2 extends Fragment{
View view;
TextView txtName;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
view = inflater.inflate(R.layout.fragment_fragment_2, container, false);
// Exception at this line
String name = getArguments().getString("message");
txtName = (TextView) view.findViewById(R.id.txtViewResult);
txtName.setText(name);
return view;
}
@Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
super.onAttach(activity);
}
public void setName(String name)
{
txtName.setText("Hi " + name);
}
}
我得到以下异常:::
04-16 18:10:24.573: E/AndroidRuntime(713): FATAL EXCEPTION: main
04-16 18:10:24.573: E/AndroidRuntime(713): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.fragmentexample/com.example.fragmentexample.SecondActivity}: android.view.InflateException: Binary XML file line #8: Error inflating class fragment
04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1815)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1831)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.ActivityThread.access$500(ActivityThread.java:122)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1024)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.os.Handler.dispatchMessage(Handler.java:99)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.os.Looper.loop(Looper.java:132)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.ActivityThread.main(ActivityThread.java:4123)
04-16 18:10:24.573: E/AndroidRuntime(713): at java.lang.reflect.Method.invokeNative(Native Method)
04-16 18:10:24.573: E/AndroidRuntime(713): at java.lang.reflect.Method.invoke(Method.java:491)
04-16 18:10:24.573: E/AndroidRuntime(713): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
04-16 18:10:24.573: E/AndroidRuntime(713): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
04-16 18:10:24.573: E/AndroidRuntime(713): at dalvik.system.NativeStart.main(Native Method)
04-16 18:10:24.573: E/AndroidRuntime(713): Caused by: android.view.InflateException: Binary XML file line #8: Error inflating class fragment
04-16 18:10:24.573: E/AndroidRuntime(713): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:688)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.view.LayoutInflater.rInflate(LayoutInflater.java:724)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.view.LayoutInflater.inflate(LayoutInflater.java:479)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.view.LayoutInflater.inflate(LayoutInflater.java:391)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.view.LayoutInflater.inflate(LayoutInflater.java:347)
04-16 18:10:24.573: E/AndroidRuntime(713): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:223)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.Activity.setContentView(Activity.java:1786)
04-16 18:10:24.573: E/AndroidRuntime(713): at com.example.fragmentexample.SecondActivity.onCreate(SecondActivity.java:13)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.Activity.performCreate(Activity.java:4397)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1048)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1779)
04-16 18:10:24.573: E/AndroidRuntime(713): ... 11 more
04-16 18:10:24.573: E/AndroidRuntime(713): Caused by: java.lang.NullPointerException
04-16 18:10:24.573: E/AndroidRuntime(713): at com.example.fragmentexample.Fragment_2.onCreateView(Fragment_2.java:24)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:754)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:956)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1035)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.app.Activity.onCreateView(Activity.java:4177)
04-16 18:10:24.573: E/AndroidRuntime(713): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:664)
04-16 18:10:24.573: E/AndroidRuntime(713): ... 21 more
如何从SecondActivity.java中的bundle获取Fragment_2.Java中的值?
答案 0 :(得分:184)
第1步。将数据从片段发送到活动
Intent intent = new Intent(getActivity().getBaseContext(),
TargetActivity.class);
intent.putExtra("message", message);
getActivity().startActivity(intent);
第2步。在活动中接收此数据:
Intent intent = getIntent();
String message = intent.getStringExtra("message");
第3步。将数据从活动发送到另一个活动遵循正常方法
Intent intent = new Intent(MainActivity.this,
TargetActivity.class);
intent.putExtra("message", message);
startActivity(intent);
第4步以在活动中接收此数据
Intent intent = getIntent();
String message = intent.getStringExtra("message");
第5步。从活动中,您可以将数据发送到Fragment,意图如下:
Bundle bundle=new Bundle();
bundle.putString("message", "From Activity");
//set Fragmentclass Arguments
Fragmentclass fragobj=new Fragmentclass();
fragobj.setArguments(bundle);
并在Fragment onCreateView方法中接收片段:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String strtext=getArguments().getString("message");
return inflater.inflate(R.layout.fragment, container, false);
}
答案 1 :(得分:41)
如开发者网站所述
通常,您会希望一个片段与另一个片段进行通信,例如根据用户事件更改内容。所有Fragment-to-Fragment通信都是通过相关的Activity完成的。两个碎片永远不应该直接沟通。
片段之间的通信应该通过相关的Activity来完成。
我们有以下几个部分:
活动托管片段并允许片段通信
FragmentA 将发送数据的第一个片段
FragmentB 第二个片段,它将从 FragmentA
接收数据
FragmentA的实现是:
public class FragmentA extends Fragment
{
DataPassListener mCallback;
public interface DataPassListener{
public void passData(String data);
}
@Override
public void onAttach(Context context)
{
super.onAttach(context);
// This makes sure that the host activity has implemented the callback interface
// If not, it throws an exception
try
{
mCallback = (OnImageClickListener) context;
}
catch (ClassCastException e)
{
throw new ClassCastException(context.toString()+ " must implement OnImageClickListener");
}
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)
{
// Suppose that when a button clicked second FragmentB will be inflated
// some data on FragmentA will pass FragmentB
// Button passDataButton = (Button).........
passDataButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (view.getId() == R.id.passDataButton) {
mCallback.passData("Text to pass FragmentB");
}
}
});
}
}
MainActivity实施是:
public class MainActivity extends ActionBarActivity implements DataPassListener{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (findViewById(R.id.container) != null) {
if (savedInstanceState != null) {
return;
}
getFragmentManager().beginTransaction()
.add(R.id.container, new FragmentA()).commit();
}
}
@Override
public void passData(String data) {
FragmentB fragmentB = new FragmentB ();
Bundle args = new Bundle();
args.putString(FragmentB.DATA_RECEIVE, data);
fragmentB .setArguments(args);
getFragmentManager().beginTransaction()
.replace(R.id.container, fragmentB )
.commit();
}
}
FragmentB的实现是:
public class FragmentB extends Fragment{
final static String DATA_RECEIVE = "data_receive";
TextView showReceivedData;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_B, container, false);
showReceivedData = (TextView) view.findViewById(R.id.showReceivedData);
}
@Override
public void onStart() {
super.onStart();
Bundle args = getArguments();
if (args != null) {
showReceivedData.setText(args.getString(DATA_RECEIVE));
}
}
}
我希望这会有所帮助..
答案 2 :(得分:31)
//在Fragment_1.java中
Bundle bundle = new Bundle();
bundle.putString("key","abc"); // Put anything what you want
Fragment_2 fragment2 = new Fragment_2();
fragment2.setArguments(bundle);
getFragmentManager()
.beginTransaction()
.replace(R.id.content, fragment2)
.commit();
//在Fragment_2.java中
Bundle bundle = this.getArguments();
if(bundle != null){
// handle your code here.
}
希望这对你有所帮助。
答案 3 :(得分:22)
来自Developers网站:
通常,您会希望一个片段与另一个片段进行通信,例如根据用户事件更改内容。所有Fragment-to-Fragment通信都是通过相关的Activity完成的。两个碎片永远不应该直接沟通。
您可以借助其活动在片段之间进行通信。您可以使用this方法在活动和片段之间进行通信。
请同时查看this链接。
答案 4 :(得分:3)
首先所有答案都是正确的,您可以使用Intent
传递除自定义对象之外的数据。如果要传递自定义对象,则必须对自定义对象类实施Serialazable
或Parcelable
。我觉得它太复杂了......
因此,如果您的项目很简单,请尝试使用DataCache
。这为传递数据提供了超级简单的方法。
参考: Github project CachePot
1 - 将此项设置为View或Activity或Fragment,它将发送数据
DataCache.getInstance().push(obj);
2 - 获取数据,如下所示
public class MainFragment extends Fragment
{
private YourObject obj;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
obj = DataCache.getInstance().pop(YourObject.class);
}//end onCreate()
}//end class MainFragment
答案 5 :(得分:3)
可以通过使用Android体系结构组件(例如ViewModel和LiveData)来实现在片段之间传递数据的最新解决方案。使用此解决方案,您无需定义用于通信的接口,并可以获得使用视图模型的优势,例如由于配置更改而导致的数据生存。
在此解决方案中,通信中涉及的片段共享与其活动生命周期相关的同一viewmodel对象。视图模型对象包含livedata对象。一个片段设置要在livedata对象上传递的数据,第二个片段观察者对livedata进行更改并接收数据。
这是完整的示例http://www.zoftino.com/passing-data-between-android-fragments-using-viewmodel
答案 6 :(得分:2)
片段之间的通信相当复杂(我发现听众的概念有点难以实现)。
通常使用“事件总线”来抽象这些通信。这是第三方库,它会为您处理这种通信。
'Otto'是经常用来做这件事的人,可能值得研究:http://square.github.io/otto/
答案 7 :(得分:2)
在片段之间传递参数。
回答这个问题已经很晚了,但它可以帮助别人!
的 Fragment_1.java
强>
Bundle i = new Bundle();
i.putString("name", "Emmanuel");
Fragment_1 frag = new Fragment_1();
frag.setArguments(i);
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.content_frame
, new Fragment_2())
.commit();
然后在 Fragment_2.java
中,您可以通常在onActivityCreated
内获取参数
例如
Intent intent = getActivity().getIntent();
if (intent.getExtras() != null) {
String name =intent.getStringExtra("name");
}
答案 8 :(得分:2)
这是一个石器时代的问题,但仍然非常重要。特别是现在,Android团队正在更加努力地坚持单一活动模型,各个片段之间的通信变得更加重要。 LiveData和Interfaces是解决此问题的绝佳方法。但是现在Google终于解决了这个问题,并试图使用FragmentManager带来一个简单得多的解决方案。这是在Kotlin中可以完成的方法。
在接收方片段中添加一个侦听器:
setFragmentResultListener(
"data_request_key",
lifecycleOwner,
FragmentResultListener { requestKey: String, bundle: Bundle ->
// unpack the bundle and use data
val frag1Str = bundle.getString("frag1_data_key")
})
在发件人片段中(frag1):
setFragmentResult(
"data_request_key",
bundleOf("frag1_data_key" to value)
)
请记住,此功能仅在fragment-ktx版本1.3.0-alpha04及更高版本中可用。
信用和进一步阅读:
答案 9 :(得分:2)
使用官方ViewModel documentation提出的SharedViewModel
一个活动中两个或多个片段通常需要 互相交流。想象一个常见的主从案例 片段,其中有一个片段,用户可以在其中选择一个项目 从列表和另一个片段中显示 选择的项目。这种情况永远都不是小事,因为两个片段都需要 定义一些接口描述,并且所有者活动必须绑定 两者在一起。此外,两个片段都必须处理该场景 另一个片段尚未创建或不可见的地方。
可以使用ViewModel对象解决此常见的痛点。 这些片段可以使用其活动范围共享ViewModel 处理此通讯
首先实现fragment-ktx,以更轻松地实例化视图模型
dependencies {
implementation "androidx.fragment:fragment-ktx:1.2.2"
}
然后,您只需要将要与另一个片段共享的数据放入视图模型中
class SharedViewModel : ViewModel() {
val selected = MutableLiveData<Item>()
fun select(item: Item) {
selected.value = item
}
}
然后,最后,只需在每个片段中实例化viewModel,然后从要设置数据的片段中设置selected
的值
class MasterFragment : Fragment() {
private val model: SharedViewModel by activityViewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
itemSelector.setOnClickListener { item ->
model.select(item)
}
}
}
然后,只需在Fragment目的地监听此值
class DetailFragment : Fragment() {
private val model: SharedViewModel by activityViewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
model.selected.observe(viewLifecycleOwner, Observer<Item> { item ->
// Update the UI
})
}
}
您也可以采用相反的方式
答案 10 :(得分:2)
我认为解决此问题的一个好方法是使用自定义界面。
假设您有两个片段(A和B),它们位于同一个活动中,并且您希望将数据从A发送到B.
界面:
public interface OnDataSentListener{
void onDataSent(Object data);
}
的活动:
public class MyActivity extends AppCompatActivity{
private OnDataSentListener onDataSentListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_activity);
FragmentTransaction trans = getFragmentManager().beginTransaction();
FragmentA fa = new FragmentA();
FragmentB fb = new FragmentB();
fa.setOnDataSentListener(new Listeners.OnDataSentListener() {
@Override
public void onDataSent(Object data) {
if(onDataSentListener != null) onDataSentListener.onDataSent(data);
}
});
transaction.add(R.id.frame_a, fa);
transaction.add(R.id.frame_b, fb);
transaction.commit();
}
public void setOnDataSentListener(OnDataSentListener listener){
this.onDataSentListener = listener;
}
}
片段A:
public class FragmentA extends Fragment{
private OnDataSentListener onDataSentListener;
private void sendDataToFragmentB(Object data){
if(onDataSentListener != null) onDataSentListener.onDataSent(data);
}
public void setOnDataSentListener(OnDataSentListener listener){
this.onDataSentListener = listener;
}
}
片段B:
public class FragmentB extends Fragment{
private void initReceiver(){
((MyActivity) getActivity()).setOnDataSentListener(new OnDataSentListener() {
@Override
public void onDataSent(Object data) {
//Here you receive the data from fragment A
}
});
}
}
答案 11 :(得分:1)
将数据从Fragment传递到另一个Fragment
从第一个片段
// Set data to pass
MyFragment fragment = new MyFragment(); //Your Fragment
Bundle bundle = new Bundle();
bundle.putInt("year", 2017) // Key, value
fragment.setArguments(bundle);
// Pass data to other Fragment
getFragmentManager()
.beginTransaction()
.replace(R.id.content, fragment)
.commit();
On Second Fragment
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle bundle = this.getArguments();
if (bundle != null) {
Int receivedYear = bundle.getInt("year", ""); // Key, default value
}
}
答案 12 :(得分:1)
这个简单的实现有助于以简单的方式在片段之间传递数据。 认为您想传递来自&#39; Frgment1&#39;到&#39; Fragment2&#39;
在Fragment1中(设置要发送的数据)
Bundle bundle = new Bundle();
bundle.putString("key","Jhon Doe"); // set your parameteres
Fragment2 nextFragment = new Fragment2();
nextFragment.setArguments(bundle);
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_drawer, nextFragment).commit();
在Fragment2 onCreateView方法(Get parameteres)
String value = this.getArguments().getString("key");//get your parameters
Toast.makeText(getActivity(), value+" ", Toast.LENGTH_LONG).show();//show data in tost
答案 13 :(得分:0)
100%有效的解决方案:(如果您有帮助的话,别忘了投票)
在您的第一个片段中输入以下代码:
editprofile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Fragment_editprofile Fragment = new Fragment_editprofile();
.
.
.
.
.
Fragment.getintentdetails(tv_name.getText().toString(),
tv_mob.getText().toString(), tv_email.getText().toString(), tv_dob.getText().toString(),
tv_gender.getText().toString(), photointent);
}
});
在第二个片段中,制作如下方法:
public void getintentdetails(String name, String mobile, String email, String dob, String gender,
String photointent) {
this.name_str= name;
this.mob_str= mobile;
this.email_str= email;
this.dob_str= dob;
this.gender_str= gender;
this.photo_str= photointent;
}
然后在类级别定义一个变量:
String name_str, mob_str, dob_str, photo_str, email_str, gender_str;
然后在第二个片段中创建另一个方法来设置值:
setexistingdetails();
private void setexistingdetails() {
if(!name_str.equalsIgnoreCase(""))
(et_name).setText(name_str);
if(!mob_str.equalsIgnoreCase(""))
et_mobile.setText(mob_str);
if(!email_str.equalsIgnoreCase(""))
email_et.setText(email_str);
if(!dob_str.equalsIgnoreCase(""))
dob_et.setText(dob_str);
if(!gender_str.equalsIgnoreCase("")){
if (gender_str.equalsIgnoreCase("m")){
male_radio.setChecked(true);
}else {
female_radio.setChecked(true);
}
}
if(!photo_str.equalsIgnoreCase("")){
try {
Picasso.get().load(Const.BASE_PATH+"include/sub-domain/GENIUS/"+photo_str).into(adminpropic_edit);
} catch (Exception e) { }
}
}
答案 14 :(得分:0)
您可以通过 ViewModel 和实时数据(已由Arnav Rao清除)来实现您的目标。现在我举一个例子来更清楚地清除它。
首先,将假设的ViewModel
命名为SharedViewModel.java
。
public class SharedViewModel extends ViewModel {
private final MutableLiveData<Item> selected = new MutableLiveData<Item>();
public void select(Item item) {
selected.setValue(item);
}
public LiveData<Item> getSelected() {
return selected;
}
}
然后,源片段是我们要从中发送数据的MasterFragment.java
。
public class MasterFragment extends Fragment {
private SharedViewModel model;
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
itemSelector.setOnClickListener(item -> {
// Data is sent
model.select(item);
});
}
}
最后,目标片段是我们要接收数据的DetailFragment.java
。
public class DetailFragment extends Fragment {
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
SharedViewModel model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
model.getSelected().observe(getViewLifecycleOwner(), { item ->
// Data is received
});
}
}
答案 15 :(得分:0)
好了,在这里进行了很多挖掘之后,我找到了一个简单的解决方案,实际上您永远不应该将数据从片段传递到片段,这总是一个坏主意,您可以将数据从片段A传递到活动,并从片段B的活动获取数据
For Example
//fragment A
//your method that will be called in Main Activity for getting data from this fragment
public List<customDataModel> getlist(){
return mlist; //your custom list
}
buttonopen.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//before calling your new fragment, send a Broadcast signal to your main activity
mContext.sendBroadcast(new Intent("call.myfragment.action"));
//here you are now changing the fragment
Fragment fragment1 = new VolunteerListDetailsFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, fragment1);
ft.commit();
}
});
//在主要活动中
this.registerReceiver(mBroadcastReceiver, new IntentFilter("call.myfragment.action"));//this line should be in your onCreate method
BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//init the fragment A
FragmenA fragment =
(FragmentA) getSupportFragmentManager().findFragmentById(R.id.content_frame);
mlistdetails = fragment.getlist();//this is my method in fragmentA which is retuning me a custom list, init this list type in top of on create fragment
}
};
//here you are creating method that is returning the list that you just recieved From fragmentA
public List<customDataModel> getcustomlist(){
return mlistdetails; //you are returning the same list that you recived from fragmentA
}
//现在在FragmentB
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = (View) inflater.inflate(R.layout.vol_listdetails, container, false);
mlistdetails=((MainActivity)getActivity()).getcustomlist();//here you are calling the method that you have created in Main Activity
Toast.makeText(getActivity().getApplicationContext(), mlistdetails.get(0).getItemqty(), Toast.LENGTH_SHORT).show();
return rootView;
}
答案 16 :(得分:0)
您可以使用多种方法来实现相同的目的:
一种是在您的父 Activity 中实现一个接口,以便 fragment1 可以通过调用这些接口方法将信息传递给其父 Activity。同样,您可以通过 fragment2 实现一个接口,以便父 Activity 可以向 fragment2 发送数据。
另一种更简单的方法是直接在彼此之间调用方法。您可以从 fragment1 使用框架 API 获取其父活动,然后通过在父活动中定义辅助方法,您可以直接从 fragment1 调用该方法并将您的信息传递给父活动。同样,在父活动中,您可以使用框架 API 来获取对其任何子片段的引用,在您的情况下是 fragment2。然后您可以在 fragment2 中定义您自己的辅助方法,以便您可以从父活动调用相同的方法并将信息传递给 fragment2。
答案 17 :(得分:-2)
我为像我这样的初学者做了一些非常轻松的事情。 我在我的activity_main.xml中创建了一个textview并放入
id=index
visibility=invisible
然后我从第一个片段
获得这个textviewindex= (Textview) getActivity().findviewbyid(R.id.index)
index.setText("fill me with the value")
然后在第二个片段中得到值
index= (Textview) getActivity().findviewbyid(R.id.index)
String get_the_value= index.getText().toString();
希望它有所帮助!