프래그먼트와 컨테이너 활동간에 데이터를 전달하려면 어떻게해야합니까? 의도를 통해 활동간에 데이터를 전달하는 것과 비슷한 것이 있습니까?
나는 이것을 읽었지만별로 도움이되지 않았다 :
http://developer.android.com/guide/topics/fundamentals/fragments.html#CommunicatingWithActivity
프래그먼트와 컨테이너 활동간에 데이터를 전달하려면 어떻게해야합니까? 의도를 통해 활동간에 데이터를 전달하는 것과 비슷한 것이 있습니까?
나는 이것을 읽었지만별로 도움이되지 않았다 :
http://developer.android.com/guide/topics/fundamentals/fragments.html#CommunicatingWithActivity
답변:
프래그먼트에서을 호출 할 수 있습니다 getActivity()
.
그러면 프래그먼트를 생성 한 액티비티에 액세스 할 수 있습니다. 거기에서 액티비티에있는 액세서 메소드를 호출 할 수 있습니다.
예를 들어 getResult()
활동에서 호출 된 메소드의 경우 :
((MyActivity) getActivity()).getResult();
인터페이스를 사용해보십시오.
데이터를 포함하는 활동으로 다시 전달해야하는 조각은 데이터를 처리하고 전달할 인터페이스를 선언해야합니다. 그런 다음 포함 활동이 해당 인터페이스를 구현하는지 확인하십시오. 예를 들면 다음과 같습니다.
자바
조각에서 인터페이스를 선언하십시오 ...
public interface OnDataPass {
public void onDataPass(String data);
}
그런 다음 포함하는 클래스의 인터페이스 구현을 다음과 같이 onAttach 메소드의 단편에 연결하십시오.
OnDataPass dataPasser;
@Override
public void onAttach(Context context) {
super.onAttach(context);
dataPasser = (OnDataPass) context;
}
프래그먼트 내에서 데이터 전달을 처리해야 할 경우 dataPasser 객체에서 호출하십시오.
public void passData(String data) {
dataPasser.onDataPass(data);
}
마지막으로, 포함 활동 하는 구현 OnDataPass
...
@Override
public void onDataPass(String data) {
Log.d("LOG","hello " + data);
}
코 틀린
1 단계. 인터페이스 생성
interface OnDataPass {
fun onDataPass(data: String)
}
2 단계. 다음과 같이 포함 클래스의 인터페이스 구현을 onAttach 메소드 (YourFragment)의 프래그먼트에 연결하십시오.
lateinit var dataPasser: OnDataPass
override fun onAttach(context: Context) {
super.onAttach(context)
dataPasser = context as OnDataPass
}
단계 3. 프래그먼트 내에서 데이터 전달을 처리해야하는 경우 dataPasser 오브젝트에서이를 호출하십시오.
fun passData(data: String){
dataPasser.onDataPass(data)
}
4 단계. 마지막으로 활동에서 OnDataPass를 구현합니다.
class MyActivity : AppCompatActivity(), OnDataPass {}
override fun onDataPass(data: String) {
Log.d("LOG","hello " + data)
}
ActionBar.TabListener
추가 인터페이스를 추가해야했습니다.
가장 쉬운 접근 방법이지만 권장되지 않음
조각에서 활동 데이터에 액세스 할 수 있습니다.
활동:
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;
}
}
MyActivity
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Bundle b = getActivity().getIntent().getExtras();
wid = b.getString("wid");
rid = b.getString("rid");
View view = inflater.inflate(R.layout.categoryfragment, container, false);
return view;
}
프래그먼트와 컨테이너 활동간에 데이터 전달
활동:
Bundle bundle = new Bundle();
bundle.putString("message", "Alo Elena!");
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) {
String myValue = this.getArguments().getString("message");
...
...
...
}
이것이 최선의 방법인지 아닌지 모르겠습니다 .Bu에서 Google에서 상당히 오랫동안 검색 해 왔지만 번들에서 컨테이너 활동으로 번들을 전달하는 방법을 찾았지만 발견 한 모든 것은 활동에서 조각으로 데이터를 보내는 것입니다. (나는 초보자이기 때문에 약간 혼란 스러웠다).
나중에 나는 내가 원하는대로 정확하게 일한 내 자신의 것을 시도했다. 그래서 나는 같은 것을 찾고있는 사람과 같은 경우에 여기에 게시 할 것입니다.
// Fragment에서 데이터 전달
Bundle gameData = new Bundle();
gameData.putStringArrayList(Constant.KEY_PLAYERS_ARR,players);
gameData.putString(Constant.KEY_TEAM_NAME,custom_team_name);
gameData.putInt(Constant.KEY_REQUESTED_OVER,requestedOver);
Intent intent = getActivity().getIntent();
intent.putExtras(gameData);
// 컨테이너 활동에서 번들에서 데이터 가져 오기
Bundle gameData = getIntent().getExtras();
if (gameData != null)
{
int over = gameData.getInt(Constant.KEY_REQUESTED_OVER);
ArrayList<String> players = gameData.getStringArrayList(Constant.KEY_PLAYERS_ARR);
String team = gameData.getString(Constant.KEY_TEAM_NAME);
}
else if (gameData == null)
{
Toast.makeText(this, "Bundle is null", Toast.LENGTH_SHORT).show();
}
인터페이스는 최고의 솔루션 중 하나입니다.
접착제 인터페이스 :
public interface DataProviderFromActivity {
public String getName();
public String getId);
}
MyActivity :
public class MyActivity implements DataProviderFromActivity{
String name = "Makarov";
String id = "sys533";
... ... ... ... ... .... ....
... ... ... ... ... .... ....
public String getName(){
return name;
};
public String getId(){
return id;
};
}
MyFragment :
public class MyFragment extends Fragment{
String fragName = "";
String fragId = "";
... ... ... ... ... .... ....
... ... ... ... ... .... ....
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
DataProviderFromActivity myActivity= (DataProviderFromActivity) getActivity();
fragName = myActivity.getName();
fragId = myActivity.getId();
... ... ... ... ... .... ....
... ... ... ... ... .... ....
updateFragmentView();
}
}
Date Listeners를 구현하는 AppCompatActivity를 사용했습니다. 날짜 범위 선택기를 코딩해야했기 때문에 조각이 필요했습니다. 또한 선택한 날짜를 받아 부모 활동으로 반환하는 컨테이너가 필요했습니다.
컨테이너 활동의 경우 이것은 클래스 선언입니다.
public class AppCompatDateRange extends AppCompatActivity implements
DateIniRangeFragment.OnDateIniSelectedListener, DateFimRangeFragment.OnDateFimSelectedListener
콜백을위한 인터페이스 :
@Override
public void onDateIniSelected(String dataIni) {
Log.i("data inicial:", dataIni);
}
@Override
public void onDateFimSelected(String dataFim) {
Log.i("data final:", dataFim);
}
날짜는 쿼리 선택에서 매개 변수이므로 콜백은 문자열입니다.
프래그먼트 코드 (초기 날짜 프래그먼트 기반) :
public class DateIniRangeFragment extends Fragment {
OnDateIniSelectedListener callbackIni;
private DatePicker startDatePicker;
public DateIniRangeFragment() {
///required empty constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
///through this interface the fragment sends data to the container activity
public interface OnDateIniSelectedListener {
void onDateIniSelected(String dataIni);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
///layout for the fragment
View v = inflater.inflate(R.layout.date_ini_fragment, container, false);
///initial date for the picker, in this case, current date
startDatePicker = (DatePicker) v.findViewById(R.id.start_date_picker_appcompat);
Calendar c = Calendar.getInstance();
int ano = c.get(Calendar.YEAR);
int mes = c.get(Calendar.MONTH);
int dia = c.get(Calendar.DAY_OF_MONTH);
startDatePicker.setSpinnersShown(false);
startDatePicker.init(ano, mes, dia, dateSetListener);
return v;
}
///listener that receives the selected date
private DatePicker.OnDateChangedListener dateSetListener = new DatePicker.OnDateChangedListener() {
public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
if (view.isShown()) { ///if the datepicker is on the screen
String sDataIni = year + "-" + (monthOfYear + 1) + "-" + dayOfMonth;
callbackIni.onDateIniSelected(sDataIni); //apply date to callback, string format
}
}
};
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
/*
* this function guarantees that the container activity implemented the callback interface
* */
try {
callbackIni = (OnDateIniSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " deve implementar OnDateIniSelectedListener");
}
}
}
컨테이너 + 조각을 작성하기 위해 FragmentPagerAdapter를 확장하는 사용자 정의 클래스와 함께 ViewPager (AppCompat)를 사용했습니다. 대화 상자가 없습니다.
간단하게 사용할 수있는 EventBus를 그것은 쉬운 일 위대한입니다
3 단계의 이벤트 버스
이벤트를 정의하십시오.
public static class MessageEvent { /* Additional fields if needed */ }
구독자 준비 : 구독 방법을 선언하고 주석을 달고 선택적으로 스레드 모드를 지정하십시오.
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {/* Do something */};
구독자를 등록 및 등록 취소하십시오. 예를 들어 Android의 경우 활동 및 프래그먼트는 일반적으로 수명주기에 따라 등록해야합니다.
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
이벤트 게시 :
EventBus.getDefault().post(new MessageEvent());
public class Fragmentdemo extends Fragment {
public interface onDemoEventListener {
public void demoEvent(String s);
}
onDemoEventListener demoEventListener;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
demoEventListener = (onDemoEventListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement onDemoEventListener");
}
}
final String LOG_TAG = "TAG";
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragmentdemo, null);
Button button = (Button) v.findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
demoEventListener.someEvent("Test text to Fragment1");
}
});
enter code here
return v;
}
}
컨테이너 활동의 조각으로 다른 활동에서 전달 된 데이터를 가져 오는 또 다른 간단한 방법은 다음과 같습니다.
Activity_A => Activity_B (조각)
Activity_A에서 다른 활동으로 데이터 (문자열 여기)를 보내는 것처럼 의도를 만듭니다.
Intent intent = new Intent(getBaseContext(),Activity_B.class);
intent.putExtra("NAME", "Value");
startActivity(intent);
Activity_B에 포함 된 조각에 :
String data = getActivity().getIntent().getExtras();
getBaseContext()
다음과 같은 오류가 발생합니다 :The method getBaseContext() is undefined for the type new View.OnClickListener(){}