Taşıma kontrollerini kullan

Compose ile daha iyi hizmet verin
Android TV OS için Jetpack Compose'u kullanarak minimum kodla etkileyici kullanıcı arayüzleri oluşturun.

Leanback kullanıcı arayüzü araç setinde, iyileştirilmiş kullanıcı deneyimi sağlayan oynatma kontrolleri bulunur. Video uygulamaları için aktarım kontrolleri, ileri ve geri kontrolleriyle video ileri geri oynatmayı destekler. Ekranı ileri geri oynatırken videoda gezinmeye yardımcı olacak küçük resimler gösterilir.

Kitaplıkta soyut sınıfların yanı sıra geliştiriciler için daha ayrıntılı kontrol sağlayan önceden oluşturulmuş, kullanıma hazır uygulamalar da bulunur. Önceden oluşturulmuş uygulamaları kullanarak, çok fazla kodlamaya gerek olmadan hızlı bir şekilde zengin özelliklere sahip bir uygulamayı oluşturabilirsiniz. Daha fazla özelleştirmeye ihtiyacınız varsa kitaplığın önceden oluşturulmuş bileşenlerinden herhangi birini genişletebilirsiniz.

Kontroller ve oynatıcı

Leanback kullanıcı arayüzü araç seti, aktarım kontrolleri kullanıcı arayüzünü videoyu oynatan oynatıcıdan ayırır. Bu işlem iki bileşenle gerçekleştirilir: aktarım kontrollerini görüntülemek için bir oynatma destek parçası (ve isteğe bağlı olarak videoyu) ve bir medya oynatıcıyı içine alan bir oynatıcı bağdaştırıcısı.

Oynatma parçası

Uygulamanızın Kullanıcı Arayüzü Etkinliği bir PlaybackSupportFragment veya VideoSupportFragment kullanmalıdır. Her ikisi de leanback aktarım denetimlerini içerir:

Kullanıcı arayüzünü geliştirmek için bir parçanın ObjectAdapter öğesini özelleştirebilirsiniz. Örneğin, "ilgili videolar" satırı eklemek için setAdapter() kullanın.

Oynatıcı Adaptörü

PlayerAdapter, temel medya oynatıcıyı kontrol eden soyut bir sınıftır. Geliştiriciler, önceden oluşturulmuş MediaPlayerAdapter uygulamasını seçebilir veya bu sınıf için kendi uygulamalarını yazabilir.

Parçaları birbirine yapıştırma

Oynatma parçasını oynatıcıya bağlamak için bir "kontrol yapıştırıcı" kullanmanız gerekir. Leanback kitaplığı iki tür tutkal sunar:

leanback taşıma kontrol tutkalı

Uygulamanızın video ileri geri oynatmayı desteklemesini istiyorsanız PlaybackTransportControlGlue kullanmanız gerekir.

Yapıştırıcıyı oynatma parçasına bağlayan, kullanıcı arayüzünde aktarım denetimlerini çizen, durumlarını koruyan ve aktarım kontrolü etkinliklerini tekrar birleştiriciye aktaran bir "yapışkan ana makine" belirtmeniz de gerekir. Ana makine, oynatma parçası türüyle eşleşmelidir. PlaybackSupportFragmentGlueHost öğesini PlaybackFragment, VideoSupportFragmentGlueHost öğesini de VideoFragment ile kullanın.

Aşağıda, leanback taşıma kontrolü parçalarının nasıl uyumlu olduğunu gösteren bir resim yer almaktadır:

leanback taşıma kontrol tutkalı

Uygulamanızı birbirine bağlayan kod, kullanıcı arayüzünü tanımlayan PlaybackSupportFragment veya VideoSupportFragment içinde olmalıdır.

Aşağıdaki örnekte uygulama, playerGlue adını vererek bir PlaybackTransportControlGlue örneği oluşturur ve VideoSupportFragment öğesini yeni oluşturulan bir MediaPlayerAdapter öğesine bağlar. Bu bir VideoSupportFragment olduğundan kurulum kodu, playerGlue öğesine VideoSupportFragmentGlueHost eklemek için setHost() yöntemini çağırır. Kod, VideoSupportFragment öğesini genişleten sınıfın içinde yer alır.

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));
  }
}

Kurulum kodunun, medya oynatıcıdan etkinlikleri işlemek için bir PlayerAdapter.Callback tanımladığını da unutmayın.

Kullanıcı arayüzü birleştiricisini özelleştirme

PlaybackControlsRow ayarını değiştirmek için PlaybackBannerControlGlue ve PlaybackTransportControlGlue öğelerini özelleştirebilirsiniz.

Başlık ve açıklamayı özelleştirme

Oynatma kontrollerinin üst kısmındaki başlığı ve açıklamayı özelleştirmek için onCreateRowPresenter() değerini geçersiz kılın:

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;
}

Denetim ekleme

Kontrol yapıştırıcısı, PlaybackControlsRow içindeki işlemlere ait kontrolleri gösterir.

PlaybackControlsRow öğesindeki işlemler iki gruba atanmıştır: birincil işlemler ve ikincil işlemler. Birincil grubun denetimleri arama çubuğunun üzerinde, ikincil grubun denetimleri ise arama çubuğunun altında görünür. Başlangıçta, oynat/duraklat düğmesi için yalnızca tek bir birincil işlem vardır, ikincil bir işlem yoktur.

onCreatePrimaryActions() ve onCreateSecondaryActions() ayarlarını geçersiz kılarak birincil ve ikincil gruplara işlem ekleyebilirsiniz.

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);
}

Yeni işlemleri işlemek için onActionClicked() politikasını geçersiz kılmanız gerekir.

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.
}

Özel durumlarda, özel denetimler oluşturmak ve PlaybackSeekUi kullanarak işlem aramasına yanıt vermek için kendi PlaybackTransportRowPresenter uygulamanızı uygulayabilirsiniz.

Video ileri geri oynatma

Uygulamanızda VideoSupportFragment kullanılıyorsa ve video ileri geri oynatmayı desteklemek istiyorsanız.

ovma

PlaybackSeekDataProvider uygulamasını sağlamanız gerekir. Bu bileşen, kaydırma sırasında kullanılan video küçük resimlerini sağlar. PlaybackSeekDataProvider süresini uzatarak kendi sağlayıcınızı uygulamanız gerekir. Leanback Vitrin uygulamasındaki örneği inceleyin.