एंड्रॉइड में फ्रैगमेंट्स के बीच डेटा पास करने का सही तरीका
एंड्रॉइड में दो फ्रैगमेंट्स के बीच सीधा कम्युनिकेशन **नहीं** करना चाहिए। Google की आधिकारिक गाइडलाइन के अनुसार, **एक्टिविटी को मध्यस्थ (mediator)** बनाना चाहिए। यह ट्यूटोरियल उसी पैटर्न को दर्शाता है: FragmentOne → Interface → MainActivity → FragmentTwo।
आर्किटेक्चर अवलोकन
┌─────────────┐ Interface ┌─────────────┐ Direct Call ┌──────────────┐ │ FragmentOne │ ─────────────────▶ │ MainActivity │ ─────────────────▶ │ FragmentTwo │ │ (Sender) │ onFragmentInteraction│ (Mediator) │ updateTextField() │ (Receiver) │ └─────────────┘ └─────────────┘ └──────────────┘
चरण 1: नया प्रोजेक्ट बनाएं
Android Studio → File → New → New Project → "Empty Activity" → Finish।
चरण 2: Activity Layout (activity_main.xml)
दोनों फ्रैगमेंट्स को स्टैटिकली `
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#574706"
tools:context=".MainActivity">
<fragment
android:id="@+id/fragmentOne"
android:name="com.example.fragmentdatapass.FragmentOne"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
tools:layout="@layout/fragment_fragment_one" />
<fragment
android:id="@+id/fragmentTwo"
android:name="com.example.fragmentdatapass.FragmentTwo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/fragmentOne"
android:layout_centerHorizontal="true"
android:layout_marginTop="41dp"
tools:layout="@layout/fragment_fragment_two" />
</RelativeLayout>
चरण 3: FragmentOne — सेंडर (FragmentOne.java)
एक इंटरफेस डिफ़ाइन करता है जिसे एक्टिविटी इम्प्लीमेंट करेगी:
package com.example.fragmentdatapass;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.fragment.app.Fragment;
public class FragmentOne extends Fragment {
private OnFragmentInteractionListener listener;
private EditText userInput;
public FragmentOne() { /* Required empty constructor */ }
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_fragment_one, container, false);
userInput = view.findViewById(R.id.userInput);
Button btnUpdate = view.findViewById(R.id.button);
btnUpdate.setOnClickListener(v -> {
String input = userInput.getText().toString().trim();
if (input.isEmpty()) {
Toast.makeText(requireContext(), "कृपया कुछ टेक्स्ट दर्ज करें", Toast.LENGTH_SHORT).show();
return;
}
// इंटरफेस के ज़रिए एक्टिविटी को डेटा भेजें
if (listener != null) {
listener.onFragmentInteraction(input);
}
});
return view;
}
// एक्टिविटी को यह इंटरफेस इम्प्लीमेंट करना होगा
public interface OnFragmentInteractionListener {
void onFragmentInteraction(String userContent);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof OnFragmentInteractionListener) {
listener = (OnFragmentInteractionListener) activity;
} else {
throw new ClassCastException(activity.toString() + " को OnFragmentInteractionListener इम्प्लीमेंट करना होगा");
}
}
@Override
public void onDetach() {
super.onDetach();
listener = null; // लीक रोकें
}
}
चरण 4: FragmentOne Layout (fragment_fragment_one.xml)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp">
<EditText
android:id="@+id/userInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="यहां टेक्स्ट टाइप करें"
android:inputType="text" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/userInput"
android:layout_centerHorizontal="true"
android:layout_marginTop="16dp"
android:padding="12dp"
android:text="FragmentTwo में भेजें" />
</RelativeLayout>
चरण 5: FragmentTwo — रिसीवर (FragmentTwo.java)
सिर्फ एक पब्लिक मेथड एक्सपोज़ करता है जिसे एक्टिविटी कॉल करेगी:
package com.example.fragmentdatapass;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.fragment.app.Fragment;
public class FragmentTwo extends Fragment {
private TextView tvReceivedText;
public FragmentTwo() { /* Required empty constructor */ }
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_fragment_two, container, false);
tvReceivedText = view.findViewById(R.id.textUpdate);
return view;
}
// एक्टिविटी इस मेथड को कॉल करेगी
public void updateTextField(String newText) {
tvReceivedText.setText(newText);
}
}
चरण 6: FragmentTwo Layout (fragment_fragment_two.xml)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp">
<TextView
android:id="@+id/textUpdate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:textSize="20sp"
android:textStyle="bold"
android:text="यहां डेटा दिखेगा" />
</RelativeLayout>
चरण 7: MainActivity — मध्यस्थ (MainActivity.java)
package com.example.fragmentdatapass;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity
implements FragmentOne.OnFragmentInteractionListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// फ्रैगमेंट्स XML में स्टैटिकली एडेड हैं, इसलिए यहां कुछ खास नहीं करना
}
// FragmentOne से डेटा प्राप्त करें
@Override
public void onFragmentInteraction(String userContent) {
// FragmentTwo ढूंढें और डेटा पास करें
FragmentTwo fragmentTwo = (FragmentTwo) getSupportFragmentManager()
.findFragmentById(R.id.fragmentTwo);
if (fragmentTwo != null) {
fragmentTwo.updateTextField(userContent);
}
}
}
चरण 8: AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="com.example.fragmentdatapass">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.FragmentDataPass">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
चलाएं और टेस्ट करें
- ऐप लॉन्च करें।
- ऊपरी फ्रैगमेंट (FragmentOne) में टेक्स्ट टाइप करें → "भेजें" दबाएं।
- निचला फ्रैगमेंट (FragmentTwo) तुरंत वही टेक्स्ट दिखाएगा।
⚡ आधुनिक विकल्प: ViewModel + LiveData
नए प्रोजेक्ट्स के लिए Google **Shared ViewModel** की सिफारिश करता है:
// SharedViewModel.java
public class SharedViewModel extends ViewModel {
private final MutableLiveData<String> text = new MutableLiveData<>();
public void setText(String s) { text.setValue(s); }
public LiveData<String> getText() { return text; }
}
// FragmentOne में
viewModel.setText(inputText);
// FragmentTwo में
viewModel.getText().observe(getViewLifecycleOwner(), text -> tv.setText(text));
यह तरीका फ्रैगमेंट्स को पूरी तरह से डिकपल करता है और कॉन्फ़िगरेशन चेंज (रोटेशन आदि) में डेटा बचाए रखता है।
सारांश
- ✅ **सही पैटर्न**: Fragment → Interface → Activity → Fragment
- ❌ **गलत**: Fragment सीधे दूसरे Fragment को रेफरेंस करे
- 🔄 **आधुनिक**: Shared ViewModel + LiveData (Jetpack)