프래그먼트간에 값을 전달하는 방법
저는 Fragments를 처음 사용합니다.
Fragments를 사용하는 간단한 샘플 애플리케이션을 빌드하려고합니다. 내 시나리오는 각 활동 내에 하나의 조각이있는 두 개의 활동이 있습니다. 첫 번째 조각에는 편집 텍스트와 버튼이 있습니다. 두 번째 조각에는 텍스트보기가 있습니다. 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의 번들에서 Fragment_2.Java로 값을 어떻게 가져 옵니까?
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 단계. Activity에서 다음과 같은 인 텐트를 사용하여 데이터를 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);
}
개발자 사이트에서 언급 한대로
예를 들어 사용자 이벤트를 기반으로 콘텐츠를 변경하기 위해 종종 하나의 Fragment가 다른 Fragment와 통신하기를 원할 것입니다. 모든 Fragment-to-Fragment 통신은 관련 활동을 통해 이루어집니다. 두 조각은 직접 통신해서는 안됩니다.
프래그먼트 간의 통신은 연관된 활동을 통해 수행되어야합니다.
다음 구성 요소가 있습니다.
활동 은 조각을 호스팅하고 조각 통신을 허용합니다.
Fragment 데이터를 보낼 첫 번째 조각
FragmentA 에서 데이터를 수신 할 FragmentB 두 번째 조각
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));
}
}
}
도움이 되었으면합니다 ..
// 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.
}
도움이 되었기를 바랍니다.
에서 개발자 웹 사이트 :
예를 들어 사용자 이벤트를 기반으로 콘텐츠를 변경하기 위해 종종 하나의 Fragment가 다른 Fragment와 통신하기를 원할 것입니다. 모든 Fragment-to-Fragment 통신은 관련 활동을 통해 이루어집니다. 두 조각은 직접 통신해서는 안됩니다.
활동의 도움으로 조각간에 통신 할 수 있습니다. 이 접근 방식을 사용하여 활동과 조각간에 통신 할 수 있습니다 .
이 링크도 확인하십시오 .
먼저 모든 대답이 맞습니다 Intent
. 을 사용하여 사용자 지정 개체를 제외한 데이터를 전달할 수 있습니다 . 사용자 지정 개체를 전달하려면 Serialazable
또는 Parcelable
사용자 지정 개체 클래스 를 구현 해야합니다. 너무 복잡하다고 생각했는데 ...
따라서 프로젝트가 간단하다면 DataCache
. 그것은 데이터를 전달하는 매우 간단한 방법을 제공합니다. 참고 : Github 프로젝트 CachePot
1- 데이터를 보낼보기 또는 활동 또는 조각으로 설정합니다.
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
조각 간 데이터 전달을위한 최신 솔루션은 ViewModel 및 LiveData와 같은 Android 아키텍처 구성 요소를 사용하여 구현할 수 있습니다. 이 솔루션을 사용하면 통신을위한 인터페이스를 정의 할 필요가 없으며 구성 변경으로 인한 데이터 생존과 같은 뷰 모델을 사용하는 이점을 얻을 수 있습니다.
이 솔루션에서 통신에 관련된 프래그먼트는 활동 라이프 사이클에 연결된 동일한 viewmodel 객체를 공유합니다. 보기 모델 개체에는 livedata 개체가 포함됩니다. 하나의 프래그먼트는 라이브 데이터 객체에 전달할 데이터를 설정하고 두 번째 프래그먼트 옵저버는 라이브 데이터를 변경하고 데이터를 수신합니다.
다음은 완전한 예입니다. http://www.zoftino.com/passing-data-between-android-fragments-using-viewmodel
프래그먼트 간의 통신은 상당히 복잡합니다 (리스너 개념을 구현하기가 약간 어렵습니다).
이러한 통신을 추상화하기 위해 '이벤트 버스'를 사용하는 것이 일반적입니다.이 통신을 처리하는 타사 라이브러리입니다.
'Otto'는이 작업을 수행하는 데 자주 사용되며 살펴볼 가치가 있습니다. http://square.github.io/otto/
조각 간 인수 전달. 이 질문에 답하기에는 상당히 늦었지만 누군가를 도울 수 있습니다!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");
}
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();
두 번째 조각에서
@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 } }
이 문제를 해결하는 좋은 방법은 사용자 정의 인터페이스를 사용하는 것입니다.
동일한 활동 내에있는 두 개의 조각 (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
}
});
}
}
이 간단한 구현은 간단한 방법으로 조각간에 데이터를 전달하는 데 도움이됩니다. 'Frgment1'에서 'Fragment2'로 데이터를 전달하고 싶다고 생각하십시오.
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 메서드 (매개 변수 가져 오기)에서
String value = this.getArguments().getString("key");//get your parameters
Toast.makeText(getActivity(), value+" ", Toast.LENGTH_LONG).show();//show data in tost
나는 나 같은 초보자를 위해 정말 쉬운 것을 만들었다. 나는 내 activity_main.xml에 textview를 만들고
id=index
visibility=invisible
그런 다음 첫 번째 조각 에서이 textview를 얻습니다.
index= (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();
도움이 되길 바랍니다!
참고 URL : https://stackoverflow.com/questions/16036572/how-to-pass-values-between-fragments
'Programing' 카테고리의 다른 글
SublimeText는 줄을 흰색 직사각형으로 묶습니다. (0) | 2020.08.15 |
---|---|
dict에서 빈 문자열이있는 키를 효율적으로 제거하는 방법 (0) | 2020.08.15 |
목록에서 중복 식별 (0) | 2020.08.15 |
수평으로 UICollectionView 셀을 중앙에 배치하는 방법은 무엇입니까? (0) | 2020.08.15 |
간단한 설명 PHP OOP 대 절차? (0) | 2020.08.15 |