ชุดเครื่องมือ Leanback UI มีตัวควบคุมการเล่นที่ช่วยให้ ประสบการณ์ของผู้ใช้ สำหรับแอปวิดีโอ การควบคุมการส่งจะรองรับการสครับวิดีโอ ด้วยตัวควบคุมไปข้างหน้าและข้างหลัง ขณะสครับจอแสดงผล เพื่อช่วยนำทางไปยังส่วนต่างๆ ของวิดีโอ
ไลบรารีนี้มีชั้นเรียน Abstract รวมถึงการนำไปใช้งานสำเร็จรูป ซึ่งมอบการควบคุมที่ละเอียดยิ่งขึ้นสำหรับนักพัฒนาซอฟต์แวร์ ใช้รูปแบบที่สร้างไว้ล่วงหน้า คุณสามารถสร้างแอปที่มีฟีเจอร์เพียบพร้อมได้อย่างรวดเร็วโดยไม่ต้องเขียนโค้ดมากนัก หากต้องการการปรับแต่งเพิ่มเติม คุณสามารถขยายไลบรารีที่สร้างไว้ล่วงหน้า คอมโพเนนต์
ตัวควบคุมและโปรแกรมเล่น
ชุดเครื่องมือ Leanback UI จะแยก UI ตัวควบคุมการส่งออกจาก โปรแกรมเล่นที่เล่นวิดีโอ โดยมีองค์ประกอบ 2 ส่วน ได้แก่ ส่วนย่อยการสนับสนุนการเล่น สำหรับแสดงตัวควบคุมการส่ง (และ วิดีโอ (ไม่บังคับ)) และอะแดปเตอร์โปรแกรมเล่นเพื่อประกอบมีเดียเพลเยอร์
ส่วนย่อยการเล่น
กิจกรรม UI ของแอปควรใช้
PlaybackSupportFragment
หรือ
VideoSupportFragment
ทั้ง 2 อย่างมีตัวควบคุมการนำส่ง Leanback ดังนี้
PlaybackSupportFragment
จะเคลื่อนไหวตัวควบคุมการรับส่งข้อมูลเพื่อซ่อน/แสดงตามความจำเป็นVideoSupportFragment
จะขยายPlaybackSupportFragment
และมีSurfaceView
ในการแสดงผลวิดีโอ
คุณสามารถปรับแต่งตัวแปร
ObjectAdapter
เพื่อปรับปรุง UI ตัวอย่างเช่น ให้ใช้
setAdapter()
เพื่อเพิ่ม "วิดีโอที่เกี่ยวข้อง" แถว
อะแดปเตอร์โปรแกรมเล่น
PlayerAdapter
เป็นคลาสนามธรรมที่
ควบคุมมีเดียเพลเยอร์เบื้องหลัง นักพัฒนาซอฟต์แวร์สามารถเลือก
การใช้งาน MediaPlayerAdapter
ที่สร้างไว้ล่วงหน้าหรือเขียน
การนำชั้นเรียนนี้ไปใช้ด้วยตนเอง
ปะติดปะต่อชิ้นส่วนเข้าด้วยกัน
คุณต้องใช้ "กาวควบคุม" บางอย่าง เพื่อเชื่อมต่อส่วนย่อยการเล่น ในโปรแกรมเล่น Leanback ไลบรารีมีกาว 2 ชนิด ได้แก่
PlaybackBannerControlGlue
เสมอ ตัวควบคุมการนำส่งในส่วนการเล่นใน "สไตล์เก่า" โดยวาง ในพื้นหลังที่ทึบแสง (PlaybackBannerControlGlue
รายการ แทนที่PlaybackControlGlue
ซึ่งเลิกใช้งานแล้ว)PlaybackTransportControlGlue
ใช้ "รูปแบบใหม่" บนพื้นหลังโปร่งใส
หากต้องการให้แอปรองรับการสครับวิดีโอ คุณต้องใช้
PlaybackTransportControlGlue
คุณต้องระบุ "Glue Host" ด้วย นั่น
เชื่อมโยงกาวเข้ากับการเล่น
Fragment จะวาดตัวควบคุมการส่งใน UI และรักษาสถานะไว้ และ
ส่งผ่านเหตุการณ์ควบคุมการขนส่งกลับไปยังกาว โฮสต์ต้องตรงกับประเภทส่วนย่อยการเล่น ใช้
PlaybackSupportFragmentGlueHost
ด้วย
PlaybackFragment
และ
VideoSupportFragmentGlueHost
ที่มี
VideoFragment
ภาพต่อไปนี้แสดงวิธีที่ตัวควบคุมการลำเลียงสารเอนหลัง เข้ากันได้ดี:
โค้ดที่รวมแอปของคุณเข้าด้วยกันควรอยู่ภายใน
PlaybackSupportFragment
หรือ VideoSupportFragment
ที่กำหนด UI
ในรายการต่อไปนี้
ตัวอย่างเช่น แอปจะสร้างอินสแตนซ์ของ PlaybackTransportControlGlue
ตั้งชื่อว่า playerGlue
และเชื่อมต่อ VideoSupportFragment
กับ MediaPlayerAdapter
ที่สร้างขึ้นใหม่ ตั้งแต่ปี
นี่คือ VideoSupportFragment
รหัสการตั้งค่าเรียก setHost()
เพื่อแนบ
VideoSupportFragmentGlueHost
ถึง playerGlue
รหัสจะรวมอยู่ในชั้นเรียน
ที่ขยาย VideoSupportFragment
Kotlin
class MyVideoFragment : VideoSupportFragment() { fun onCreate(savedInstanceState: Bundle) { super.onCreate(savedInstanceState) val playerGlue = PlaybackTransportControlGlue(getActivity(), MediaPlayerAdapter(getActivity())) playerGlue.setHost(VideoSupportFragmentGlueHost(this)) playerGlue.addPlayerCallback(object : PlaybackGlue.PlayerCallback() { override fun onPreparedStateChanged(glue: PlaybackGlue) { if (glue.isPrepared()) { playerGlue.seekProvider = MySeekProvider() playerGlue.play() } } }) playerGlue.setSubtitle("Leanback artist") playerGlue.setTitle("Leanback team at work") val uriPath = "android.resource://com.example.android.leanback/raw/video" playerGlue.getPlayerAdapter().setDataSource(Uri.parse(uriPath)) } }
Java
public class MyVideoFragment extends VideoSupportFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final PlaybackTransportControlGlue<MediaPlayerAdapter> playerGlue = new PlaybackTransportControlGlue(getActivity(), new MediaPlayerAdapter(getActivity())); playerGlue.setHost(new VideoSupportFragmentGlueHost(this)); playerGlue.addPlayerCallback(new PlaybackGlue.PlayerCallback() { @Override public void onPreparedStateChanged(PlaybackGlue glue) { if (glue.isPrepared()) { playerGlue.setSeekProvider(new MySeekProvider()); playerGlue.play(); } } }); playerGlue.setSubtitle("Leanback artist"); playerGlue.setTitle("Leanback team at work"); String uriPath = "android.resource://com.example.android.leanback/raw/video"; playerGlue.getPlayerAdapter().setDataSource(Uri.parse(uriPath)); } }
โปรดทราบว่ารหัสการตั้งค่าจะกำหนด PlayerAdapter.Callback
เพื่อจัดการเหตุการณ์จากด้วย
มีเดียเพลเยอร์
การปรับแต่งกาว UI
โดยคุณสามารถปรับแต่ง
PlaybackBannerControlGlue
และ PlaybackTransportControlGlue
เพื่อเปลี่ยน
PlaybackControlsRow
การปรับแต่งชื่อและคำอธิบาย
หากต้องการปรับแต่งชื่อและคำอธิบายที่ด้านบนของ
ตัวควบคุมการเล่น, ลบล้าง
onCreateRowPresenter()
:
Kotlin
override fun onCreateRowPresenter(): PlaybackRowPresenter { return super.onCreateRowPresenter().apply { (this as? PlaybackTransportRowPresenter) ?.setDescriptionPresenter(MyCustomDescriptionPresenter()) } }
Java
@Override protected PlaybackRowPresenter onCreateRowPresenter() { PlaybackTransportRowPresenter presenter = (PlaybackTransportRowPresenter) super.onCreateRowPresenter(); presenter.setDescriptionPresenter(new MyCustomDescriptionPresenter()); return presenter; }
การเพิ่มตัวควบคุม
กาวควบคุมแสดงการควบคุมการดำเนินการใน PlaybackControlsRow
การดำเนินการใน PlaybackControlsRow
จะแบ่งออกเป็น 2 กลุ่ม ได้แก่ การกระทำหลักและการกระทำรอง
การดำเนินการ ตัวควบคุมสำหรับกลุ่มหลักจะปรากฏเหนือแถบค้นหาและตัวควบคุมสำหรับ
กลุ่มรองจะปรากฏใต้แถบค้นหา ในช่วงแรกจะมีการดำเนินการหลักเพียงรายการเดียว
สำหรับปุ่มเล่น/หยุดชั่วคราว และไม่มีการดำเนินการรอง
คุณสามารถเพิ่มการดําเนินการให้กับกลุ่มหลักและกลุ่มรองได้โดยการลบล้าง
onCreatePrimaryActions()
และ
onCreateSecondaryActions()
Kotlin
private lateinit var repeatAction: PlaybackControlsRow.RepeatAction private lateinit var pipAction: PlaybackControlsRow.PictureInPictureAction private lateinit var thumbsUpAction: PlaybackControlsRow.ThumbsUpAction private lateinit var thumbsDownAction: PlaybackControlsRow.ThumbsDownAction private lateinit var skipPreviousAction: PlaybackControlsRow.SkipPreviousAction private lateinit var skipNextAction: PlaybackControlsRow.SkipNextAction private lateinit var fastForwardAction: PlaybackControlsRow.FastForwardAction private lateinit var rewindAction: PlaybackControlsRow.RewindAction override fun onCreatePrimaryActions(primaryActionsAdapter: ArrayObjectAdapter) { // Order matters, super.onCreatePrimaryActions() will create the play / pause action. // Will display as follows: // play/pause, previous, rewind, fast forward, next // > /|| |< << >> >| super.onCreatePrimaryActions(primaryActionsAdapter) primaryActionsAdapter.apply { add(skipPreviousAction) add(rewindAction) add(fastForwardAction) add(skipNextAction) } } override fun onCreateSecondaryActions(adapter: ArrayObjectAdapter?) { super.onCreateSecondaryActions(adapter) adapter?.apply { add(thumbsDownAction) add(thumbsUpAction) } }
Java
private PlaybackControlsRow.RepeatAction repeatAction; private PlaybackControlsRow.PictureInPictureAction pipAction; private PlaybackControlsRow.ThumbsUpAction thumbsUpAction; private PlaybackControlsRow.ThumbsDownAction thumbsDownAction; private PlaybackControlsRow.SkipPreviousAction skipPreviousAction; private PlaybackControlsRow.SkipNextAction skipNextAction; private PlaybackControlsRow.FastForwardAction fastForwardAction; private PlaybackControlsRow.RewindAction rewindAction; @Override protected void onCreatePrimaryActions(ArrayObjectAdapter primaryActionsAdapter) { // Order matters, super.onCreatePrimaryActions() will create the play / pause action. // Will display as follows: // play/pause, previous, rewind, fast forward, next // > /|| |< << >> >| super.onCreatePrimaryActions(primaryActionsAdapter); primaryActionsAdapter.add(skipPreviousAction); primaryActionsAdapter.add(rewindAction); primaryActionsAdapter.add(fastForwardAction); primaryActionsAdapter.add(skipNextAction); } @Override protected void onCreateSecondaryActions(ArrayObjectAdapter adapter) { super.onCreateSecondaryActions(adapter); adapter.add(thumbsDownAction); adapter.add(thumbsUpAction); }
คุณต้องลบล้าง
onActionClicked()
เพื่อจัดการการดำเนินการใหม่
Kotlin
override fun onActionClicked(action: Action) { when(action) { rewindAction -> { // Handle Rewind } fastForwardAction -> { // Handle FastForward } thumbsDownAction -> { // Handle ThumbsDown } thumbsUpAction -> { // Handle ThumbsUp } else -> // The superclass handles play/pause and delegates next/previous actions to abstract methods, // so those two methods should be overridden rather than handling the actions here. super.onActionClicked(action) } } override fun next() { // Skip to next item in playlist. } override fun previous() { // Skip to previous item in playlist. }
Java
@Override public void onActionClicked(Action action) { if (action == rewindAction) { // Handle Rewind } else if (action == fastForwardAction ) { // Handle FastForward } else if (action == thumbsDownAction) { // Handle ThumbsDown } else if (action == thumbsUpAction) { // Handle ThumbsUp } else { // The superclass handles play/pause and delegates next/previous actions to abstract methods, // so those two methods should be overridden rather than handling the actions here. super.onActionClicked(action); } } @Override public void next() { // Skip to next item in playlist. } @Override public void previous() { // Skip to previous item in playlist. }
ในกรณีพิเศษ คุณอาจต้องการใช้
PlaybackTransportRowPresenter
เพื่อแสดงการควบคุมที่กำหนดเองและตอบกลับเพื่อค้นหาการดำเนินการโดยใช้
PlaybackSeekUi
การสครับวิดีโอ
หากแอปใช้ VideoSupportFragment
และคุณต้องการรองรับการสครับวิดีโอ
คุณ
จะต้องมีการติดตั้งใช้งาน PlaybackSeekDataProvider
คอมโพเนนต์นี้มีภาพขนาดย่อของวิดีโอที่ใช้เมื่อเลื่อนหน้าจอ
คุณต้องใช้ผู้ให้บริการของคุณเองโดยขยายเวลา
PlaybackSeekDataProvider
ดูตัวอย่างใน
แอป Leanback Showcase
ที่ใช้เวลาเพียง 2 นาที