Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Android

एंड्रॉइड में एक फ्रैगमेंट से दूसरे फ्रैगमेंट में डेटा कैसे पास करें?

एंड्रॉइड में फ्रैगमेंट-टू-फ्रैगमेंट संचार

फ्रैगमेंट्स को एक-दूसरे से सीधे बात नहीं करनी चाहिए। अनुशंसित पैटर्न: **शेयर्ड ViewModel** (आर्किटेक्चर कंपोनेंट्स) या **इंटरफेस कॉलबैक** होस्ट गतिविधि के माध्यम से। दोनों दृष्टिकोण यहां दिखाए गए हैं।

दृष्टिकोण 1 - शेयर्ड ViewModel (पसंदीदा, जीवनचक्र-जागरूक)

ViewModel

public class SharedViewModel extends ViewModel {
    private final MutableLiveData message = new MutableLiveData<>();

    public void sendMessage(String msg) { message.setValue(msg); }
    public LiveData getMessage() { return message; }
}

फ्रैगमेंट A (प्रेषक)

public class SenderFragment extends Fragment {
    private SharedViewModel vm;
    private EditText etInput;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle saved) {
        View v = inflater.inflate(R.layout.fragment_sender, container, false);
        etInput = v.findViewById(R.id.etInput);
        v.findViewById(R.id.btnSend).setOnClickListener(view -> {
            String txt = etInput.getText().toString();
            if (!txt.isEmpty()) vm.sendMessage(txt);
        });
        return v;
    }

    @Override
    public void onViewCreated(@NonNull View view, Bundle saved) {
        super.onViewCreated(view, saved);
        vm = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
    }
}

फ्रैगमेंट B (प्राप्तकर्ता)

public class ReceiverFragment extends Fragment {
    private TextView tvMessage;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle saved) {
        return inflater.inflate(R.layout.fragment_receiver, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, Bundle saved) {
        super.onViewCreated(view, saved);
        tvMessage = view.findViewById(R.id.tvMessage);
        SharedViewModel vm = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
        vm.getMessage().observe(getViewLifecycleOwner(), msg -> tvMessage.setText("प्राप्त: " + msg));
    }
}

दृष्टिकोण 2 - इंटरफेस कॉलबैक (लीगेसी/सरल मामले)

इंटरफेस

public interface OnFragmentMessageListener {
    void onMessageReceived(String message);
}

फ्रैगमेंट A

public class SenderFragment extends Fragment {
    private OnFragmentMessageListener listener;
    private EditText etInput;

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentMessageListener) {
            listener = (OnFragmentMessageListener) context;
        } else {
            throw new ClassCastException("होस्ट को OnFragmentMessageListener लागू करना होगा");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        listener = null;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle saved) {
        View v = inflater.inflate(R.layout.fragment_sender, container, false);
        etInput = v.findViewById(R.id.etInput);
        v.findViewById(R.id.btnSend).setOnClickListener(view -> {
            if (listener != null) listener.onMessageReceived(etInput.getText().toString());
        });
        return v;
    }
}

गतिविधि (मध्यस्थ)

public class MainActivity extends AppCompatActivity implements OnFragmentMessageListener {
    @Override
    protected void onCreate(Bundle saved) {
        super.onCreate(saved);
        setContentView(R.layout.activity_main); // दोनों फ्रैगमेंट्स वाला लेआउट
    }

    @Override
    public void onMessageReceived(String message) {
        ReceiverFragment receiver = (ReceiverFragment) getSupportFragmentManager()
                .findFragmentById(R.id.receiverFragment);
        if (receiver != null) receiver.updateMessage(message);
    }
}

फ्रैगमेंट B

public class ReceiverFragment extends Fragment {
    private TextView tvMessage;
    @Override public View onCreateView(LayoutInflater inf, ViewGroup c, Bundle s) {
        return inf.inflate(R.layout.fragment_receiver, c, false);
    }
    @Override public void onViewCreated(View v, Bundle s) {
        tvMessage = v.findViewById(R.id.tvMessage);
    }
    public void updateMessage(String msg) { tvMessage.setText("प्राप्त: " + msg); }
}

तुलना

