Android Bài 34: Phân Loại Fragment

Posted by
Rating: 5.0/5. From 14 votes.
Please wait...

Được chỉnh sửa ngày 30/10/2019.

Chào mừng các bạn đã đến với bài học Android thứ 34, bài học về Fragment (phần tiếp theo). Đây là bài học trong chuỗi bài viết về lập trình ứng dụng Android bằng Java của Yellow Code Books.

Có thể đến bài học này bạn thắc mắc rằng, ôi các bài về Fragment sao nó dài lê thê thế, đến bao giờ mới kết thúc đây. Thực ra thì có bao nhiêu đây kiến thức về Fragment mà mình xin phép tổng hợp lại ở các bài viết của mình như sau.

  • Làm quen với Fragment – Với bài này bạn đã hiểu tại sao Android lại đẻ ra cái khái niệm Fragment cho việc hiển thị động giao diện trên các thiết bị chạy hệ điều hành này. Bạn cũng biết được Fragment ra đời khi nào và sự hỗ trợ ngược cho các hệ điều hành chưa có Fragment trước đó như thế nào. Bạn cũng thử làm quen với cách tạo một Fragment trong Android Studio.
  • Làm quen với việc tạo mới một Fragment – Bài học này tập trung vào việc tạo và hiểu những đoạn code mà khi bạn tạo mới một Fragment bằng Android Studio. FirstFragmentSecondFragment cũng được tạo ra ở bài học này.
  • Làm quen với việc hiển thị Fragment – Bạn đã được biết đến cách hiển thị TĩnhĐộng các Fragment lên Activity như thế nào.
  • Làm quen với việc hệ thống quản lý Fragment thông qua Back Stack và Vòng đời của nó – Bạn đã hiểu rõ cách hệ thống lưu trữ Fragment trong Back Stack, và cách sử dụng các phương thức callback bên trong vòng đời của Fragment.

Thật thú vị khi được hiểu rõ về Fragment như vậy (chứ không phải đau đầu đâu đúng không nào).

Và bài học hôm nay sẽ là kiến thức cuối cùng về Fragment mà mình muốn cung cấp. Bài học sẽ cho bạn biết, trong Android, có những thể loại Fragment nào mà chúng ta có thể sử dụng.

Fragment Cơ Bản

Minh họa Fragment cơ bản
Minh họa Fragment cơ bản

Chính là Fragment mà bạn đã làm quen từ các bài học trước, mà mình cũng có liệt kê trên kia. Đây là Fragment đơn thuần, với nó, bạn có thể xây dựng mọi thứ theo ý của bạn, với việc theo dõi các bài học về Fragment như mình đã nói, thì bạn đã hiểu rất rõ về thể loại Fragment này, nên mục này mình không nói đến nó nữa, chỉ điểm qua cho nó có mặt mà thôi.

Chúng ta bắt đầu xem qua các thể loại Fragment sau đây, chúng đều là các lớp con của Fragment cả. Chúng được sinh ra để làm gì vậy? Mời bạn cùng xem.

ListFragment

Minh họa ListFragment
Minh họa ListFragment

Đây là một biến thể của Fragment. Dĩ nhiên rồi, vì như mình nói đó, ListFragment là con của Fragment mà. ListFragment giúp cho bạn có thể thiết kế ra một Fragment có chứa ListView một cách nhanh chóng (mặc dù chúng ta hoàn toàn có thể dùng Fragment như trước giờ để thiết kế giao diện có chứa ListView như mình đã nói này).

Và tất nhiên, cũng như Fragment, ListFragment vẫn được xây dựng trong hai gói android.appandroid.support.v4.app dành cho nhu cầu tương thích ngược. Bạn cũng có thể xem lại thông tin về tương thích ngược ở mục này.

ListFragment hay các kiến thức liên quan đến hiển thị UI dạng list này sẽ được mình nói đến cụ thể ở bài học về ListView. Tuy nhiên mình cũng đưa ra một tí code cho bạn tham khảo (và có thể code thử). Code này sẽ không có trên GitHub nhé.

Đầu tiên, bạn có thể tạo mới một Blank Fragment. Bạn có thể không check chọn vào cả ở Include fragment factory methods? và Include interface callbacks? để source code được gọn nhẹ. ListFragment này mình đặt tên là ListFragmentSample.

