Giao tiếp với Fragments thông qua Interface

1. GIỚI THIỆU

Thông thường một ứng dụng android chúng ta sẽ sử dụng rất nhiều activity và fragment vậy làm thế nào để giao tiếp nhận dữ liệu giữa fragment và activity.

Trong bài viết này mình sẽ hướng dẫn các bạn sử dụng interface để lắng nghe fragment.
Cụ thể như sau:

  • Ở MainActivity mình sẽ chia đôi màn hình và chèn 1 fragment vào.
  • Tiếp theo ở Fragment mình tạo một ListView chứa dữ liệu
  • Vậy khi mình click vào data trên ListView mình sẽ dùng interface để lắng nghe dữ liệu trả về activity 😀

2. Bắt đầu

Đầu tiên chúng ta tạo 1 fragment trong đó chứa 1 interface, và tạo dữ liệu cho fragment chứa một listview có data.

  • fragment_one.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ListView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/list_data"/>
</LinearLayout>
  • FragmentOne.java
public class FragmentOne extends Fragment {
    OnSelectedListener mCallback;
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    // Activity phải implement interface này
    public interface OnSelectedListener {
        public void onSelected(String value);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        super.onCreateView(inflater, container, savedInstanceState);
        View view = inflater.inflate(R.layout.fragment_one, container, false);
        ListView lvData = (ListView) view.findViewById(R.id.list_data);
        final String[] data = {"Linh","Kim","Minh","Khải"};
        lvData.setAdapter(new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1,data));
        lvData.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                String value = data[position];
                mCallback.onSelected(value);
            }
        });
        return view;
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        try {
            mCallback = (OnSelectedListener) context;
        } catch (ClassCastException e) {
            throw new ClassCastException(context.toString()
                    + " must implement OnSelectedListener");
        }
    }
}

Lưu ý: Activity phải implement Interface OnSelectedListener.

  • Quay lại MainActivity chúng ta sẽ tạo 1 giao diện chia đôi màn hình mục đích replace fragment ngay trên MainActivity.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.lynkmieu.communicatingfragment.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:gravity="center"
        android:layout_weight="1">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Activity Main"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/tv_value"
            android:text="Value"/>
    </LinearLayout>

    <!--Replace Fragment tại đây-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_weight="1"
        android:id="@+id/fragment_content"/>
</LinearLayout>

Tiến hành implement interface và overide method của nó như sau:

public class MainActivity extends AppCompatActivity implements FragmentOne.OnSelectedListener {
    private TextView tvValue;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tvValue = (TextView) findViewById(R.id.tv_value);

        replaceFragment();
    }
 
    private void replaceFragment() {
        FragmentOne fragmentOne = new FragmentOne();
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.replace(R.id.fragment_content, fragmentOne);
        transaction.addToBackStack(null);
        transaction.commit();
    }

    @Override
    public void onSelected(String value) {
        tvValue.setText(value);
    }
}

Oke vậy là đã hoàn thành, khi chúng ta tương tác với ListView bên FragmentOne dữ liệu sẽ được trả về MainActivity ^^

Xem bài viết khác về fragment

Source Git.

Nguyễn Linh

Chia sẻ để cùng tiến bộ...