Thêm một bước có hướng dẫn

Tạo dựng ứng dụng hiệu quả hơn với Compose
Tạo giao diện người dùng đẹp mắt mà không cần nhiều mã nguồn bằng Jetpack Compose cho hệ điều hành Android TV.

Ứng dụng của bạn có thể có các nhiệm vụ nhiều bước cho người dùng. Ví dụ: ứng dụng của bạn có thể cần hướng dẫn người dùng mua nội dung bổ sung, thiết lập một chế độ cài đặt cấu hình phức tạp hoặc chỉ đơn giản là xác nhận quyết định. Tất cả các tác vụ này yêu cầu hướng dẫn người dùng thực hiện một hoặc nhiều bước hoặc quyết định có thứ tự.

Thư viện androidx.leanback cung cấp các lớp để triển khai các tác vụ nhiều bước của người dùng. Trang này thảo luận cách sử dụng lớp GuidedStepSupportFragment để hướng dẫn người dùng thực hiện một loạt quyết định để hoàn thành một nhiệm vụ. GuidedStepSupportFragment áp dụng các phương pháp hay nhất về giao diện người dùng trên TV để giúp bạn dễ dàng hiểu và thao tác trên các thao tác gồm nhiều bước trên thiết bị TV.

Cung cấp thông tin chi tiết cho một bước

GuidedStepSupportFragment đại diện cho một bước trong chuỗi các bước. Về mặt trực quan, công cụ này cung cấp chế độ xem hướng dẫn kèm theo danh sách các hành động hoặc quyết định có thể thực hiện cho bước đó.

Hình 1. Một bước có hướng dẫn mẫu.

Đối với mỗi bước trong nhiệm vụ nhiều bước, hãy mở rộng GuidedStepSupportFragment và cung cấp thông tin ngữ cảnh về bước và hành động mà người dùng có thể thực hiện. Ghi đè onCreateGuidance() và trả về một GuidanceStylist.Guidance mới chứa thông tin ngữ cảnh, chẳng hạn như tiêu đề, nội dung mô tả và biểu tượng bước, như trong ví dụ sau:

Kotlin

override fun onCreateGuidance(savedInstanceState: Bundle?): GuidanceStylist.Guidance {
    return GuidanceStylist.Guidance(
            getString(R.string.guidedstep_first_title),
            getString(R.string.guidedstep_first_description),
            getString(R.string.guidedstep_first_breadcrumb),
            activity.getDrawable(R.drawable.guidedstep_main_icon_1)
    )
}

Java

@Override
public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) {
    String title = getString(R.string.guidedstep_first_title);
    String breadcrumb = getString(R.string.guidedstep_first_breadcrumb);
    String description = getString(R.string.guidedstep_first_description);
    Drawable icon = getActivity().getDrawable(R.drawable.guidedstep_main_icon_1);
    return new GuidanceStylist.Guidance(title, description, breadcrumb, icon);
}

Thêm lớp con GuidedStepSupportFragment vào hoạt động bạn muốn bằng cách gọi GuidedStepSupportFragment.add() trong phương thức onCreate() của hoạt động.

Nếu hoạt động của bạn chỉ chứa các đối tượng GuidedStepSupportFragment, hãy sử dụng GuidedStepSupportFragment.addAsRoot() thay vì add() để thêm GuidedStepSupportFragment đầu tiên. Việc sử dụng addAsRoot() giúp đảm bảo rằng nếu người dùng nhấn nút Quay lại trên điều khiển từ xa của TV khi xem GuidedStepSupportFragment đầu tiên, thì cả GuidedStepSupportFragment và hoạt động gốc đều đóng.

Lưu ý: Thêm các đối tượng GuidedStepSupportFragment theo phương thức lập trình, chứ không phải trong tệp XML bố cục.

Tạo và xử lý các thao tác của người dùng

Thêm hành động của người dùng bằng cách ghi đè onCreateActions(). Trong phần ghi đè, hãy thêm GuidedAction mới cho từng mục hành động và cung cấp chuỗi hành động, nội dung mô tả và mã nhận dạng. Sử dụng GuidedAction.Builder để thêm các thao tác mới.

Kotlin

