조각과 해당 컨테이너 활동 사이에 데이터 전달
단편과 해당 컨테이너 활동 사이에 데이터를 전달하려면 어떻게 해야 합니까?활동 간에 의도를 통해 데이터를 전달하는 것과 유사한 것이 있습니까?
인터페이스를 사용해 보십시오.
데이터를 포함하는 활동에 다시 전달해야 하는 프래그먼트는 데이터를 처리하고 전달하기 위한 인터페이스를 선언해야 합니다.그런 다음 포함 활동이 이러한 인터페이스를 구현하는지 확인합니다.예를 들어,
자바
당신의 조각에서, 인터페이스를 선언합니다...
public interface OnDataPass {
public void onDataPass(String data);
}
그런 다음 onAttach 메서드의 fragment에 포함 클래스의 인터페이스 구현을 다음과 같이 연결 방법은 다음과 같습니다.
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);
}
KOTLIN
1단계. 인터페이스 만들기
interface OnDataPass {
fun onDataPass(data: String)
}
2단계 다음과 같이 onAttach 메서드(Your Fragment)의 fragment에 포함 클래스의 인터페이스 구현을 연결합니다.
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)
}
당신의 조각에 전화를 걸 수 있습니다.
이렇게 하면 조각을 만든 활동에 액세스할 수 있습니다.여기서 활동 중인 모든 종류의 접근자나 메소드를 호출할 수 있습니다.
예를 들어 라고 하는 방법의 경우getResult()
귀하의 활동에 대해:
((MyActivity) getActivity()).getResult();
가장 쉬운 접근법이지만 권장되지 않음
프래그먼트에서 활동 데이터에 액세스할 수 있습니다.
활동:
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;
}
}
@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");
...
...
...
}
이것이 최선의 방법인지 아닌지는 모르겠지만 나는 꽤 오랫동안 구글에서 번들을 조각에서 컨테이너 활동으로 전달하는 방법을 찾고 있었지만 내가 찾은 것은 대신 활동에서 조각으로 데이터를 보내는 것뿐이었습니다(처음이라 조금 혼란스러웠습니다).
나중에 내가 원하는 대로 나만의 것을 시도했습니다.그래서 저 같은 사람이 같은 걸 찾는 경우에 여기에 올릴게요.
// 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);
}
내 활동:
public class MyActivity implements DataProviderFromActivity{
String name = "Makarov";
String id = "sys533";
... ... ... ... ... .... ....
... ... ... ... ... .... ....
public String getName(){
return name;
};
public String getId(){
return id;
};
}
내 조각:
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 Listener를 구현하는 AppCompat Activity를 사용했습니다.날짜 범위 선택기를 코드화해야 했기 때문에 프래그먼트는 필수 사항으로 왔습니다.그리고 부모님의 활동으로 돌려드리기 위해 선택한 날짜를 받을 컨테이너도 필요했습니다.
컨테이너 활동의 경우, 클래스 선언은 다음과 같습니다.
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");
}
}
}
컨테이너 + fragment를 구성하기 위해 FragmentPagerAdapter를 확장하는 사용자 지정 클래스가 있는 ViewPager(AppCompat)를 사용했습니다.대화상자가 없습니다.
간단하게 이벤트버스를 이용할 수 있습니다. 쉽고 잘 작동합니다.
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());
늦을지도 모른다는 거 알아요.하지만 저 또한 이 질문에 항상 길을 잃었습니다.이 링크를 공유하고 있습니다...왜냐하면 이것은 아마도 내가 이것에 대해 웹에서 찾은 최고의 설명이기 때문입니다.프래그먼트 투 액티비티 & 프래그먼트 투 프래그먼트!
Fragment 1.3.0-alpha04부터 각 Fragment Manager는 Fragment Result Owner를 구현합니다.이는 Fragment Manager가 프래그먼트 결과에 대한 중앙 저장소 역할을 할 수 있음을 의미합니다.이렇게 변경하면 구성 요소가 서로 직접 참조할 필요 없이 조각 결과를 설정하고 해당 결과를 청취하여 구성 요소가 서로 통신할 수 있습니다.
조각에서:하위 fragment는 Fragment Manager에 결과를 설정합니다.그러면 프래그먼트가 시작되면 부모는 결과를 받습니다.
button.setOnClickListener {
val result = "result"
// Use the Kotlin extension in the fragment-ktx artifact
setFragmentResult("requestKey", bundleOf("bundleKey" to result))
}
호스트 활동에서:호스트 작업에서 조각 결과를 수신하려면 getSupportFragmentManager()를 사용하여 조각 관리자에서 결과 수신기를 설정합니다.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
supportFragmentManager
.setFragmentResultListener("requestKey", this) { requestKey, bundle ->
// We use a String here, but any type that can be put in a Bundle is supported
val result = bundle.getString("bundleKey")
// Do something with the result
}
}
}
이게 저한테 효과가 있어요.
활동에서 이 메서드 추가
public void GetData(String data)
{
// do something with your data
}
프래그먼트에 이 행을 추가합니다.
((YourActivity)getContext).GetData("your data here");
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;
}
}
먼저 Fragment.java에 인터페이스를 만듭니다.
public interface SendDataInterface{
public void sendData(String data);
}
그런 다음 첨부(Context context) 메서드를 재정의하여 Fragment.java에 Activity 참조를 만듭니다.
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
Activity activity =(Activity)context ;
try{
mSendDataInterface= (SendDataInterface) activity;
}catch(RuntimeException e){
throw new RuntimeException(activity.toString()+" must implement method");
}
}
Fragment.java는 다음과 같이 나타납니다.
public class FirstFragment extends Fragment {
private Button mButton;
private EditText mEditText;
SendDataInterface mSendDataInterface;
public FirstFragment(){ }
/**
* We can not directly access the data of Fragment
* So we should create an interface
*
*/
public interface SendDataInterface{
public void sendData(String data);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_first, container, false);
mButton = view.findViewById(R.id.button);
mEditText = view.findViewById(R.id.editText);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String data= mEditText.getText().toString();
mSendDataInterface.sendData(data);
}
});
return view;
}
/**
* We create a reference of activity
*/
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
Activity activity =(Activity)context ;
try{
mSendDataInterface= (SendDataInterface) activity;
}catch(RuntimeException e){
throw new RuntimeException(activity.toString()+" must implement method");
}
}
MainActivity.java에서 SendDataInterface 인터페이스 구현
public class MainActivity extends AppCompatActivity implements FirstFragment.SendDataInterface {
private TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = findViewById(R.id.textView);
if(findViewById(R.id.container) != null){
// Check if app is on Resume in Lifecycle
if(savedInstanceState != null){
return;
}
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.add(R.id.container,new FirstFragment(),null)
.commit();
}
}
@Override
public void sendData(String data) {
mTextView.setText(data);
}
}
다 했어요.
데이터를 프래그먼트에서 액티비티로 변환하는 데 사용한 효과적인 솔루션은 다음과 같습니다.
In fragment:
Intent intent = new Intent(this, OtherActivity.class);
Bundle bundle = new Bundle();
bundle.putString("KEY", Value);
intent.putExtras(bundle);
getActivity().startActivity(bundle);
//------------------------------------------------------------
In Activity get data:
Bundle bundle = getIntent().getExtras();
if (bundle != null){
String getData = bundle.getString("KEY");
}
Done!
컨테이너 작업의 조각에서 다른 작업에서 전달된 데이터를 가져오는 간단한 또 다른 방법: 예:
활동_A => 활동_B(파편)
활동_A에서 다른 활동에 데이터(String here)를 보내는 것과 같은 의도를 만듭니다.
Intent intent = new Intent(getBaseContext(),Activity_B.class);
intent.putExtra("NAME", "Value");
startActivity(intent);
Activity_B에 포함된 당신의 프래그먼트에서:
String data = getActivity().getIntent().getExtras();
언급URL : https://stackoverflow.com/questions/9343241/passing-data-between-a-fragment-and-its-container-activity
'sourcecode' 카테고리의 다른 글
SHA256으로 문자열 해시 (0) | 2023.10.21 |
---|---|
부트스트랩-선택 - 변경 시 이벤트를 발생시키는 방법 (0) | 2023.10.21 |
각 JS 명명 규칙($, camelCase 및 pascalCase) (0) | 2023.10.21 |
C 프로그래밍: pthread를 사용한 디버깅 (0) | 2023.10.21 |
내 ng 모델이 꼭 점이 있어야 하위 $scope 문제를 피할 수 있습니까? (0) | 2023.10.21 |