पहलूशेयर्ड ViewModelइंटरफेस कॉलबैक
डिकॉउपलिंगउच्च (फ्रैगमेंट्स एक-दूसरे को नहीं जानते)मध्यम (गतिविधि मध्यस्थ है)
कॉन्फिग परिवर्तन पर जीवित रहता हैहांनहीं (मैन्युअल हैंडलिंग आवश्यक)
बैक स्टैक सुरक्षितहांनाजुक (फ्रैगमेंट नष्ट हो सकता है)
बॉयलरप्लेटकममध्यम

लेआउट (गतिविधि)

<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">

    <fragment
        android:id="@+id/senderFragment"
        android:name="com.example.SenderFragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1" />

    <fragment
        android:id="@+id/receiverFragment"
        android:name="com.example.ReceiverFragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1" />

</LinearLayout>

सर्वोत्तम अभ्यास

  • नए ऐप्स के लिए **शेयर्ड ViewModel** का उपयोग करें — यह जीवनचक्र, बैक स्टैक और प्रक्रिया पुनर्निर्माण को संभालता है।
  • सरल, अल्पकालिक इवेंट्स के लिए जहां ViewModel ओवरकिल है, **इंटरफेस** का उपयोग करें।
  • कभी भी getFragmentManager().findFragmentById() पर भरोसा न करें और सीधे दूसरे फ्रैगमेंट पर विधियों को कॉल न करें — यह टाइट कपलिंग और क्रैश का कारण बनता है।
  • नेविगेशन कंपोनेंट का उपयोग कर रहे हैं? NavController + getBackStackEntry() के माध्यम से शेयर्ड ViewModel को स्कोप करें।

मूल उदाहरण की समीक्षा

मूल कोड गतिविधि में एक इंटरफेस का उपयोग करता था लेकिन onAttach में कास्टिंग, नल-सुरक्षा की कमी, और प्राप्तकर्ता फ्रैगमेंट पर एक सार्वजनिक विधि onFragmentInteraction थी। ऊपर दिए गए ViewModel दृष्टिकोण को प्राथमिकता दें।

  1. एंड्रॉइड में एक्टिविटी से फ्रैगमेंट में वेरिएबल कैसे पास करें? एंड्रॉइड में एक्टिविटी से फ्रैगमेंट में वेरिएबल कैसे पास करें?

    Bundle और setArguments के साथ फ्रैगमेंट को डेटा पास करें यह उदाहरण दर्शाता है कि Bundle का उपयोग करके एक्टिविटी से फ्रैगमेंट में स्ट्रिंग डेटा कैसे पास करें। चरण 1: नया प्रोजेक्ट बनाएं Android Studio में File → New Project चुनें। चरण 2: लेआउट में कंटेनर और इनपुट res/layout/activity_main.xml: <?

  1. एंड्रॉइड में एक एक्टिविटी से दूसरी एक्टिविटी में इमेज कैसे पास करें एंड्रॉइड में एक एक्टिविटी से दूसरी एक्टिविटी में इमेज कैसे पास करें

    Intent के माध्यम से इमेज रिसोर्स ID या बिटमैप पास करना एंड्रॉइड में एक एक्टिविटी से दूसरी में इमेज पास करने के दो मुख्य तरीके हैं: रिसोर्स ID (इंट/ड्रॉएबल रेफरेंस) पास करना (कुशल, केवल ऐप-इंटरनल इमेज के लिए) या बिटमैप/बाइट ऐरे पास करना (किसी भी इमेज के लिए, लेकिन मेमोरी-इंटेंसिव)। चरण 1: नया प्रोजे

  1. Android में एक Fragment से दूसरे Fragment में डेटा कैसे भेजें? Android में एक Fragment से दूसरे Fragment में डेटा कैसे भेजें?

    परिचय यह ट्यूटोरियल दर्शाता है कि Android में Fragment के बीच डेटा कैसे पास करें। हम ViewPager और TabLayout का उपयोग करके दो फ्रैगमेंट्स बनाएंगे और इंटरफेस के माध्यम से डेटा ट्रांसफर करेंगे। आवश्यक चरण चरण 1: नया प्रोजेक्ट बनाएं Android Studio में File → New Project चुनें। चरण 2: मुख्य लेआउट (res