Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Android

Cách gọi method của Activity từ Fragment trong Android

Giới thiệu

Bài viết này minh họa cách Fragment gọi phương thức (method) của Activity chứa nó. Đây là pattern phổ biến để giao tiếp Fragment ↔ Activity.

Các bước thực hiện

Bước 1: Tạo dự án mới

Tạo project Android Studio mới.

Bước 2: Layout Activity chứa Fragment (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="8dp"
    tools:context=".MainActivity">

    <FrameLayout
        android:id="@+id/frameLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

Bước 3: MainActivity với method public (src/MainActivity.java)

package app.com.sample;

import android.os.Bundle;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
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);

        // Thêm Fragment vào container
        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        ft.replace(R.id.frameLayout, new SampleFragment());
        ft.commit();
    }

    // Method public để Fragment gọi
    public void fragmentMethod() {
        Toast.makeText(this, "Method được gọi từ Fragment!", Toast.LENGTH_LONG).show();
    }
}

Bước 4: Tạo Fragment (SampleFragment.java)

package app.com.sample;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;

public class SampleFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_sample, container, false);

        // Gọi method của Activity chứa Fragment này
        // Cách 1: Ép kiểu (chỉ dùng khi chắc chắn Activity là MainActivity)
        ((MainActivity) requireActivity()).fragmentMethod();

        // Cách 2: Interface (khuyên dùng - loose coupling)
        // if (getActivity() instanceof OnFragmentInteractionListener) {
        //     ((OnFragmentInteractionListener) getActivity()).onFragmentAction();
        // }

        return view;
    }
}

Layout Fragment (res/layout/fragment_sample.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"
    tools:context=".SampleFragment">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="Gọi method từ Fragment sang Activity"
        android:textAlignment="center"
        android:textSize="24sp"
        android:textStyle="bold" />

</RelativeLayout>

Bước 5: Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="app.com.sample">

    <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/AppTheme">

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
</manifest>

Chạy ứng dụng

Chạy app, Fragment được load ngay khi Activity tạo, Toast "Method được gọi từ Fragment!" sẽ hiện ra.

Cách gọi method của Activity từ Fragment trong Android

Best Practice: Sử dụng Interface (Listener Pattern)

Cách ép kiểu ((MainActivity) getActivity()) tạo sự phụ thuộc chặt chẽ. Nên dùng Interface:

// 1. Định nghĩa interface
public interface OnFragmentInteractionListener {
    void onFragmentAction(String data);
}

// 2. Activity implement interface
public class MainActivity extends AppCompatActivity implements OnFragmentInteractionListener {
    @Override
    public void onFragmentAction(String data) {
        // Xử lý
    }
}

// 3. Fragment kiểm tra và gọi
@Override
public void onAttach(@NonNull Context context) {
    super.onAttach(context);
    if (context instanceof OnFragmentInteractionListener) {
        listener = (OnFragmentInteractionListener) context;
    } else {
        throw new RuntimeException(context + " must implement OnFragmentInteractionListener");
    }
}

// 4. Gọi listener.onFragmentAction("data") khi cần

Lưu ý quan trọng

  • Luôn kiểm tra getActivity() != null trước khi gọi (Fragment có thể detached)
  • Dùng requireActivity() (API 23+) sẽ ném exception nếu null, an toàn hơn
  • Tránh memory leak: không giữ reference Activity lâu dài trong Fragment