조각간에 데이터를 전달하는 방법
내 프로그램에서 두 개의 fragmen간에 데이터를 전달하려고합니다. List에 저장되는 단순한 문자열입니다. 목록은 조각 A에서 공개되며 사용자가 목록 항목을 클릭하면 조각 B에 표시되어야합니다. 콘텐츠 제공자는 ID 만 지원하는 것 같아서 작동하지 않습니다. 어떤 제안?
프래그먼트 간의 통신은 활동을 통해 이루어져야한다고 생각합니다. 프래그먼트와 액티비티 간의 통신은 https://developer.android.com/training/basics/fragments/communicating.html https://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity와 같은 방법으로 수행 할 수 있습니다.
Roboguice를 사용하는 경우 Roboguice의 EventManager를 사용하여 Activity를 인터페이스로 사용하지 않고도 데이터를 전달할 수 있습니다. 이것은 아주 깨끗한 IMO입니다.
Roboguice를 사용하지 않는 경우 Otto도 이벤트 버스로 사용할 수 있습니다. http://square.github.com/otto/
업데이트 20150909 : 이제 Green Robot Event Bus 또는 RxJava도 사용할 수 있습니다. 사용 사례에 따라 다릅니다.
번들을 사용하지 않으시겠습니까? 첫 번째 조각에서 설정하는 방법은 다음과 같습니다.
Fragment fragment = new Fragment();
Bundle bundle = new Bundle();
bundle.putInt(key, value);
fragment.setArguments(bundle);
그런 다음 두 번째 Fragment에서 다음을 사용하여 데이터를 검색합니다.
Bundle bundle = this.getArguments();
int myInt = bundle.getInt(key, defaultValue);
번들에는 많은 데이터 유형에 대한 put 메소드가 있습니다. http://developer.android.com/reference/android/os/Bundle.html을 참조 하십시오.
로부터 Fragment
문서 :
예를 들어 사용자 이벤트를 기반으로 콘텐츠를 변경하기 위해 종종 한 조각이 다른 조각과 통신하기를 원할 것입니다. 모든 Fragment-to-Fragment 통신은 관련 활동을 통해 이루어집니다. 두 조각은 직접 통신해서는 안됩니다.
그래서 나는 당신이 문서 에서 기본적인 조각 훈련 문서 를 보길 제안합니다 . 예제와 둘러보기 가이드로 꽤 포괄적입니다.
따라서 Frag A와 Fragment B를 제어하는 Activity AB가 있다고 가정 해 보겠습니다. Fragment A 내부에는 Activity AB가 구현할 수있는 인터페이스가 필요합니다. 샘플 Android 코드에는 다음이 있습니다.
private Callbacks mCallbacks = sDummyCallbacks;
/ *이 조각을 포함하는 모든 활동이 구현해야하는 콜백 인터페이스. 이 메커니즘을 사용하면 활동에 항목 선택을 알릴 수 있습니다. * /
public interface Callbacks {
/*Callback for when an item has been selected. */
public void onItemSelected(String id);
}
/*A dummy implementation of the {@link Callbacks} interface that does nothing. Used only when this fragment is not attached to an activity. */
private static Callbacks sDummyCallbacks = new Callbacks() {
@Override
public void onItemSelected(String id) {
}
};
콜백 인터페이스는 프래그먼트 중 하나에 배치됩니다 (Fragment A라고 가정 해 보겠습니다). 이 콜백 인터페이스의 목적은 모든 활동이 구현할 수있는 Frag A 내부의 중첩 클래스와 같다고 생각합니다. 따라서 Fragment A가 TV 인 경우 CallBack은 Fragment A를 Activity AB에서 사용할 수 있도록하는 TV 리모컨 (인터페이스)입니다. 나는 멍청한 사람이기 때문에 세부 사항에 대해 틀릴 수 있지만 프로그램이 모든 화면 크기에서 완벽하게 작동하도록 만들었으며 이것이 내가 사용한 것입니다.
따라서 Fragment A 내부에는 다음이 있습니다. (Android의 샘플 프로그램에서 가져 왔습니다.)
@Override
public void onListItemClick(ListView listView, View view, int position, long id) {
super.onListItemClick(listView, view, position, id);
// Notify the active callbacks interface (the activity, if the
// fragment is attached to one) that an item has been selected.
mCallbacks.onItemSelected(DummyContent.ITEMS.get(position).id);
//mCallbacks.onItemSelected( PUT YOUR SHIT HERE. int, String, etc.);
//mCallbacks.onItemSelected (Object);
}
그리고 Activity AB 내에서 onItemSelected 메서드를 재정의합니다.
public class AB extends FragmentActivity implements ItemListFragment.Callbacks {
//...
@Override
//public void onItemSelected (CATCH YOUR SHIT HERE) {
//public void onItemSelected (Object obj) {
public void onItemSelected(String id) {
//Pass Data to Fragment B. For example:
Bundle arguments = new Bundle();
arguments.putString(“FragmentB_package”, id);
FragmentB fragment = new FragmentB();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction().replace(R.id.item_detail_container, fragment).commit();
}
따라서 Activity AB 내에서 기본적으로 모든 것을 Bundle에 넣고 B에 전달합니다. Bundle을 사용하는 방법을 잘 모르는 경우 클래스를 찾아보십시오.
기본적으로 Android가 제공 한 샘플 코드를 사용합니다. DummyContent 물건이있는 사람. 새로운 Android 애플리케이션 패키지를 만들면 MasterDetailFlow라는 제목의 패키지입니다.
1- 첫 번째 방법은 인터페이스를 정의하는 것입니다.
public interface OnMessage{
void sendMessage(int fragmentId, String message);
}
public interface OnReceive{
void onReceive(String message);
}
2- 활동에서 OnMessage 인터페이스 구현
public class MyActivity implements OnMessage {
...
@Override
public void sendMessage(int fragmentId, String message){
Fragment fragment = getSupportFragmentManager().findFragmentById(fragmentId);
((OnReceive) fragment).sendMessage();
}
}
3- 조각에서 OnReceive 인터페이스 구현
public class MyFragment implements OnReceive{
...
@Override
public void onReceive(String message){
myTextView.setText("Received message:" + message);
}
}
이것은 프래그먼트 간 메시지 전달을 처리하는 표준 버전입니다.
프래그먼트 간의 데이터 전달을 처리하는 또 다른 방법은 이벤트 버스를 사용하는 것입니다.
1- 이벤트 버스에 등록 / 등록 취소
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
EventBus.getDefault().unregister(this);
super.onStop();
}
2- 이벤트 클래스 정의
public class Message{
public final String message;
public Message(String message){
this.message = message;
}
}
3- 애플리케이션의 어느 곳에 나이 이벤트를 게시하십시오.
EventBus.getDefault().post(new Message("hello world"));
4- 해당 이벤트를 구독하여 조각으로 받으십시오.
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessage(Message event){
mytextview.setText(event.message);
}
자세한 내용, 사용 사례 및 이벤트 버스 패턴에 대한 예제 프로젝트 .
제 경우에는 FragmentB-> FragmentA에서 데이터를 거꾸로 보내야 했으므로 조각이 이미 초기화되었으므로 Intents는 옵션이 아니 었 습니다. 위의 모든 답변이 좋게 들리지만 구현 하는 데 많은 보일러 플레이트 코드가 필요 하므로 LocalBroadcastManager 를 사용 하는 훨씬 더 간단한 접근 방식 을 사용 했습니다. 위에서 말한대로 정확히 수행하지만 불쾌한 상용구 코드가 없습니다. 아래에 예가 나와 있습니다.
조각을 보내는 중 (조각 B)
public class FragmentB {
private void sendMessage() {
Intent intent = new Intent("custom-event-name");
intent.putExtra("message", "your message");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
}
수신 할 메시지 조각 (FRAGMENT A)
public class FragmentA {
@Override
public void onCreate(Bundle savedInstanceState) {
...
// Register receiver
LocalBroadcastManager.getInstance(this).registerReceiver(receiver,
new IntentFilter("custom-event-name"));
}
// This will be called whenever an Intent with an action named "custom-event-name" is broadcasted.
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String message = intent.getStringExtra("message");
}
};
}
누군가에게 도움이되기를 바랍니다.
그것은 조각의 구조에 달려 있습니다. Fragment Class B 정적 및 대상 TextView 객체 정적에 대한 일부 메서드를 가질 수있는 경우 Fragment Class A에서 직접 메서드를 호출 할 수 있습니다. 메서드가 즉시 수행되므로 리스너보다 낫습니다. 활동 전반에 걸쳐 청취를 수행하는 추가 작업이 필요합니다. 아래 예를 참조하십시오.
Fragment_class_B.setmyText(String yourstring);
조각 B에서 다음과 같이 정의 된 메서드를 가질 수 있습니다.
public static void setmyText(final String string) {
myTextView.setText(string);
}
Fragment B에서 myTextView를 정적으로 설정하고 Fragment A에서 Fragment B 클래스를 올바르게 가져 오는 것을 잊지 마십시오.
최근에 내 프로젝트에서 절차를 수행했고 효과가있었습니다. 도움이 되었기를 바랍니다.
이 문서를 읽을 수 있습니다.이 개념은 http://developer.android.com/training/basics/fragments/communicating.html 여기에 잘 설명되어 있습니다.
비슷한 프로젝트를 진행 중이며 위의 상황에서 내 코드가 도움이 될 것 같습니다.
내가하는 일에 대한 개요입니다.
내 프로젝트에는 " FragmentA "및 "FragmentB " 라는 두 개의 조각이 있습니다 .
- FragmentA은 당신이 항목을 클릭 한 목록보기, 포함 FragmentA 에 전달이의 INDEX FragmentB 커뮤니케이터 인터페이스를 사용하여이
- 디자인 패턴은 " 인터페이스 참조 변수가 서브 클래스 객체를 참조 할 수 있습니다 "라는 Java 인터페이스 개념을 전적으로 기반으로 합니다.
- 하자 MainActivity가 에 의해 제공되는 인터페이스 구현 fragmentA을 (그렇지 않으면 우리는 MainActivity에 포인트 인터페이스 참조 변수를 만들 수 없습니다)
- 아래 코드에서 communicator 객체는 fragmentA에 존재 하는 " setCommunicator (Communicatot c) "메소드 를 사용하여 MainActivity의 객체 를 참조하도록 만들어졌습니다 .
MainActivity의 참조를 사용하여 FrgamentA 에서 인터페이스의 respond () 메서드를 트리거 하고 있습니다.
Interface communcator는 fragmentA 내부에 정의되어 있으며, 이는 communicator 인터페이스 에 대한 최소 액세스 권한을 제공하기위한 것 입니다.
아래는 내 완전한 작업 코드입니다.
FragmentA.java
public class FragmentA extends Fragment implements OnItemClickListener {
ListView list;
Communicator communicater;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
return inflater.inflate(R.layout.fragmenta, container,false);
}
public void setCommunicator(Communicator c){
communicater=c;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
communicater=(Communicator) getActivity();
list = (ListView) getActivity().findViewById(R.id.lvModularListView);
ArrayAdapter<?> adapter = ArrayAdapter.createFromResource(getActivity(),
R.array.items, android.R.layout.simple_list_item_1);
list.setAdapter(adapter);
list.setOnItemClickListener(this);
}
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int index, long arg3) {
communicater.respond(index);
}
public interface Communicator{
public void respond(int index);
}
}
fragmentB.java
public class FragmentA extends Fragment implements OnItemClickListener {
ListView list;
Communicator communicater;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
return inflater.inflate(R.layout.fragmenta, container,false);
}
public void setCommunicator(Communicator c){
communicater=c;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
communicater=(Communicator) getActivity();
list = (ListView) getActivity().findViewById(R.id.lvModularListView);
ArrayAdapter<?> adapter = ArrayAdapter.createFromResource(getActivity(),
R.array.items, android.R.layout.simple_list_item_1);
list.setAdapter(adapter);
list.setOnItemClickListener(this);
}
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int index, long arg3) {
communicater.respond(index);
}
public interface Communicator{
public void respond(int index);
}
}
MainActivity.java
public class MainActivity extends Activity implements FragmentA.Communicator {
FragmentManager manager=getFragmentManager();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentA fragA=(FragmentA) manager.findFragmentById(R.id.fragmenta);
fragA.setCommunicator(this);
}
@Override
public void respond(int i) {
// TODO Auto-generated method stub
FragmentB FragB=(FragmentB) manager.findFragmentById(R.id.fragmentb);
FragB.changetext(i);
}
}
기본적으로 활동과 프래그먼트 간의 통신을위한 인터페이스를 구현합니다.
1) 주요 활동
public class MainActivity extends Activity implements SendFragment.StartCommunication
{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public void setComm(String msg) {
// TODO Auto-generated method stub
DisplayFragment mDisplayFragment = (DisplayFragment)getFragmentManager().findFragmentById(R.id.fragment2);
if(mDisplayFragment != null && mDisplayFragment.isInLayout())
{
mDisplayFragment.setText(msg);
}
else
{
Toast.makeText(this, "Error Sending Message", Toast.LENGTH_SHORT).show();
}
}
}
2) 발신자 조각 (fragment-to-Activity)
public class SendFragment extends Fragment
{
StartCommunication mStartCommunicationListner;
String msg = "hi";
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View mView = (View) inflater.inflate(R.layout.send_fragment, container);
final EditText mEditText = (EditText)mView.findViewById(R.id.editText1);
Button mButton = (Button) mView.findViewById(R.id.button1);
mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
msg = mEditText.getText().toString();
sendMessage();
}
});
return mView;
}
interface StartCommunication
{
public void setComm(String msg);
}
@Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
super.onAttach(activity);
if(activity instanceof StartCommunication)
{
mStartCommunicationListner = (StartCommunication)activity;
}
else
throw new ClassCastException();
}
public void sendMessage()
{
mStartCommunicationListner.setComm(msg);
}
}
3) 수신자 조각 (Activity-to-fragment)
public class DisplayFragment extends Fragment
{
View mView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
mView = (View) inflater.inflate(R.layout.display_frgmt_layout, container);
return mView;
}
void setText(String msg)
{
TextView mTextView = (TextView) mView.findViewById(R.id.textView1);
mTextView.setText(msg);
}
}
나는이 링크를 동일한 솔루션에 사용했으며 누군가가 유용하다고 생각하기를 바랍니다. 매우 간단하고 기본적인 예입니다.
http://infobloggall.com/2014/06/22/communication-between-activity-and-fragments/
조각 클래스 A
public class CountryListFragment extends ListFragment{
/** List of countries to be displayed in the ListFragment */
ListFragmentItemClickListener ifaceItemClickListener;
/** An interface for defining the callback method */
public interface ListFragmentItemClickListener {
/** This method will be invoked when an item in the ListFragment is clicked */
void onListFragmentItemClick(int position);
}
/** A callback function, executed when this fragment is attached to an activity */
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try{
/** This statement ensures that the hosting activity implements ListFragmentItemClickListener */
ifaceItemClickListener = (ListFragmentItemClickListener) activity;
}catch(Exception e){
Toast.makeText(activity.getBaseContext(), "Exception",Toast.LENGTH_SHORT).show();
}
}
조각 클래스 B
public class CountryDetailsFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
/** Inflating the layout country_details_fragment_layout to the view object v */
View v = inflater.inflate(R.layout.country_details_fragment_layout, null);
/** Getting the textview object of the layout to set the details */
TextView tv = (TextView) v.findViewById(R.id.country_details);
/** Getting the bundle object passed from MainActivity ( in Landscape mode ) or from
* CountryDetailsActivity ( in Portrait Mode )
* */
Bundle b = getArguments();
/** Getting the clicked item's position and setting corresponding details in the textview of the detailed fragment */
tv.setText("Details of " + Country.name[b.getInt("position")]);
return v;
}
}
단편 간 데이터 전달을위한 기본 활동 클래스
public class MainActivity extends Activity implements ListFragmentItemClickListener {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
/** This method will be executed when the user clicks on an item in the listview */
@Override
public void onListFragmentItemClick(int position) {
/** Getting the orientation ( Landscape or Portrait ) of the screen */
int orientation = getResources().getConfiguration().orientation;
/** Landscape Mode */
if(orientation == Configuration.ORIENTATION_LANDSCAPE ){
/** Getting the fragment manager for fragment related operations */
FragmentManager fragmentManager = getFragmentManager();
/** Getting the fragmenttransaction object, which can be used to add, remove or replace a fragment */
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
/** Getting the existing detailed fragment object, if it already exists.
* The fragment object is retrieved by its tag name *
*/
Fragment prevFrag = fragmentManager.findFragmentByTag("in.wptrafficanalyzer.country.details");
/** Remove the existing detailed fragment object if it exists */
if(prevFrag!=null)
fragmentTransaction.remove(prevFrag);
/** Instantiating the fragment CountryDetailsFragment */
CountryDetailsFragment fragment = new CountryDetailsFragment();
/** Creating a bundle object to pass the data(the clicked item's position) from the activity to the fragment */
Bundle b = new Bundle();
/** Setting the data to the bundle object */
b.putInt("position", position);
/** Setting the bundle object to the fragment */
fragment.setArguments(b);
/** Adding the fragment to the fragment transaction */
fragmentTransaction.add(R.id.detail_fragment_container, fragment,"in.wptrafficanalyzer.country.details");
/** Adding this transaction to backstack */
fragmentTransaction.addToBackStack(null);
/** Making this transaction in effect */
fragmentTransaction.commit();
}else{ /** Portrait Mode or Square mode */
/** Creating an intent object to start the CountryDetailsActivity */
Intent intent = new Intent("in.wptrafficanalyzer.CountryDetailsActivity");
/** Setting data ( the clicked item's position ) to this intent */
intent.putExtra("position", position);
/** Starting the activity by passing the implicit intent */
startActivity(intent);
}
}
}
Detailde 활동 수업
public class CountryDetailsActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/** Setting the layout for this activity */
setContentView(R.layout.country_details_activity_layout);
/** Getting the fragment manager for fragment related operations */
FragmentManager fragmentManager = getFragmentManager();
/** Getting the fragmenttransaction object, which can be used to add, remove or replace a fragment */
FragmentTransaction fragmentTransacton = fragmentManager.beginTransaction();
/** Instantiating the fragment CountryDetailsFragment */
CountryDetailsFragment detailsFragment = new CountryDetailsFragment();
/** Creating a bundle object to pass the data(the clicked item's position) from the activity to the fragment */
Bundle b = new Bundle();
/** Setting the data to the bundle object from the Intent*/
b.putInt("position", getIntent().getIntExtra("position", 0));
/** Setting the bundle object to the fragment */
detailsFragment.setArguments(b);
/** Adding the fragment to the fragment transaction */
fragmentTransacton.add(R.id.country_details_fragment_container, detailsFragment);
/** Making this transaction in effect */
fragmentTransacton.commit();
}
}
연속 배열
public class Country {
/** Array of countries used to display in CountryListFragment */
static String name[] = new String[] {
"India",
"Pakistan",
"Sri Lanka",
"China",
"Bangladesh",
"Nepal",
"Afghanistan",
"North Korea",
"South Korea",
"Japan",
"Bhutan"
};
}
자세한 내용은이 링크 [ http://wptrafficanalyzer.in/blog/itemclick-handler-for-listfragment-in-android/]를 방문 하세요 . 전체 예가 있습니다 ..
기본적으로 여기서 우리는 Fragment 간의 통신을 다루고 있습니다. 프래그먼트 간의 통신은 절대 직접 가능하지 않습니다. 두 조각이 모두 생성되는 컨텍스트에서의 활동이 포함됩니다.
You need to create an interface in the sending fragment and implement the interface in the activity which will reprieve the message and transfer to the receiving fragment.
참고URL : https://stackoverflow.com/questions/5194548/how-to-pass-data-between-fragments
'program tip' 카테고리의 다른 글
double equals vs is in python (0) | 2020.10.24 |
---|---|
저장 프로 시저에 매개 변수 배열 전달 (0) | 2020.10.24 |
파이썬 : 줄이 빈 줄인지 확인하는 방법 (0) | 2020.10.24 |
JBoss AS 7 : tmp를 정리하는 방법? (0) | 2020.10.24 |
CALayer IOS의 자동 레이아웃 제약 (0) | 2020.10.24 |