Tạo ListFragmentSample
Tạo ListFragmentSample

Đây là giao diện của ListFragment, chính là file fragment_list_fragment_sample.xml.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
 
    <ListView
        android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ListView>
 
    <TextView
        android:id="@android:id/empty"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </TextView>
</LinearLayout>

Còn đây là source code của ListFragmentSample. Bạn có thể thấy Fragment này kế thừa từ ListFragment thay vì Fragment như các bài học trước. Và implements sự kiện OnItemClickListener. Với các callback của Fragment này mình vẫn dùng onCreateView()onActivityCreated() để thiết kế giao diện và xây dựng adapter cho nó. Tất cả những thông tin chi tiết này sẽ được mình nói rõ hơn ở bài học về ListView sau này nhé.

public class ListFragmentSample extends ListFragment implements AdapterView.OnItemClickListener {
 
    private String[] planets = { "Sun", "Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune" };
 
    public ListFragmentSample() {
        // Required empty public constructor
    }
 
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_list_fragment_sample, container, false);
    }
 
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_expandable_list_item_1, planets);
        setListAdapter(adapter);
        getListView().setOnItemClickListener(this);
    }
 
    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
        Toast.makeText(getActivity(), "Item: " + position, Toast.LENGTH_SHORT).show();
    }
}

Với layout của MainActivity, mình sử dụng cách hiển thị Fragment theo kiểu tĩnh. Bạn xem file activity_main.xml sẽ như sau.

<!-- Content -->
 
<LinearLayout
    android:id="@+id/activity_main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.yellowcode.tournote.MainActivity">
 
    <fragment
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.yellowcode.tournote.ListFragmentSample"/>
 
</LinearLayout>

Và nhờ sử dụng cách hiển thị Fragment theo kiểu tĩnh, chúng ta không cần làm gì nhiều với MainActivity.java (bạn chỉ cần đảm bảo xóa bỏ các dòng code add Fragment động từ các bài học trước, nếu có, ra khỏi code của MainActivity.java mà thôi).

Kết quả thực thi sẽ như hình chụp đầu tiên của mục này trên kia.

DialogFragment

Minh họa DialogFragment
Minh họa DialogFragment

Dĩ nhiên là DialogFragment cũng kế thừa từ Fragment. Nếu như ListFragment là một dạng mở rộng nhưng khá là giống Fragment đến nỗi chúng ta hầu như cũng chẳng cần đến ListFragment nữa (so sánh theo tư tưởng khai triển code, qua bài về ListView bạn sẽ thấy rằng không dùng ListFragment cũng vẫn xây dựng được giao diện danh sách một cách tương tự). Thì DialogFragment lại là một biến thể mới mẻ của Fragment. DialogFragment giúp tạo ra một dialog, chính là một giao diện hiển thị đè lên trên giao diện khác và không che hoàn toàn giao diện bên dưới nó.

DialogFragment được Android đưa ra nhằm thay thế cho Dialog cũ ngày xưa. Dĩ nhiên là với DialogFragment thì chúng ta hoàn toàn có thể kế thừa được các callback từ vòng đời của Fragment. Chi tiết về vấn đề này sẽ được mình nói đến ở bài học về Dialog sắp tới đây.

Để xây dựng một DialogFragment “chơi chơi”, bạn vẫn có thể tạo mới một Blank Fragment và vẫn không check chọn vào Include fragment factory methods? hay Include interface callbacks?.

Mình giả sử với việc tạo một DialogFragment có tên là DialogFragmentSample.

Tạo DialogFragmentSample
Tạo DialogFragmentSample

Thì giao diện của nó, fragment_dialog_fragment_sample.xml sẽ đại loại như sau.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
 
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:padding="10dp"
        android:text="This is content of DialogFragment" />
 
</RelativeLayout>

Còn DialogFragmentSample.java, bạn nên kế thừa từ DialogFragment thay vì Fragment như các bài học trước. Chỉ cần một callback onCreateView() (hoặc onCreateDialog() mà bài học về Dialog chúng ta sẽ nói rõ hơn).

public class DialogFragmentSample extends DialogFragment {
 