override fun onCreateActions(actions: MutableList<GuidedAction>, savedInstanceState: Bundle?) {
    super.onCreateActions(actions, savedInstanceState)

    // Add "Continue" user action for this step
    actions.add(GuidedAction.Builder()
            .id(CONTINUE)
            .title(getString(R.string.guidedstep_continue))
            .description(getString(R.string.guidedstep_letsdoit))
            .hasNext(true)
            .build())
    ...

Java

@Override
public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
    // Add "Continue" user action for this step
    actions.add(new GuidedAction.Builder()
           .id(CONTINUE)
           .title(getString(R.string.guidedstep_continue))
           .description(getString(R.string.guidedstep_letsdoit))
           .hasNext(true)
           .build());
...

Các thao tác không bị giới hạn ở việc chọn một dòng. Dưới đây là một số loại thao tác khác mà bạn có thể tạo:

  • Thêm thao tác đối với nhãn thông tin để cung cấp thêm thông tin về các lựa chọn của người dùng bằng cách thiết lập infoOnly(true). Khi infoOnly là đúng, người dùng sẽ không thể chọn thao tác này.
  • Thêm một thao tác có thể chỉnh sửa cho văn bản bằng cách thiết lập editable(true). Khi giá trị editable là true, người dùng có thể nhập văn bản vào một thao tác đã chọn bằng điều khiển từ xa hoặc bàn phím đã kết nối. Ghi đè onGuidedActionEditedAndProceed() để lấy văn bản sửa đổi mà người dùng đã nhập. Bạn cũng có thể ghi đè onGuidedActionEditCanceled() để biết thời điểm người dùng huỷ dữ liệu nhập.
  • Thêm một tập hợp các thao tác hoạt động như các nút chọn có thể đánh dấu bằng cách sử dụng checkSetId() với giá trị mã nhận dạng phổ biến để nhóm các thao tác thành một tập hợp. Tất cả các thao tác trong cùng một danh sách có cùng mã nhóm kiểm tra đều được coi là đã liên kết. Khi người dùng chọn một trong các hành động trong tập hợp đó, hành động đó sẽ được đánh dấu và tất cả các hành động khác sẽ bị bỏ đánh dấu.
  • Thêm một thao tác đối với bộ chọn ngày bằng cách sử dụng GuidedDatePickerAction.Builder thay vì GuidedAction.Builder trong onCreateActions(). Ghi đè onGuidedActionEditedAndProceed() để lấy giá trị ngày sửa đổi mà người dùng đã nhập.
  • Thêm một thao tác sử dụng các thao tác phụ để cho phép người dùng chọn trong một danh sách mở rộng gồm các lựa chọn. Thao tác phụ được mô tả trong phần Thêm tiểu mục.
  • Thêm một thao tác bằng nút xuất hiện ở bên phải danh sách thao tác và dễ dàng truy cập được. Các thao tác của nút được mô tả trong phần Thêm thao tác của nút.

Bạn cũng có thể thêm chỉ báo trực quan cho biết việc chọn một hành động sẽ dẫn đến một bước mới bằng cách đặt hasNext(true).

Đối với tất cả các thuộc tính mà bạn có thể thiết lập, hãy xem GuidedAction.

Để phản hồi các thao tác, hãy ghi đè onGuidedActionClicked() và xử lý GuidedAction được truyền vào. Xác định hành động đã chọn bằng cách kiểm tra GuidedAction.getId().

Thêm các hành động phụ

Một số thao tác có thể yêu cầu bạn cung cấp cho người dùng một nhóm lựa chọn bổ sung. GuidedAction có thể chỉ định một danh sách các thao tác con xuất hiện dưới dạng trình đơn gồm các thao tác con.

Hình 2. Các bước phụ theo bước có hướng dẫn.

Danh sách hành động phụ có thể chứa các thao tác thông thường hoặc thao tác qua nút chọn, nhưng không chứa bộ chọn ngày hoặc các thao tác văn bản có thể chỉnh sửa. Ngoài ra, một hành động phụ không thể có tập hợp các hành động phụ riêng vì hệ thống không hỗ trợ nhiều hơn một cấp độ của các hành động phụ.

Để thêm hành động phụ, trước tiên, hãy tạo và điền danh sách các đối tượng GuidedAction đóng vai trò là hành động phụ, như trong ví dụ sau:

Kotlin

subActions.add(GuidedAction.Builder()
        .id(SUBACTION1)
        .title(getString(R.string.guidedstep_subaction1_title))
        .description(getString(R.string.guidedstep_subaction1_desc))
        .build())
...

Java

List<GuidedAction> subActions = new ArrayList<GuidedAction>();
subActions.add(new GuidedAction.Builder()
       .id(SUBACTION1)
       .title(getString(R.string.guidedstep_subaction1_title))
       .description(getString(R.string.guidedstep_subaction1_desc))
       .build());
...

Trong onCreateActions(), hãy tạo một GuidedAction cấp cao nhất để hiển thị danh sách các thao tác phụ khi được chọn:

Kotlin

    ...
    actions.add(GuidedAction.Builder()
            .id(SUBACTIONS)
            .title(getString(R.string.guidedstep_subactions_title))
            .description(getString(R.string.guidedstep_subactions_desc))
            .subActions(subActions)
            .build())
    ...

Java

@Override
public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
...
    actions.add(new GuidedAction.Builder()
           .id(SUBACTIONS)
           .title(getString(R.string.guidedstep_subactions_title))
           .description(getString(R.string.guidedstep_subactions_desc))
           .subActions(subActions)
           .build());
...
}

