Tạo những khoảnh khắc kỳ diệu cùng với Picture in Picture

1. Giới thiệu

Picture in Picture (PIP) là một tính năng kỳ diệu mang lại cho người sử dụng một trải nghiệm thú vị. PIP là một trường hợp đặc biệt của giao diện đa cửa sổ(multi-window UI). Việc xem video và sử dụng camera có thể được tăng cường hiệu quả bằng cách sử dụng PIP. Ví dụ: trong khi xem YouTube, bạn có thể chọn một video khác để thêm vào danh sách phát của bạn trong khi tiếp tục xem video hiện tại vì video chạy đang chuyển sang chế độ PIP. Đây là một khoảnh khắc huyền diệu cho phép bạn thoải mái làm hai việc cùng một lúc.

Một cách sử dụng tuyệt vời khác của PIP là kiểm tra lịch của bạn trong khi bạn đang trò chuyện video. Video có thể co lại và di chuyển xuống góc màn hình và cho phép bạn kiểm tra các cuộc hẹn của bạn. Bạn có thể tham gia vào cuộc trò chuyện trong khi hoàn thành một tác vụ khác như hình bên dưới.

2. Sử dụng PIP vào trong ứng dụng của bạn

Bắt đầu từ Android 8.0(API Level 26), bạn có thể dễ dàng đưa Activity của mình vào chế độ PIP. Activity của bạn phải khai baos rằng nó hỗ trợ PIP. Trong file Manifest.xml của bạn, bạn phải đặt cờ supportPictureInPicture thành true.

<activity 
    android:name=".MediaSessionPlaybackActivity"
    ...
    android:supportsPictureInPicture="true" />

3. Sử dụng PIP vào thời điểm nào thì thích hợp?

Có vài thời điểm thích hợp để vào chế độ PIP. Cách sử dụng đơn giản nhất là với một Button hoặc một Menu Item. Material Design của google đã cũng cấp cho chúng ta các biểu tưởng PIP chuẩn nhất. Tuy nhiên tùy chọn vào cách sử dụng mà icon đó có ý nghĩa hơn trong ứng dụng của bạn. Picture in Picture icon Alternative Picture in Picture icon Icon sẽ chỉ ra trạng thái của PIP. Ví dụ: nếu cửa sổ PIP của bạn hiển thị ở trên cùng bên phải của màn hình, hãy sử dụng một icon Picture In Picture thứ nhất để cho người dùng một gợi ý tinh tế về những gì mong đợi.

4. PIP thay thế cho việc chuyển đổi ứng dụng

Việc sử dụng PIP thay vì phải thoát khỏi ứng dụng thì thực sự hữu ích. Ví dụ khi người dùng bấm HOME BUTTON hay BACK BUTTON

PIP có thể là trải nghiệm tốt hơn là đóng ứng dụng của bạn.

Khi người nhấn BACK BUTTON, có thể có ích khi nhập chế độ PIP thay vì đóng một video đang chạy. Chẳng hạn như người dùng đang duyệt web để xem nhiều nội dung hơn và có thể tiếp tục xem chương trình gốc ở chế độ PIP. Nếu ứng dụng của bạn sử dụng PIP theo cách này, thì nên đảm bảo cung cấp tùy chọn để loại bỏ cửa sổ PIP. Nếu người dùng chọn HOME BUTTON, RECENT APPS hoặc mở NOTIFICATION trong khi đang bật một cuộc gọi điện video hoặc xem một video, có thể tiện lợi hơn nếu sử dụng PIP thay vì thoát khỏi ứng dụng. Android Activity Lifecycle có một method được gọi lại mỗi khi người dùng rời khỏi ứng dụng. Bạn có thể override onUserLeaveHint() như giải thích ở bên trên thì bật chế độ PIP thay vì tắt app.

5. Tìm hiểu sâu hơn về PIP

Khi ở trong chế độ PIP, bạn nên ẩn mọi thứ đi ngoại trừ cái gì quan trọng nhất trong ứng dụng của bạn. Trong hầu hết các trường hợp thì thứ quan trọng nhất đó sẽ là video hoặc máy ảnh. Trước khi bật PIP, bạn nên chuẩn bị bằng cách thực hiện các bước sau :

  1. Ẩn tất cả các Control hoặc Overlay nằm trên Views. Ví dụ: Ẩn các nút điều khiển video playback (các nút play, pause , v.v.v) hoặc trình đơn tùy chọn máy ảnh.
  2. Tạo một PictureInPictureParams.Builder
  3. Đặt tỉ lệ khung hình dựa trên ché độ xem của bạn. Ví dụ Google Map navigation có chế độ dọc tại PIP trong khi đó các video trên Youtube lại xuất hiện trong một cửa sổ nằm ngang.
  4. Tùy chọn thêm hành động tùy chỉnh. Ví dụ: cung cấp tua lại / chuyển tiếp nhanh về phát lại video hoặc tắt tiếng cho các cuộc gọi điện video.
  5. Tùy chọn thiết lập một Rect bounds để làm mịn quá trình chuyển đổi cho các hoạt động vào PIP. Ví dụ bật chế độ PIP khi bấm vào 1 nút