    public DialogFragmentSample() {
        // Required empty public constructor
    }
 
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_dialog_fragment_sample, container, false);
        getDialog().setTitle("This is title");
        return view;
    }
}

activity_main.xml chúng ta có thể thiết kế tạm một Button.

<!-- Content -->
 
<LinearLayout
    android:id="@+id/activity_main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    tools:context="com.yellowcode.tournote.MainActivity">
 
    <Button
        android:id="@+id/activity_main_btn_show_dialogfragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Show DialogFragment"/>
 
</LinearLayout>

Để khi click vào Button đó ở MainActivity.java, chúng ta sẽ hiển thị DialogFragment như sau.

Button btnShowDislogFragment = (Button) findViewById(R.id.activity_main_btn_show_dialogfragment);
btnShowDislogFragment.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        DialogFragmentSample dialogFragmentSample = new DialogFragmentSample();
        dialogFragmentSample.show(getSupportFragmentManager(), "Dialog Fragment");
    }
});

Kết quả của các đoạn code này khi thực thi sẽ được giao diện như hình chụp mà hình ở phía trên.

PreferenceFragment

Minh họa PreferenceFragment

PreferenceFragment cũng kế thừa từ Fragment. Thành phần này mang lại cho chúng ta một tùy chọn cho việc xây dựng giao diện cho màn hình Cài đặt (Settings) của ứng dụng. Tất nhiên ứng dụng nào cũng sẽ có vài tùy chọn cho người dùng thiết lập các thông số, như cho phép hiện thông báo lên notification hay không, hay thiết lập âm thanh cho một số chức năng nào đó,… tất cả những tùy chọn này có thể được để vào trong màn hình Cài đặt. Và tất nhiên bạn có thể tự xây dựng loại màn hình này. Tuy nhiên, việc sử dụng PreferenceFragment sẽ cho chúng ta một giao diện Cài đặt đồng nhất trên các ứng dụng có sử dụng FreferenceFragment và cả đồng nhất với màn hình Cài đặt của hệ thống nữa.

Để nói sâu về cấu trúc của màn hình Cài đặt hay các thể loại Preference trong màn hình này là rất dài và nhiều kiến thức. Mình sẽ dành một bài riêng để nói về nó. Còn bài hôm nay chúng ta sẽ chỉ làm quen với các dòng code mẫu để hiểu thế nào là PreferenceFragment thôi nhé.

Để thử nghiệm “vọc” chơi PreferenceFragment, thì bạn có thể tạo một Blank Fragment với việc không check chọn vào Include fragment factory methods? hay Include interface callbacks?. Thậm chí chúng ta bỏ luôn cả check chọn Create layout XML?, vì Fragment loại này không cần đến giao diện, chúng ta sẽ dùng chính giao diện của hệ điều hành. Wow làm sao mà được như vậy? Mời bạn cùng xem tiếp.

Tạo PreferenceFragmentSample
Tạo PreferenceFragmentSample

Các phần sau đây của mục này mình sẽ nói khá vắn tắt nhưng cũng đủ để bạn muốn thử nghiệm.

Nói là không có giao diện cho PreferenceFragment, nhưng không hẳn là như vậy. Chúng ta chỉ dùng lại các loại Preference có sẵn từ Android, để làm giao diện cho nó, bạn có thể xem kỹ hơn về thông tin này ở link này.

Vậy việc đầu tiên sau khi chúng ta tạo PreferenceFragmentSample như trên kia, đó là thêm thư viện có hỗ trợ các loại Preference, chúng ta sẽ thêm vào dependencies của module. Nếu bạn chưa rõ lắm về cách thức thêm một thư viện vào dependencies thì có thể xem lại bài học này.

implementation 'androidx.preference:preference:1.1.0'

