저는 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
답변
조각 간 인수 전달.
이 질문에 답하기에는 상당히 늦었지만 누군가를 도울 수 있습니다!
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");
}