फ्रैगमेंट से होस्ट एक्टिविटी के पब्लिक मेथड को कॉल करने के तरीके
एंड्रॉइड में फ्रैगमेंट अपनी होस्ट एक्टिविटी के साथ getActivity() के माध्यम से संवाद कर सकता है। एक्टिविटी के पब्लिक मेथड को कॉल करने के लिए फ्रैगमेंट को एक्टिविटी को उपयुक्त टाइप में कास्ट करना होता है। यह पैटर्न फ्रैगमेंट-एक्टिविटी संचार के लिए मानक है।
चरण 1: नया प्रोजेक्ट बनाएं
Android Studio में प्रोजेक्ट बनाएं।
चरण 2: एक्टिविटी लेआउट में फ्रैगमेंट कंटेनर
res/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:padding="16dp"
tools:context=".MainActivity">
<FrameLayout
android:id="@+id/fragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
चरण 3: MainActivity में पब्लिक मेथड
package com.app.sample;
import android.os.Bundle;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// फ्रैगमेंट प्रोग्रामेटिकली जोड़ें
if (savedInstanceState == null) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.fragmentContainer, new SampleFragment());
ft.commit();
}
}
// यह पब्लिक मेथड फ्रैगमेंट से कॉल किया जाएगा
public void activityMethodFromFragment(String message) {
Toast.makeText(this, "एक्टिविटी मेथड कॉल हुआ: " + message, Toast.LENGTH_LONG).show();
}
// पैरामीटर के साथ एक और मेथड
public void updateToolbarTitle(String title) {
if (getSupportActionBar() != null) {
getSupportActionBar().setTitle(title);
}
}
}
चरण 4: फ्रैगमेंट क्लास
SampleFragment.java:
package com.app.sample;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
public class SampleFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_sample, container, false);
Button btnCallActivity = view.findViewById(R.id.btnCallActivity);
btnCallActivity.setOnClickListener(v -> callActivityMethod());
return view;
}
private void callActivityMethod() {
// तरीका 1: डायरेक्ट कास्ट (सिंपल लेकिन टाइट कपलिंग)
if (getActivity() instanceof MainActivity) {
((MainActivity) getActivity()).activityMethodFromFragment("फ्रैगमेंट से संदेश");
}
// तरीका 2: इंटरफेस के माध्यम से (अनुशंसित - लूज कपलिंग)
// ((OnFragmentInteractionListener) getActivity()).onFragmentMessage("संदेश");
}
}
चरण 5: फ्रैगमेंट लेआउट
res/layout/fragment_sample.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="match_parent"
android:padding="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="फ्रैगमेंट से एक्टिविटी मेथड कॉल करना"
android:textAlignment="center"
android:textSize="18sp"
android:textStyle="bold" />
<Button
android:id="@+id/btnCallActivity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/textView"
android:layout_centerHorizontal="true"
android:layout_marginTop="24dp"
android:text="एक्टिविटी मेथड कॉल करें" />
</RelativeLayout>
बेहतर तरीका: इंटरफेस पैटर्न (लूज कपलिंग)
फ्रैगमेंट को विशिष्ट एक्टिविटी क्लास पर निर्भर नहीं करना चाहिए:
1. इंटरफेस परिभाषित करें
public interface OnFragmentInteractionListener {
void onFragmentAction(String data);
void onFragmentEvent(int eventType);
}
2. एक्टिविटी इम्प्लीमेंट करे
public class MainActivity extends AppCompatActivity implements OnFragmentInteractionListener {
@Override
public void onFragmentAction(String data) {
Toast.makeText(this, "इंटरफेस के माध्यम से: " + data, Toast.LENGTH_SHORT).show();
}
@Override
public void onFragmentEvent(int eventType) {
// इवेंट टाइप के अनुसार हैंडल करें
}
}
3. फ्रैगमेंट में इंटरफेस का उपयोग
public class SampleFragment extends Fragment {
private OnFragmentInteractionListener listener;
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
listener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context + " को OnFragmentInteractionListener इम्प्लीमेंट करना चाहिए");
}
}
@Override
public void onDetach() {
super.onDetach();
listener = null; // लीक रोकें
}
private void notifyActivity() {
if (listener != null) {
listener.onFragmentAction("फ्रैगमेंट से डेटा");
}
}
}
Kotlin में सरल संस्करण
| पैटर्न | पक्ष | विपक्ष |
|---|---|---|
| डायरेक्ट कास्ट | सरल, त्वरित | टाइट कपलिंग, टेस्टिंग कठिन |
| इंटरफेस (Listener) | लूज कपलिंग, टेस्टेबल, पुन: प्रयोज्य | थोड़ा अधिक कोड |
| ViewModel (Shared) | लाइफसाइकिल अवेयर, डेटा साझा | Jetpack निर्भरता |
| EventBus / LiveData | डिकपल्ड, मल्टीपल ऑब्जर्वर्स | ओवरहेड, जटिलता |
बेस्ट प्रैक्टिस: उत्पादन ऐप्स के लिए Shared ViewModel या इंटरफेस पैटर्न का उपयोग करें। डायरेक्ट कास्ट केवल सरल डेमो/प्रोटोटाइप के लिए ठीक है।