Và đây là “giao diện” của PreferenceFragment. Giao diện này được tạo ở thư mục res/xml/ với tên là preferences.xml. Nội dung của giao diện này chính là các Preference định nghĩa sẵn bởi hệ thống.

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
 
    <PreferenceCategory
        android:title="First Section" >
 
        <CheckBoxPreference
            android:key="checkbox_preference"
            android:title="Checkbox Preference"
            android:defaultValue="true" />
 
        <EditTextPreference
            android:key="edittext_preference"
            android:title="Edit Text Preference"
            android:summary="This is a sample edit text preference."
            android:dialogTitle="Dialog Edit Text Preference"
            android:dependency="checkbox_preference" />
 
    </PreferenceCategory>
 
    <PreferenceCategory
        android:title="Second Section" >
 
        <ListPreference
            android:key="list_preference"
            android:title="List Preference"
            android:dialogTitle="Dialog List Preference"
            android:entries="@array/entries_list_preference"
            android:entryValues="@array/entryvalues_list_preference" />
 
        <Preference
            android:title="Custom Intent" >
 
            <intent android:action="android.intent.action.VIEW"
                android:data="https://yellowcodebooks.com/" />
 
        </Preference>
 
    </PreferenceCategory>
 
</PreferenceScreen>

Giao diện này có sử dụng đến hai resource string array đã được khai báo như sau.

<string-array name="entries_list_preference">
    <item>Entry 1</item>
    <item>Entry 2</item>
    <item>Entry 3</item>
</string-array>
 
<string-array name="entryvalues_list_preference">
    <item>Value 1</item>
    <item>Value 2</item>
    <item>Value 3</item>
</string-array>

Đến PreferenceFragmentSample.java, chúng ta nên kế thừa từ PreferenceFragment, sau đó chỉ định “giao diện” của Fragment này chính là file preferences.xml mà chúng ta vừa tạo ra ở trên kia thông qua phương thức addPreferencesFromResource() như sau.

public class PreferenceFragmentSample extends PreferenceFragment {
 
    public PreferenceFragmentSample() {
        // Required empty public constructor
    }
 
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
 
        addPreferencesFromResource(R.xml.preferences);
    }
}

Bạn có thể gắn Fragment này theo kiểu tĩnh như với ListFragmentSample trên kia vào MainActivity cho nhanh. Kết quả của các đoạn code này khi thực thi sẽ được giao diện như hình chụp trên kia.

WebViewFragment

Chú ý: lần chỉnh sửa bài viết lần này của mình đối với bài học thứ 34 này mình phát hiện ra rằng lớp WebViewFragment đã bị Google loại bỏ từ phiên bản API level 28. Do đó kiến thức về WebViewFragment này chỉ còn là ký ức. Tuy nhiên mình cũng không xóa bỏ nội dung bài học lẫn code trên Github. Nội dung bài học và bài thực hành vẫn còn dưới đây, và link source code vẫn được để trên một branch riêng, nhưng từ các bài học sau, các source code này sẽ không xuất hiện trong TourNote của chúng ta nữa nhé. Chúng ta sẽ xây dựng màn hình hiển thị web này ở bài học liên quan khác.

Minh họa WebViewFragment
Minh họa WebViewFragment

Dĩ nhiên như các anh em của nó đã được nói đến trên kia, WebViewFragment cũng được kế thừa từ Fragment.

Trước hết, WebView là một vùng giao diện trên màn hình, mà ở đó chúng ta có thể hiển thị nội dung một trang web nào đó. Kiến thức về WebView rất thú vị, và mình dành một bài riêng để nói về nó sau này.

Vậy còn WebViewFragment thì sao? WebViewFragment cũng là một Fragment mở rộng từ Fragment gốc, giúp bạn thiết kế một Fragment với WebView bên trong nó một cách nhanh hơn. Bạn có thể không cần phải sử dụng WebViewFragment mới có thể đặt WebView vào trong nó, bản thân Fragment cũng có thể làm được. Code sau giúp bạn có cái nhìn ban đầu về WebView.

Để thử nghiệm WebViewFragment, bạn cũng nên tạo một Blank Fragment với việc không check chọn vào Include fragment factory methods? hay Include interface callbacks?. Bạn cũng nên bỏ luôn cả check chọn Create layout XML?, vì fragment loại này cũng không cần đến giao diện, vì là web mà, mọi giao diện đều dựa vào website hết cả rồi.

Tạo WebViewFragmentSample
Tạo WebViewFragmentSample

Một điều hiển nhiên khi hiển thị một website, đó là bạn phải cần kết nối mạng. Dù cho thiết bị của bạn đã có kết nối rồi, thì bạn vẫn cần phải xin quyền được sử dụng kết nối mạng của hệ thống thông qua thẻ uses-permission được định nghĩa thêm vào file AndroidManifest.xml bởi dòng sau.