Cuối cùng, hãy phản hồi các lựa chọn hành động phụ bằng cách ghi đè onSubGuidedActionClicked():

Kotlin

override fun onSubGuidedActionClicked(action: GuidedAction): Boolean {
    // Check for which action was clicked and handle as needed
    when(action.id) {
        SUBACTION1 -> {
            // Subaction 1 selected
        }
    }
    // Return true to collapse the subactions menu or
    // false to keep the menu expanded
    return true
}

Java

@Override
public boolean onSubGuidedActionClicked(GuidedAction action) {
   // Check for which action was clicked and handle as needed
   if (action.getId() == SUBACTION1) {
       // Subaction 1 selected
   }
   // Return true to collapse the subactions menu or
   // false to keep the menu expanded
   return true;
}

Thêm các thao tác của nút

Nếu bước có hướng dẫn của bạn có nhiều thao tác, thì người dùng có thể phải cuộn qua danh sách để truy cập những thao tác thường dùng nhất. Sử dụng các thao tác của nút để tách các thao tác thường dùng khỏi danh sách thao tác. Các thao tác bằng nút sẽ xuất hiện bên cạnh danh sách thao tác và rất dễ thao tác.

Hình 3. Các thao tác trên nút bước có hướng dẫn.

Các thao tác của nút được tạo và xử lý giống như các thao tác thông thường, nhưng bạn sẽ tạo các thao tác với nút trong onCreateButtonActions() thay vì onCreateActions(). Phản hồi các thao tác của nút trong onGuidedActionClicked().

Sử dụng thao tác trên nút cho các thao tác đơn giản, chẳng hạn như thao tác di chuyển giữa các bước. Không sử dụng hành động bộ chọn ngày hoặc các thao tác có thể chỉnh sửa khác làm thao tác trên nút. Ngoài ra, thao tác của nút không được có hành động phụ.

Nhóm các bước có hướng dẫn thành một trình tự có hướng dẫn

GuidedStepSupportFragment đại diện cho một bước duy nhất. Để tạo một trình tự các bước theo thứ tự, hãy nhóm nhiều đối tượng GuidedStepSupportFragment lại với nhau bằng cách sử dụng GuidedStepSupportFragment.add() để thêm bước tiếp theo trong trình tự vào ngăn xếp mảnh.

Kotlin

override fun onGuidedActionClicked(action: GuidedAction) {
    val fm = fragmentManager
    when(action.id) {
        CONTINUE -> GuidedStepSupportFragment.add(fm, SecondStepFragment())
    }
}

Java

