답변:
활동에서 다음과 같은 의도로 데이터를 보냅니다.
Bundle bundle = new Bundle();
bundle.putString("edttext", "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("edttext");
return inflater.inflate(R.layout.fragment, container, false);
}
getArguments().getString(key)
또한 조각에서 활동 데이터에 액세스 할 수 있습니다.
활동:
public class MyActivity extends Activity {
private String myString = "hello";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
...
}
public String getMyData() {
return myString;
}
}
파편:
public class MyFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
MyActivity activity = (MyActivity) getActivity();
String myDataFromActivity = activity.getMyData();
return view;
}
}
Bundle
클래스를 사용하여 정보를 전달 하는 것이 좋습니다 . 또는 해당 getMyData()
메소드를 인터페이스에서 상속 및 구현하고 Fragment
getActivity가 instanceof
에서 인터페이스를 리턴하는지 여부를 확인할 수 onAttach()
있습니다.
@ stackoverflow.com에서 많은 답변을 찾았지만 분명히 다음과 같은 정답입니다.
활동:
Bundle bundle = new Bundle();
String myMessage = "Stackoverflow is cool!";
bundle.putString("message", myMessage );
FragmentClass fragInfo = new FragmentClass();
fragInfo.setArguments(bundle);
transaction.replace(R.id.fragment_single, fragInfo);
transaction.commit();
파편:
프래그먼트의 값 읽기
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Bundle bundle = this.getArguments();
String myValue = bundle.getString("message");
...
...
...
}
아니면 그냥
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
String myValue = this.getArguments().getString("message");
...
...
...
}
이 답변은 너무 늦을 수 있습니다. 그러나 미래의 독자들에게는 유용 할 것입니다.
몇 가지 기준이 있습니다. 의도에서 파일을 선택하도록 코딩했습니다. 추가 프로세스를 위해 특정 파일로 전달 될 선택된 파일. 파일 선택 기능을 가진 많은 조각이 있습니다. 당시에는 조건을 확인하고 조각을 가져 와서 값을 전달할 때마다 매우 역겨운 것입니다. 그래서 인터페이스를 사용하여 값을 전달하기로 결정했습니다.
1 단계 : 기본 활동에서 인터페이스를 작성하십시오.
public interface SelectedBundle {
void onBundleSelect(Bundle bundle);
}
2 단계 : 동일한 활동에서 SelectedBundle 참조 작성
SelectedBundle selectedBundle;
3 단계 : 동일한 활동에서 분석법 생성
public void setOnBundleSelected(SelectedBundle selectedBundle) {
this.selectedBundle = selectedBundle;
}
4 단계 : 모든 조각에 파일 선택기 기능이 필요한 SelectedBundle 참조를 초기화해야합니다.이 코드를 조각 onCreateView(..)
방법 에 배치합니다.
((MainActivity)getActivity()).setOnBundleSelected(new MainActivity.SelectedBundle() {
@Override
public void onBundleSelect(Bundle bundle) {
updateList(bundle);
}
});
5 단계 : 제 경우에는 HomeActivity에서 Uri 이미지를 조각으로 전달해야합니다. 그래서 onActivityResult 메소드 에서이 기능을 사용했습니다.
MainActivity의 onActivityResult에서 인터페이스를 사용하여 조각에 값을 전달하십시오.
참고 : 귀하의 사례는 다를 수 있습니다. HomeActivity의 어느 곳에서나 전화 할 수 있습니다.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
selectedBundle.onBundleSelect(bundle);
}
그게 다야. FragmentClass에 필요한 모든 조각을 구현하십시오. 당신은 위대합니다. 당신은 해냈습니다. 와...
Fragments (F) 사용의 기본 아이디어는 Android 애플리케이션에서 재사용 가능한 자체 유지 UI 구성 요소를 작성하는 것입니다. 이 조각은 활동에 포함되어 있으며 A-> F 및 FA에서 통신 경로를 만드는 일반적인 (최상의) 방법이 있습니다. 조각을 분리하고 자체 유지하기 때문에 활동을 통해 FF간에 통신해야합니다.
따라서 A-> F에서 데이터를 전달하는 것은 ρяσѕρєя K의 설명과 동일합니다.이 답변 외에도 액티비티 내에서 조각을 만든 후 조각에서 메서드를 호출하는 조각으로 데이터를 전달할 수도 있습니다.
예를 들면 다음과 같습니다.
ArticleFragment articleFrag = (ArticleFragment)
getSupportFragmentManager().findFragmentById(R.id.article_fragment);
articleFrag.updateArticleView(position);
가장 편리하고 편리한 방법은 조각 인스턴스를 호출하고 그 당시에 데이터를 보내는 것입니다. 기본적으로 모든 조각에는 인스턴스 메소드가 있습니다.
예를 들어, 조각 이름이 MyFragment 인 경우
따라서 다음과 같이 활동에서 조각을 호출합니다.
getSupportFragmentManager().beginTransaction().add(R.id.container, MyFragment.newInstance("data1","data2"),"MyFragment").commit();
* R.id.container는 내 FrameLayout의 ID입니다.
따라서 MyFragment.newInstance ( "data1", "data2") 에서 조각으로 데이터를 보낼 수 있으며 조각에서이 데이터를 MyFragment newInstance (String param1, String param2)로 가져옵니다.
public static MyFragment newInstance(String param1, String param2) {
MyFragment fragment = new MyFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
그런 다음 조각의 onCreate 메소드에서 데이터를 얻습니다.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
이제 mParam1에 data1이 있고 mParam2에 data2가 있습니다.
이제이 mParam1 및 mParam2 를 조각에 사용할 수 있습니다 .
초보자를 위해 여기에 가장 많이 찬성 된 두 답변의 차이점이 조각의 다른 사용에 의해 제공된다는 것을 추가하고 싶습니다.
전달하려는 데이터가있는 Java 클래스 내에서 조각을 사용하는 경우 첫 번째 응답을 적용하여 데이터를 전달할 수 있습니다.
Bundle bundle = new Bundle();
bundle.putString("edttext", "From Activity");
Fragmentclass fragobj = new Fragmentclass();
fragobj.setArguments(bundle);
그러나 예를 들어 탭 조각에 Android Studio에서 제공 한 기본 코드를 사용하면이 코드가 작동하지 않습니다.
기본 PlaceholderFragment를 FragmentClasses로 바꾸거나 FragmentPagerAdapter를 새 상황으로 수정하더라도 getItem () 용 스위치와 getPageTitle () 용 스위치를 추가하면 ( 여기에 표시됨) 작동하지 않습니다.
경고 : 위에서 언급 한 클립에는 코드 오류가 있으므로 나중에 설명하지만 탭 조각의 기본 코드에서 편집 가능한 코드로 이동하는 방법을 보는 데 유용합니다! 그 클립의 Java 클래스와 xml 파일 (초보 시나리오에서 탭 조각을 처음 사용하는 경우)을 고려하면 나머지 답변이 훨씬 더 합리적입니다.
이 페이지에서 가장 많이 대답 한 답변이 효과가없는 주된 이유는 탭 조각의 기본 코드에서 조각이 다른 Java 클래스 인 FragmentPagerAdapter에서 사용되기 때문입니다.
따라서 데이터를 보내려면 MotherActivity에서 번들을 생성하고 응답 번호 2를 사용하여 FragmentPagerAdapter에 전달해야합니다.
그게 또 잘못이야 ( 아마도 그렇게 할 수는 있지만 실제로는 필요하지 않은 합병증 일뿐입니다 ).
정확하고 쉬운 방법은 대답 2 번을 사용하여 문제의 조각으로 데이터를 직접 전달하는 것입니다. 예, 탭 조각에 대해서는 액티비티와 조각 (단편) 사이에 긴밀한 연결이있을 것입니다. MotherActivity java 클래스 내부에서 탭 조각을 만들도록 조언 할 것입니다 (하위 클래스는 MotherActivity 외부에서 사용되지 않으므로). 필요한 경우 MotherActivity Java 클래스 내부에 많은 조각을 추가하는 것이 쉽습니다.
public static class Tab1 extends Fragment {
public Tab1() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.your_layout_name_for_fragment_1, container, false);
return rootView;
}
}.
따라서 MotherActivity에서 이러한 조각으로 데이터를 전달하려면 onCreate Mother 활동 위에 개인 문자열 / 번들을 생성해야합니다. 조각에 전달할 데이터를 채우고이를 통해 전달할 수 있습니다. onCreate 이후에 생성 된 메소드 (여기서는 getMyData ()라고 함)
public class MotherActivity extends Activity {
private String out;
private Bundle results;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mother_activity);
// for example get a value from the previous activity
Intent intent = getIntent();
out = intent.getExtras().getString("Key");
}
public Bundle getMyData() {
Bundle hm = new Bundle();
hm.putString("val1",out);
return hm;
}
}
그런 다음 프래그먼트 클래스에서 getMyData를 사용합니다.
public static class Tab1 extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
public Tab1() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.your_layout_name_for_fragment_1, container, false);
TextView output = (TextView)rootView.findViewById(R.id.your_id_for_a_text_view_within_the_layout);
MotherActivity activity = (MotherActivity)getActivity();
Bundle results = activity.getMyData();
String value1 = results.getString("val1");
output.setText(value1);
return rootView;
}
}
데이터베이스 쿼리가있는 경우 탭 조각 내에서와 같이 MotherActivity에서 쿼리를 수행하고 (위 그림과 같이 번들 내부의 키에 연결된 문자열 / 정수로 결과를 전달) 조언을 구하십시오. 구문이 더 복잡해집니다 (이는 getActivity가됩니다) 예를 들어, getIntent는 getActivity (). getIntent)가되지만 원하는대로 수행 할 수도 있습니다.
초보자를위한 조언은 작은 단계에 초점을 맞추는 것입니다. 먼저, 모든 데이터를 전달하지 않고 매우 간단한 탭 활동을 열도록하십시오. 작동합니까? 원하는 탭이 열립니까? 그렇지 않다면 왜?
그것부터 시작 하고이 클립에 제시된 것과 같은 솔루션을 적용하여 무엇이 빠졌는지보십시오. 특정 클립의 경우 mainactivity.xml이 표시되지 않습니다. 그것은 당신을 혼란스럽게 할 것입니다. 그러나주의를 기울이면 예를 들어 xml 조각 파일의 컨텍스트 (tools : context)가 잘못되었음을 알 수 있습니다. 각 조각 XML은 올바른 조각 클래스 (또는 구분 기호 $를 사용하는 하위 클래스)를 가리켜 야합니다.
또한 주요 활동 java 클래스에서 tabLayout.setupWithViewPager (mViewPager)-TabLayout tabLayout = (TabLayout) findViewById (R.id.tabs) 행 바로 뒤에 tabLayout.setupWithViewPager (mViewPager)를 추가해야 함을 알 수 있습니다. 이 줄이 없으면 뷰는 실제로 조각의 XML 파일에 연결되지 않지만 주 활동의 xml 파일 만 표시합니다.
기본 활동 Java 클래스의 행 외에도 기본 활동 XML 파일에서 상황에 맞게 탭을 변경해야합니다 (예 : TabItems 추가 또는 제거). 기본 활동 XML에 탭이없는 경우 처음에 새 활동-탭 활동을 작성할 때 올바른 활동 유형을 선택하지 않았을 수 있습니다.
마지막 3 단락에서 비디오에 대해 이야기합니다! 따라서 주요 활동 XML이라고 말하면 비디오의 주요 활동 XML이며, 현재 상황에서는 MotherActivity XML 파일입니다.
비동기 태스크에 (콘크리트 서브 클래스) 프래그먼트에 대한 참조를 전달하면 프래그먼트에 직접 액세스 할 수 있습니다.
조각 참조를 비동기 작업으로 전달하는 몇 가지 방법 :
class FooTask extends AsyncTask
) 인 경우 조각을 생성자에 전달하십시오.때때로 당신은 당신의 활동에서 의도를받을 수 있으며 작업 조각에 정보를 전달해야합니다.
조각을 시작해야하지만 여전히 작동하는 경우 대답이 괜찮습니다 setArguments()
. 매우 유용하지 않습니다.
전달 된 정보가 UI와 상호 작용하게되면 다른 문제가 발생합니다. 이 경우 myfragment.passData()
안드로이드는 뷰를 만든 스레드 만 상호 작용할 수 있다고 신속하게 알려주기 때문에 호출 할 수 없습니다 .
그래서 제 제안은 수신기를 사용하는 것입니다. 이렇게하면 활동을 포함하여 어디에서나 데이터를 보낼 수 있지만 작업은 프래그먼트 컨텍스트 내에서 수행됩니다.
당신의 단편에서 onCreate()
:
protected DataReceiver dataReceiver;
public static final String REC_DATA = "REC_DATA";
@Override
public void onCreate(Bundle savedInstanceState) {
data Receiver = new DataReceiver();
intentFilter = new IntentFilter(REC_DATA);
getActivity().registerReceiver(dataReceiver, intentFilter);
}
private class DataReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
int data= intent.getIntExtra("data", -1);
// Do anything including interact with your UI
}
}
당신의 활동에서 :
// somewhere
Intent retIntent = new Intent(RE_DATA);
retIntent.putExtra("data", myData);
sendBroadcast(retIntent);
아주 오래된 게시물이지만 여전히 도움이 될만한 작은 설명을 추가 할 수 있습니다.
기술적으로 활동의 조각에서 모든 유형의 구성원을 직접 설정할 수 있습니다.
왜 번들?
그 이유는 매우 간단합니다. 번들은 균일 한 처리 방법을 제공합니다 :
-조각 생성 / 열기
-재구성 (화면 회전) – onSaveInstanceState ()에서 outState에 초기 / 업데이트 된 번들 추가
-백그라운드에서 가비지 수집 후 앱 복원 ( 재구성과 마찬가지로).
간단한 상황에서 (실험을 좋아하는 경우) 해결 방법을 만들 수 있지만 번들 접근 방식은 백 스택에서 하나의 조각과 1000 사이의 차이를 보지 못합니다. 간단하고 간단합니다. @Elenasys
의 답변 이 가장 우아하고 보편적 인 솔루션 인 이유 입니다. 에 의해 주어진 답 이유입니다 @Martin이 이 함정을
활동 클래스에서 프래그먼트로 데이터를 전송하는 더 좋은 방법은 setter 메소드를 통해 전달하는 것입니다. 처럼
FragmentClass fragmentClass = new FragmentClass();
fragmentClass.setMyList(mylist);
fragmentClass.setMyString(myString);
fragmentClass.setMyMap(myMap);
수업에서 이러한 데이터를 쉽게 얻을 수 있습니다.
에서 Activity
당신은 번들로 데이터를 전송 :
Bundle bundle = new Bundle();
bundle.putString("data", "Data you want to send");
// Your fragment
MyFragment obj = new MyFragment();
obj.setArguments(bundle);
그리고 Fragment
onCreateView 메소드에서 데이터를 가져옵니다.
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
String data = getArguments().getString("data");// data which sent from activity
return inflater.inflate(R.layout.myfragment, container, false);
}
초기화 후 조치를 수행 activity
해야하는 경우 fragment
가장 쉬운 방법은 인스턴스 activity
에서 메소드를 호출하는 것입니다 fragment
. 에서 fragment
, 방법을 추가 :
public class DemoFragment extends Fragment {
public void doSomething(String param) {
// do something in fragment
}
}
그런 다음에서 관리자를 사용하여 activity
액세스 하고 다음을 호출하십시오 .fragment
fragment
method
public class MainActivity extends FragmentActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DemoFragment fragmentDemo = (DemoFragment)
getSupportFragmentManager().findFragmentById(R.id.fragmentDemo);
fragmentDemo.doSomething("some param");
}
}
그리고 이것을 호출 activity
하여와 직접 통신 할 수 있습니다 .fragment
method
onCreateView
조각에서 메소드에 들어가고 싶지 않다는 점에서 정말 좋습니다 . 정말 도움이되었습니다
다음 인터페이스를 사용하여 활동과 조각 간 통신
public interface BundleListener {
void update(Bundle bundle);
Bundle getBundle();
}
또는 인터페이스를 사용한 양방향 통신을 위해이 일반 리스너를 따르십시오.
/**
* Created by Qamar4P on 10/11/2017.
*/
public interface GenericConnector<T,E> {
T getData();
void updateData(E data);
void connect(GenericConnector<T,E> connector);
}
조각 쇼 방법
public static void show(AppCompatActivity activity) {
CustomValueDialogFragment dialog = new CustomValueDialogFragment();
dialog.connector = (GenericConnector) activity;
dialog.show(activity.getSupportFragmentManager(),"CustomValueDialogFragment");
}
당신은 당신의 상황을 캐스트 할 수 있습니다 GenericConnector
에 onAttach(Context)
너무
당신의 활동에서
CustomValueDialogFragment.show(this);
당신의 조각에
...
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
connector.connect(new GenericConnector() {
@Override
public Object getData() {
return null;
}
@Override
public void updateData(Object data) {
}
@Override
public void connect(GenericConnector connector) {
}
});
}
...
public static void show(AppCompatActivity activity, GenericConnector connector) {
CustomValueDialogFragment dialog = new CustomValueDialogFragment();
dialog.connector = connector;
dialog.show(activity.getSupportFragmentManager(),"CustomValueDialogFragment");
}
참고 : 절대로 그렇게 사용하지 마십시오 "".toString().toString().toString();
.
위의 방법 중 대부분이 작동하는 동안이 질문을 우연히 발견했습니다. 이벤트 버스 라이브러리를 사용할 수 있다고 덧붙이고 싶습니다 . 특히 구성 요소 (활동 또는 조각)가 생성되지 않은 시나리오에서 모든 크기의 안드로이드 프로젝트와 많은 유스 케이스에 적합합니다. 나는 플레이 스토어에있는 여러 프로젝트에서 개인적으로 사용했습니다.
프래그먼트와 활동간에 데이터를 전달하는 가장 현명하고 시도 된 방법은 변수를 만드는 것입니다. 예 :
class StorageUtil {
public static ArrayList<Employee> employees;
}
그런 다음 조각에서 활동으로 데이터를 전달하기 위해 onActivityCreated 메소드에서 수행합니다.
//a field created in the sending fragment
ArrayList<Employee> employees;
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
employees=new ArrayList();
//java 7 and above syntax for arraylist else use employees=new ArrayList<Employee>() for java 6 and below
//Adding first employee
Employee employee=new Employee("1","Andrew","Sam","1984-04-10","Male","Ghanaian");
employees.add(employee);
//Adding second employee
Employee employee=new Employee("1","Akuah","Morrison","1984-02-04","Female","Ghanaian");
employees.add(employee);
StorageUtil.employees=employees;
}
이제 어디서나 StorageUtil.employees의 가치를 얻을 수 있습니다. 행운을 빕니다!
내 솔루션은 조각 안에 정적 메서드를 작성하는 것입니다.
public TheFragment setData(TheData data) {
TheFragment tf = new TheFragment();
tf.data = data;
return tf;
}
이렇게하면 필요한 모든 데이터가 조각 내부에 있어야 다른 가능한 작업을 수행 할 수 있습니다. 또한 내 의견으로는 더 깨끗해 보입니다.
최신 탐색 아키텍처 구성 요소를 사용하는 동안 비슷한 문제가 발생했습니다. 내 호출 활동에서 Fragment로 번들을 전달하여 위에서 언급 한 모든 코드를 시도했습니다.
Android의 최신 개발 동향에 따른 최상의 솔루션은 View Model (Android Jetpack의 일부)을 사용하는 것입니다.
상위 활동에서 ViewModel 클래스를 작성하고 초기화하십시오.이 ViewModel은 활동과 프래그먼트간에 공유되어야합니다.
이제 조각의 onViewCreated () 내부에서 동일한 ViewModel을 초기화하고 관찰자를 설정하여 ViewModel 필드를 수신하십시오.
필요한 경우 도움이되는 심층적 인 자습서가 있습니다.
활동에서 정적 변수를 선언하십시오.
public static HashMap<String,ContactsModal> contactItems=new HashMap<String, ContactsModal>();
그런 다음 조각에서 다음과 같이하십시오.
ActivityName.contactItems.put(Number,contactsModal);