<uses-permission android:name="android.permission.INTERNET" />

Như mình đã nói, chúng ta chẳng cần đến giao diện gì ráo, chỉ cần truyền url vào cho WebView như code dưới đây của file WebViewFragmentSample.java mà thôi.

public class WebViewFragmentSample extends WebViewFragment {
 
 
    public WebViewFragmentSample() {
        // Required empty public constructor
    }
 
 
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = super.onCreateView(inflater, container, savedInstanceState);
 
        getWebView().getSettings().setJavaScriptEnabled(true);
        getWebView().getSettings().setSupportZoom(true);
        getWebView().getSettings().setBuiltInZoomControls(true);
        getWebView().loadUrl("https://yellowcodebooks.com/");
 
        return view;
    }
 
}

Kết quả của việc thực thi ứng dụng khi này như hình minh họa đầu tiên của mục này.

Thực Hành Xây Dựng Fragment Cho TourNote

Đã lâu rồi chúng ta không xây dựng gì cho TourNote cả, đây là một sự buồn tẻ đúng không nào.

Hôm nay, sau khi đã trở thành “chuyên gia” trong lĩnh vực Fragment rồi, chúng ta cùng quay lại với nhau để xây đắp thêm các viên gạch mới cho ngôi nhà TourNote của chúng ta.

Ôn lại một tí những gì đã làm ở bài thực hành trước, đó là chúng ta đã làm sao cho ContactActivity “hiểu” được user đã chọn tùy chọn gì từ MainActivity thông qua Bundle. Khi đó, chúng ta có dùng Toast để hiển thị lên xem nội dung mà Bundle gửi qua là gì. Mọi thứ đã trơn tru.

Bài thực hành hôm nay chúng ta sẽ xây dựng một Fragment, Fragment này có nhiệm vụ hiển thị nội dung trang web tương ứng với những gì mà user đã chọn lựa. Cụ thể là, nếu từ MainActivity, nếu user chọn About app thì qua ContactActivity sẽ hiển thị trang Giới Thiệu, còn nếu user đã chọn Help thì qua ContactActivity sẽ hiển thị trang Liên Hệ. Nói rằng ContactActivity sẽ hiển thị, nhưng thực chất ContactActivity chứa đựng một WebViewFragment giúp đảm đương công việc này.

Tổ Chức Lại Package

Trước đây, do có rất ít file source code, nên chúng ta cứ tạo đại vào trong package mặc định của project như hình dưới đây.

Cách tổ chức package từ những bài học trước
Cách tổ chức package từ những bài học trước

Vấn đề sẽ trở nên rất phức tạp nếu như sau này chúng ta tạo ngày càng nhiều file source code. Vậy nhân tiện hôm nay, khi tạo mới một Fragment, chúng ta nên tổ chức các package sao cho có thể tách bạch giữa Activity và Fragment với nhau, khi đó bạn sẽ thấy project trở nên gọn gàng hơn như thế nào.

Đầu tiên, chúng ta nên tạo một package có tên là fragments. Package fragments này sẽ chứa đựng tất cả các Fragment sau này có thể có.

Để tạo mới một package trong Android Studio, bạn nên để vệt sáng vào package nào muốn tạo package con cho nó ở cửa sổ Project. Rồi chọn theo menu File > New > Package hoặc click phải chuột vào package đó rồi chọn như hình dưới đây.

Tạo mới một package
Tạo mới một package

Popup xuất hiện sau đó, bạn gõ vào tên package muốn tạo, trong trường hợp này chùng ta gõ “fragments”.

Khai báo tên của package sắp tạo
Khai báo tên của package sắp tạo

Bạn hãy làm tương tự để chúng ta có thêm một package nữa có tên activities. Kết quả của các package vừa mới tạo sẽ như sau.

Bạn hãy tạo sao cho có 2 package mới là activities và fragments
Bạn hãy tạo sao cho có 2 package mới là activities và fragments

Bước tiếp theo sau đó, bạn hãy click chọn cả hai ContactActivity và MainActivity ở cửa sổ Project bên trái rồi kéo chúng vào package activities vừa mới tạo cũng ở cửa sổ này. Popup xác nhận sau đó xuất hiện bạn cứ nhấn vào nút Refactor.