void minimize() {
    if (mMovieView == null) {
        return;
    }
    // Hide the controls in picture-in-picture mode.
    mMovieView.hideControls();
    // Calculate the aspect ratio of the PIP screen.
    Rational aspectRatio = new Rational(
                mMovieView.getWidth(), mMovieView.getHeight());
    PictureInPictureParams params = mPictureInPictureParamsBuilder
        .setAspectRatio(aspectRatio)
        .build();
    enterPictureInPictureMode(params);
}

Dưới đây là ví dụ về sử dụng onUserLeaveHint() để bắt việc chuyển đổi ứng dụng và nhập PIP dưới dạng tác dụng phụ (side-effect). Không yêu cầu một tương tác gì từ phía người dùng

public class MyPictureInPictureActivity extends AppCompatActivity {
    ...
    @Override
    protected void onUserLeaveHint() {
        super.onUserLeaveHint();
        PictureInPictureParams params = 
            new PictureInPictureParams.Builder()
                // Set actions or aspect ratio.
                .build();
        enterPictureInPictureMode(params);
    }
    ...
}

Bạn nên tạo PictureInPictureParams để truyền qua hàm enterPictureInPictureMode. Có một method được overload mà không có các tham số được deprecated. Android Studio có thể giúp đảm bảo rằng bạn sẽ không sử dụng các API đã bị deprecated.

6. Chuyển đổi bật tắt chế độ PIP

Bật chế độ PIP là khá dễ dàng, nhưng nếu người dùng khôi phục cửa sổ của bạn để toàn màn hình?. Bạn nên khôi phục lại hoạt động của mình như trước khi nhập PIP. Ví dụ như hiển thị các trình điều khiển video playback mà bạn đã ẩn đi. Activity đã có 1 callback là onPictureInPictureModeChanged() . Bạn có thể override lại nó để lắng nghe sự kiện. Trong Fragment cũng có một sự kiện như vậy. Nếu người dùng khôi phục cửa sổ để toàn màn hình, isInPictureInPictureMode sẽ là false.

@Override
public void onPictureInPictureModeChanged (
        boolean isInPictureInPictureMode, Configuration newConfig) {
    if (isInPictureInPictureMode) {
        // Hide the full-screen UI (controls, etc.) while in
        // picture-in-picture mode.
        ...
    } else {
       // Restore the full-screen UI.
        ...
    }
}

7. Thêm các tùy chỉnh hành động người dùng

Mặc dù bạn nên đơn giản hóa giao diện người dùng khi ở chế độ PIP, bạn vẫn có thể cho phép người dùng tương tác với các hành động remote. PictureInPictureParams.BuildersetActions() để tạo ra một danh sách các RemoteAction. Nếu có nhiều hơn getMaxNumPictureInPictureActions() hành động, danh sách đầu vào sẽ được cắt ngắn để phù hợp với số đó. Bạn có thể thêm các hành động đơn giản tùy chỉnh để bảo vệ một số tính năng toàn màn hình của bạn, chẳng hạn như chuyển đổi phát / tạm dừng. Ứng dụng mẫu, xác định hai hành động tùy chỉnh; một chuyển đổi chạy / tạm dừng và yêu cầu thông tin. Đây là ảnh PIP đã được tùy chỉnh Nếu bạn đang sử dụng MediaSession để phát lại video, khuôn khổ sẽ tự động nhận ra phiên và thêm các hành động để chơi / tạm dừng, bỏ qua và bỏ qua trước đó. Các hành động được xử lý bởi các phương pháp tương ứng trong MediaSession.Callback Các hành động mặc định khi sử dụng MediaSession

Các hành động được tự động kích hoạt và vô hiệu hóa tùy thuộc vào trạng thái MediaSession. Trong hình dưới đây, trạng thái MediaSession được thiết lập để PlaybackStateCompat.ACTION_PLAY_PAUSE | PlaybackStateCompat.ACTION_SKIP_TO_NEXT Nếu bạn không cần bất kỳ hoặc tất cả các hành động được cung cấp bởi MediaSession, hãy gọi setActions () để chỉ định những hành động bạn muốn.

8. Tổng kết

Để quyết định khi nào sử dụng PIP là phần khó nhất. PIP có thể làm cho ứng dụng của bạn cảm thấy tuyệt với bằng khách suy luận ý định của người dùng hoặc nó có thể làm cho họ cảm thấy khó chịu và gây phiền nhiễu. Nên bạn hãy cân nhác khi sử dụng PIP. Các cách ứng dụng PIP phổ biến nhất sẽ là :

  1. Kích hoạt từ một nút : onClicked(View), onOptionsItemSelected(MenuItem)...
  2. Kích hoạt khi người dùng thoát khỏi app : onUserLeaveHint()
  3. Kích hoạt từ các phím cứng : onBackPressed()

9. Tiếp tục tìm hiểu về PIP

Bạn có thể tìm hiểu các bài viết và các tài liệu trainning để tiếp tục tìm hiểu về PIP như :