@Override
public void onGuidedActionClicked(GuidedAction action) {
    FragmentManager fm = getFragmentManager();
    if (action.getId() == CONTINUE) {
       GuidedStepSupportFragment.add(fm, new SecondStepFragment());
    }
...

Nếu người dùng nhấn nút Back (Quay lại) trên điều khiển từ xa của TV, thiết bị sẽ hiện GuidedStepSupportFragment trước đó trên ngăn xếp mảnh. Nếu cung cấp GuidedAction của riêng mình để trả về bước trước, bạn có thể triển khai hành vi Quay lại bằng cách gọi getFragmentManager().popBackStack(). Nếu bạn cần đưa người dùng quay lại một bước trước đó trong trình tự, hãy sử dụng popBackStackToGuidedStepSupportFragment() để quay lại một GuidedStepSupportFragment cụ thể trong ngăn xếp mảnh.

Khi người dùng hoàn tất bước cuối cùng trong trình tự, hãy sử dụng finishGuidedStepSupportFragments() để xoá tất cả các thực thể GuidedStepSupportFragment khỏi ngăn xếp hiện tại rồi quay lại hoạt động gốc ban đầu. Nếu GuidedStepSupportFragment đầu tiên được thêm vào bằng addAsRoot(), thì việc gọi finishGuidedStepSupportFragments() cũng đóng hoạt động gốc.

Tuỳ chỉnh cách trình bày theo bước

Lớp GuidedStepSupportFragment có thể sử dụng giao diện tuỳ chỉnh kiểm soát các khía cạnh trình bày, chẳng hạn như định dạng văn bản tiêu đề hoặc ảnh động chuyển đổi từng bước. Giao diện tuỳ chỉnh phải kế thừa từ Theme_Leanback_GuidedStep, đồng thời có thể cung cấp giá trị ghi đè cho các thuộc tính được xác định trong GuidanceStylistGuidedActionsStylist.

Để áp dụng giao diện tuỳ chỉnh cho GuidedStepSupportFragment, hãy làm theo một trong những cách sau:

  • Áp dụng giao diện cho hoạt động gốc bằng cách đặt thuộc tính android:theme thành phần tử hoạt động trong tệp kê khai Android. Việc đặt thuộc tính này sẽ áp dụng giao diện cho tất cả các khung hiển thị con và là cách đơn giản nhất để áp dụng một giao diện tuỳ chỉnh nếu hoạt động gốc chỉ chứa các đối tượng GuidedStepSupportFragment.
  • Nếu hoạt động của bạn đã sử dụng giao diện tuỳ chỉnh và bạn không muốn áp dụng kiểu GuidedStepSupportFragment cho các thành phần hiển thị khác trong hoạt động, hãy thêm thuộc tính LeanbackGuidedStepTheme_guidedStepTheme vào giao diện tuỳ chỉnh hiện có cho hoạt động. Thuộc tính này trỏ đến giao diện tuỳ chỉnh mà chỉ các đối tượng GuidedStepSupportFragment trong hoạt động của bạn sử dụng.
  • Nếu bạn sử dụng đối tượng GuidedStepSupportFragment trong nhiều hoạt động thuộc cùng một tác vụ nhiều bước tổng thể và muốn sử dụng một giao diện hình ảnh nhất quán trong tất cả các bước, hãy ghi đè GuidedStepSupportFragment.onProvideTheme() và trả về giao diện tuỳ chỉnh của bạn.

Để biết thêm thông tin về cách thêm kiểu và giao diện, hãy xem bài viết Kiểu và giao diện.

Lớp GuidedStepSupportFragment sử dụng các lớp tạo mẫu đặc biệt để truy cập và áp dụng các thuộc tính giao diện. Lớp GuidanceStylist sử dụng thông tin giao diện để kiểm soát cách trình bày khung hiển thị hướng dẫn bên trái, trong khi lớp GuidedActionsStylist sử dụng thông tin giao diện để kiểm soát việc trình bày khung hiển thị hành động bên phải.

Để tuỳ chỉnh kiểu hình ảnh của các bước ngoài những tính năng tuỳ chỉnh giao diện cung cấp, hãy tạo lớp con GuidanceStylist hoặc GuidedActionsStylist và trả về lớp con trong GuidedStepSupportFragment.onCreateGuidanceStylist() hoặc GuidedStepSupportFragment.onCreateActionsStylist(). Để biết thông tin chi tiết về những nội dung bạn có thể tuỳ chỉnh trong các lớp con này, vui lòng xem tài liệu về GuidanceStylistGuidedActionsStylist.