Kết quả cuối cùng chúng ta có được cấu trúc như sau.

Kéo ContactActivity và MainActivity vào packages activities
Kéo ContactActivity và MainActivity vào packages activities

Thật là đẹp đẽ. Giờ hãy tạo mới Fragment nào.

Tạo Mới Fragment

Chúng ta sẽ tạo mới một BlankFragment theo hướng dẫn ở bài trước, ở cửa sổ thiết lập Fragment mới bạn đặt tên Fragment này là AboutHelpFragment. Bạn nên nhớ không check chọn vào Create layout XML?, vì như mục trên kia có nói rằng giao diện của Fragment này chính là web. Nhưng nhớ phải check chọn vào Include fragment factory methods? để Fragment này có thể nhận dữ liệu đầu vào là url. Và phải nhớ tạo Fragment mới này bên trong package fragments nhé.

Tạo mới AboutHelpFragment
Tạo mới AboutHelpFragment

Khi đó cấu trúc project của chúng ta như sau.

Cấu trúc package sau khi thêm AboutHelpFragment
Cấu trúc package sau khi thêm AboutHelpFragment

Đừng Quên Permission

Như những gì bạn đã làm quen với WebView trên kia, ở bước này bạn cần định nghĩa một uses-permisson để ứng dụng có thể kết nối vào internet. Và đây là nội dung của file AndroidManifest.xml.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.yellowcode.tournote">

    <uses-permission android:name="android.permission.INTERNET"/>

    <supports-screens
        android:largeScreens="true"
        android:normalScreens="true"
        android:smallScreens="false"
        android:xlargeScreens="true" />

    <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=".activities.ContactActivity"></activity>
        <activity android:name=".activities.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Xây Dựng AboutHelpFragment

Như những gì bạn đã làm quen với code được tạo sẵn với SecondFragment ở bài học trước, và code của WebViewFragmentSample của bài hôm nay. Thì code của AboutHelpFragment sẽ trông như sau.

public class AboutHelpFragment extends WebViewFragment {

    private static final String ARG_URL = "url";

    private String mUrl;

    public AboutHelpFragment() {
        // Required empty public constructor
    }

    public static AboutHelpFragment newInstance(String url) {
        AboutHelpFragment fragment = new AboutHelpFragment();
        Bundle args = new Bundle();
        args.putString(ARG_URL, url);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mUrl = getArguments().getString(ARG_URL);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = super.onCreateView(inflater, container, savedInstanceState);

        getWebView().getSettings().setJavaScriptEnabled(true);
        getWebView().getSettings().setSupportZoom(true);
        getWebView().getSettings().setBuiltInZoomControls(true);
        getWebView().loadUrl(mUrl);

        return view;
    }

}

Chỉnh Sửa Giao Diện Của ContactActivity

Chúng ta sẽ dùng phương pháp hiển thị Fragment động. Dĩ nhiên rồi, vì còn tùy vào chọn lựa của user mà chúng ta sẽ thêm Fragment với url tương ứng vào cho ContactActivity mà.

Để hiển thị Fragment theo kiểu động như thế này, bạn đã biết, chúng ta cần có một FrameLayout trong activity_contact.xml như sau.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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"
    tools:context=".activities.ContactActivity">

    <FrameLayout
        android:id="@+id/contactMainFrame"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

    </FrameLayout>
</android.support.constraint.ConstraintLayout>

Thêm AboutHelpFragment Động Vào ContactActivity

Nào, code của ContactActivity.java bây giờ sẽ như sau.

public class ContactActivity extends AppCompatActivity {
 
    public static final String KEY_SHOW_WHAT = "show_what";
    public static final String VALUE_SHOW_ABOUT = "show_about";
    public static final String VALUE_SHOW_HELP = "show_help";
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_contact);
 
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setHomeButtonEnabled(true);
 
        Intent intent = getIntent();
        Bundle bundle = intent.getExtras();
        if (bundle != null) {
            String valueShow = bundle.getString(KEY_SHOW_WHAT, "");
 
            FragmentManager fragmentManager = getFragmentManager();
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            if (valueShow.equals(VALUE_SHOW_ABOUT)) {
                AboutHelpFragment aboutHelpFragment = AboutHelpFragment.newInstance("https://yellowcodebooks.com/about/");
                fragmentTransaction.add(R.id.contactMainFrame, aboutHelpFragment);
                fragmentTransaction.commit();
            } else if (valueShow.equals(VALUE_SHOW_HELP)) {
                AboutHelpFragment aboutHelpFragment = AboutHelpFragment.newInstance("https://yellowcodebooks.com/contact/");
                fragmentTransaction.add(R.id.contactMainFrame, aboutHelpFragment);
                fragmentTransaction.commit();
            }
        }
    }
 
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                finish();
                return true;
        }
 
        return super.onOptionsItemSelected(item);
    }
}

