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

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

Thư viện Leanback androidx cung cấp các lớp để triển khai những tác vụ người dùng nhiều bước. Trang này thảo luận về 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 TV để giúp các thao tác có nhiều bước trở nên dễ hiểu và thao tác dễ dàng trên thiết bị TV.

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

GuidedStepSupportFragment đại diện cho một bước duy nhất trong một loạt các bước. Rõ ràng, nó cung cấp khung hiển thị hướng dẫn kèm theo danh sách các thao tác 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 tác vụ nhiều bước của bạn, hãy mở rộng GuidedStepSupportFragment và cung cấp thông tin ngữ cảnh về bước đó cũng như các 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ư tên bước, nội dung mô tả và biểu tượng 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 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 sẽ đóng.

Lưu ý: Hãy thêm đố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ý 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 chế độ 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. Hãy dùng GuidedAction.Builder để thêm 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());
...

Hành động không bị giới hạn ở những lựa chọn trên một dòng. Dưới đây là những loại thao tác khác mà bạn có thể tạo:

  • Thêm thao tác với nhãn thông tin để cung cấp thêm thông tin về lựa chọn của người dùng bằng cách thiết lập infoOnly(true). Khi infoOnly là true, người dùng sẽ không thể chọn thao tác đó.
  • Thêm một thao tác có thể chỉnh sửa đối với văn bản bằng cách thiết lập editable(true). Khi 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() để nhận 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ỷ phương thức nhập.
  • Thêm một tập hợp 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() có giá trị mã nhận dạng chung để nhóm các thao tác thành một tập hợp. Tất cả hành động 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ẽ được bỏ đánh dấu.
  • Thêm thao tác bộ chọn ngày bằng cách sử dụng GuidedDatePickerAction.Builder thay vì GuidedAction.Builder trong onCreateActions(). Ghi đè onGuidedActionEditedAndProceed() để nhận giá trị ngày sửa đổi mà người dùng đã nhập.
  • Thêm một hành động sử dụng thao tác phụ để người dùng chọn trong một danh sách mở rộng các lựa chọn. Hành động phụ được mô tả trong phần Thêm hành động phụ.
  • Thêm một thao tác của 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 thao tác trên nút được mô tả trong phần Thêm thao tác cho nút.

Bạn cũng có thể thêm chỉ báo trực quan rằng 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).

Để biết mọi thuộc tính mà bạn có thể đặt, hãy xem GuidedAction.

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

Thêm hành động phụ

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

Hình 2. Hành động phụ 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 trên nút chọn, nhưng không chứa các thao tác như bộ chọn ngày hoặc văn bản có thể chỉnh sửa. Ngoài ra, một tác vụ phụ không thể có tập hợp tác vụ phụ riêng vì hệ thống không hỗ trợ nhiều cấp độ phụ.

Để thêm các 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 hành động 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 thao tác của nút

Nếu bước hướng dẫn của bạn có một danh sách lớn các thao tác, thì người dùng có thể phải cuộn qua danh sách để truy cập vào các thao tác thường dùng nhất. Hãy sử dụng các thao tác trên 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 của nút sẽ xuất hiện bên cạnh danh sách thao tác và bạn có thể dễ dàng điều hướng đến đó.

Hình 3. Thao tác của nút Bước có hướng dẫn.

Các thao tác trên 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 nút trong onCreateButtonActions() thay vì onCreateActions(). Phản hồi các thao tác của nút trong onGuidedActionClicked().

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. Đừng sử dụng hành động bộ chọn ngày hoặc các hành động có thể chỉnh sửa khác làm hành động cho nút. Ngoài ra, các hành động 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 Quay lại trên điều khiển từ xa của TV, thì 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 quay 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 trở về 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ả thực thể GuidedStepSupportFragment khỏi ngăn xếp hiện tại và quay lại hoạt động gốc ban đầu. Nếu GuidedStepSupportFragment đầu tiên được thêm bằng addAsRoot(), việc gọi finishGuidedStepSupportFragments() cũng sẽ đóng hoạt động mẹ.

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

Lớp GuidedStepSupportFragment có thể sử dụng các 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 tiếp bước. Giao diện tuỳ chỉnh phải kế thừa từ Theme_Leanback_GuidedStep và 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 mẹ 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ả khung hiển thị con và là cách đơn giản nhất để áp dụng giao diện tuỳ chỉnh nếu hoạt động mẹ chỉ chứa các đối tượng GuidedStepSupportFragment.
  • Nếu hoạt động của bạn đã sử dụng một giao diện tuỳ chỉnh và bạn không muốn áp dụng kiểu GuidedStepSupportFragment cho các khung hiển thị khác trong hoạt động đó, hãy thêm thuộc tính LeanbackGuidedStepTheme_guidedStepTheme vào giao diện hoạt động tuỳ chỉnh hiện có. 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 nhiệm 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.

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

Lớp GuidedStepSupportFragment sử dụng các lớp stylist đặ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 cách trình bày khung hiển thị thao tác phù hợp.

Để tuỳ chỉnh kiểu hình ảnh của các bước ngoài nhữ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, hãy xem tài liệu về GuidanceStylistGuidedActionsStylist.