Download Source Code Mẫu

Bạn có thể download source code mẫu của bài này ở đây.

Chúng ta vừa kết thúc chuỗi bài học về Fragment. Bài học sau chúng ta sẽ tìm hiểu về Toolbar. Chúng ta sẽ xem giữa ToolbarActionBar mà chúng ta đã biết có mối liên hệ gì, và TourNote sẽ trở thành như thế nào sau khi khoác lên mình kỹ thuật mới mẻ này nữa nhé.

Cảm ơn bạn đã đọc các bài viết của Yellow Code Books. Bạn hãy ủng hộ blog bằng cách:

Đánh giá 5 sao ở mỗi bài nếu thấy thích.
Comment bên dưới mỗi bài nếu có thắc mắc.
Để lại địa chỉ email của bạn ở thanh bên phải để nhận được thông báo sớm nhất khi có bài viết mới.
Chia sẻ các bài viết của Yellow Code Books đến nhiều người khác.

Bài Kế Tiếp

Nào hãy xem Toolbar là gì, Toolbar khác với ActionBar như thế nào, và cùng nhau ứng dụng thành phần mới mẽ này lên giao diện của TourNote nhé.

10 comments

  1. sao chưa thấy bài mới nhỉ

    Rating: 4.3/5. From 3 votes.
    Please wait...
    1. Do Google một phần đấy bạn. Dạo gần đây Google liên tục tung ra các kiến thức mới, như bạn thấy mình phải chuyển sang nói về Android Architecture Component, xem kẽ vào các bài học Android, để kiến thức của chúng ta đừng bị lỗi thời í. Mình sẽ tranh thủ quay lại bài học chính Android nhanh thôi.

      No votes yet.
      Please wait...
  2. Chi tiết và dễ hiểu.. hóng bài tiếp bạn ơi!

    No votes yet.
    Please wait...
  3. Bài viết của anh rất hay, hóng các bài tiếp theo ạ. Btw, cảm ơn anh nhiều

    No votes yet.
    Please wait...
  4. hóng các bài tiếp theo

    Rating: 5.0/5. From 2 votes.
    Please wait...
  5. đang đợi bài mới của anh

    Rating: 5.0/5. From 2 votes.
    Please wait...
    1. Chào bạn và các bạn khác đang mong bài Android mới. Hic. Do khi mình viết đến bài này thì Google thay đổi Android nhiều quá, từ việc ko hỗ trợ các thư viện cũ, đến thay thế các code mới, rồi Android Studio cũng mới. Nên các bài viết của mình lỗi thời nhanh quá, giờ đọc lại từ các bài đầu sẽ rất khó để hiểu và áp dụng các bài của mình vào thực tế. Nên mình đang xem lại các bài cũ, và đang sửa lại chúng, nên sẽ mất khá nhiều thời gian để mình có thể viết tiếp. Mong các bạn thông cảm với mình nhé.

      Rating: 5.0/5. From 4 votes.
      Please wait...
  6. Đã theo dõi 34 bài viết của tác giả, thực sự rất hay và dễ hiểu. Mong tác giả sẽ cố gắng ra những bài tiếp theo của seri này ạ. Chúc tác giả nhiều thành công trong cuộc sống và công việc.

    No votes yet.
    Please wait...
    1. Cảm ơn bạn nhiều. Hiện mình đang viết bài 35 nhé.

      No votes yet.
      Please wait...
  7. Rất hay và bổ ích cho những người còn đang lang mang về kiến thức android… Mong anh có thêm bài viết để mọi người cùng nhau tham khảo ạ..

    No votes yet.
    Please wait...

Gửi phản hồi