AAOS'de medya kartı uygulama

Medya kartı, aşağıdaki gibi medya meta verilerini görüntüleyen bağımsız bir ViewGroup'tur: gibi oynatma kontrollerini de gösterir. Örneğin, Oynat ve Duraklat, Atla ve hatta üçüncü tarafın sağladığı özel işlemler taraf medya uygulaması. Bir medya kartı, oynatma listesi.

Medya kartı

Medya kartı

Medya kartı

Şekil 1. Medya kartı örnek uygulamaları.

Medya kartları AAOS'te nasıl uygulanır?

Medya bilgilerini gösteren görüntüleme grupları car-media-common kitaplığı veri modelini (PlaybackViewModel) doldurmak için ViewGroup. Her LiveData güncellemesi, MediaItemMetadata, PlaybackStateWrapper ve MediaSource gibi değişen bir medya bilgisi alt kümesine karşılık gelir.

Bu yaklaşım yinelenen koda yol açtığından (her istemci uygulaması, her bir LiveData parçasına ve birçok benzer Görünüme güncellenmiş veriler atanırsa PlaybackCardController oluşturuldu.

OynatmaKartı Denetleyicisi

PlaybackCardController, car-media-common kitaplığına şu uygulama için eklendi: bir medya kartı oluşturmaya yardımcı olabilir. Bu, bir ViewGroup (mView), PlaybackViewModel (mDataModel), PlaybackCardViewModel (mViewModel) ve MediaItemsRepository örneği (mItemsRepository) ile oluşturulan herkese açık bir sınıftır.

setupController işlevinde, ViewGroup belirli görünümler için mView.findViewById(R.id.xxx) ile kimlik (korumalı View nesnelerine atanır).

private void getViewsFromWidget() {
        mTitle = mView.findViewById(R.id.title);
        mAlbumCover = mView.findViewById(R.id.album_art);
        mDescription = mView.findViewById(R.id.album_title);
        mLogo = mView.findViewById(R.id.content_format);

        mAppIcon = mView.findViewById(R.id.media_widget_app_icon);
        mAppName = mView.findViewById(R.id.media_widget_app_name);

         // ...
}

PlaybackViewModel kaynağından gelen her LiveData güncellemesi, korumalı bir yöntemle gözlemlenir ve alınan verilerle alakalı Görünümlerle etkileşim gerçekleştirir. Örneğin, MediaItemMetadata'teki bir gözlemci, mTitle TextView'de başlığı ayarlar ve MediaItemMetadata.ArtworkRef'ı albüm resmi ImageBinder mAlbumArtBinder'e iletir. Meta veri boşsa Görünümler gizlendi. Denetleyicinin alt sınıfları, gerekirse bu mantığı geçersiz kılabilir.

mDataModel.getMetadata().observe(mViewLifecycle, this::updateMetadata);
// ...

/** Update views with {@link MediaItemMetadata} */
protected void updateMetadata(MediaItemMetadata metadata) {
        if (metadata != null) {
            String defaultTitle = mView.getContext().getString(
                    R.string.metadata_default_title);
            updateTextViewAndVisibility(mTitle, metadata.getTitle(),    defaultTitle);
            updateTextViewAndVisibility(mSubtitle, metadata.getSubtitle());
            updateMediaLink(mSubtitleLinker,metadata.getSubtitleLinkMediaId());
            updateTextViewAndVisibility(mDescription, metadata.getDescription());
            updateMediaLink(mDescriptionLinker, metadata.getDescriptionLinkMediaId());
            updateMetadataAlbumCoverArtworkRef(metadata.getArtworkKey());
            updateMetadataLogoWithUri(metadata);
        } else {
            ViewUtils.setVisible(mTitle, false);
            ViewUtils.setVisible(mSubtitle, false);
            ViewUtils.setVisible(mAlbumCover, false);
            ViewUtils.setVisible(mDescription, false);
            ViewUtils.setVisible(mLogo, false);
        }
    }

OynatmaKartı Denetleyicisi'ni genişletin

Medya kartı oluşturmak isteyen istemci uygulamaları, her LiveData güncellemesinde ele almak istedikleri ek bir özellik varsa PlaybackCardController sınıfını genişletmelidir. AAOS'deki mevcut istemciler bu kalıbı uygular. İlk olarak bir PlaybackCardController alt sınıfı oluşturulmalıdır. Örneğin: MediaCardController. Daha sonra, MediaCardController bir statik iç PlaybackCardController öğesini genişleten oluşturucu sınıfı.

public class MediaCardController extends PlaybackCardController {

    // extra fields specific to MediaCardController

    /** Builder for {@link MediaCardController}. Overrides build() method to
     * return NowPlayingController rather than base {@link PlaybackCardController}
     */
    public static class Builder extends PlaybackCardController.Builder {

        @Override
        public MediaCardController build() {
            MediaCardController controller = new MediaCardController(this);
            controller.setupController();
            return controller;
        }
    }

    public MediaCardController(Builder builder) {
        super(builder);
    // any other function calls needed in constructor
    // ...

  }
}

PlaybackCardController'ı veya bir alt sınıfı örneklendirme

LiveData gözlemcileri için bir LifecycleOwner'a sahip olmak amacıyla Controller sınıfı bir Fragment veya Activity'den oluşturulmalıdır.

mMediaCardController = (MediaCardController) new MediaCardController.Builder()
                    .setModels(mViewModel.getPlaybackViewModel(),
                            mViewModel,
                            mViewModel.getMediaItemsRepository())
                    .setViewGroup((ViewGroup) view)
                    .build();

mViewModel, PlaybackCardViewModel (veya alt sınıf) örneğidir.

Durumu Kaydetme İçin PlaybackCardViewModel

PlaybackCardViewModel, bir Parça veya Aşağıdaki durumlarda medya kartının içeriğini yeniden oluşturmak için kullanılması gereken etkinlik yapılandırma değişikliği oluştuğunda (örneğin, yeni bir kod etkinken açık temadan koyu temaya Kullanıcının tünelden geçmesi). Varsayılan PlaybackCardViewModel, oynatma için MediaModel örneklerini depolama PlaybackViewModel ve MediaItemsRepository alınabilir. Şunu kullanın: Sıranın, geçmişin ve taşmanın durumunu izlemek için PlaybackCardViewModel e-postalara göz atın.

public class PlaybackCardViewModel extends AndroidViewModel {

    private MediaModels mModels;
    private boolean mNeedsInitialization = true;
    private boolean mQueueVisible = false;
    private boolean mHistoryVisible = false;
    private boolean mOverflowExpanded = false;

    public PlaybackCardViewModel(@NonNull Application application) {
        super(application);
    }

    /** Initialize the PlaybackCardViewModel */
    public void init(MediaModels models) {
        mModels = models;
        mNeedsInitialization = false;
    }

    /**
     * Returns whether the ViewModel needs to be initialized. The ViewModel may
     * need re-initialization if a config change occurs or if the system kills
     * the Fragment.
     */
    public boolean needsInitialization() {
        return mNeedsInitialization;
    }

    public MediaItemsRepository getMediaItemsRepository() {
        return mModels.getMediaItemsRepository();
    }

    public PlaybackViewModel getPlaybackViewModel() {
        return mModels.getPlaybackViewModel();
    }

    public MediaSourceViewModel getMediaSourceViewModel() {
        return mModels.getMediaSourceViewModel();
    }

    public void setQueueVisible(boolean visible) {
        mQueueVisible = visible;
    }

    public boolean getQueueVisible() {
        return mQueueVisible;
    }

    public void setHistoryVisible(boolean visible) {
        mHistoryVisible = visible;
    }

    public boolean getHistoryVisible() {
        return mHistoryVisible;
    }

    public void setOverflowExpanded(boolean expanded) {
        mOverflowExpanded = expanded;
    }

    public boolean getOverflowExpanded() {
        return mOverflowExpanded;
    }
}

Daha fazla eyaletin izlenmesi gerekiyorsa bu sınıf genişletilebilir.

Medya kartında sıra gösterme

PlaybackViewModel, MediaSource'un bir sırayı destekleyip desteklemediğini algılamak ve sıradaki MediaItemMetadata nesnelerinin listesini almak için LiveData API'leri sağlar. Bu API'ler doğrudan RecyclerView öğesini doldurmak için kullanılabilir nesnesini sorguladıysanız PlaybackQueueController sınıfı bu işlemi kolaylaştırmak için car-media-common kitaplığına eklendi. CarUiRecyclerView içindeki her öğenin düzeni, isteğe bağlı bir başlık düzeni olarak istemci uygulaması tarafından da belirtilir. İstemci uygulaması, özel UXR kısıtlamalarıyla sürüş durumunda sırada gösterilen öğe sayısını da sınırlayabilir.

PlaybackQueueController kurucusu ve ayarlayıcıları aşağıdaki örnekte gösterilmektedir. queueResource ve headerResource düzen kaynakları, önceki durumda kapsayıcıda id queue_list içeren bir CarUiRecyclerView varsa ve son durumda kuyrukta bir başlık yoksa Resources.ID_NULL olarak iletilebilir.

   /**
    * Construct a PlaybackQueueController. If clients don't have a separate
    * layout for the queue, where the queue is already inflated within the
    * container, they should pass {@link Resources.ID_NULL} as the LayoutRes
    * resource. If clients don't require a UxrContentLimiter, they should pass
    * null for uxrContentLimiter and the int passed for uxrConfigurationId will
    * be ignored.
    */
    public PlaybackQueueController(
            ViewGroup container,
            @LayoutRes int queueResource,
            @LayoutRes int queueItemResource,
            @LayoutRes int headerResource,
            LifecycleOwner lifecycleOwner,
            PlaybackViewModel playbackViewModel,
            MediaItemsRepository itemsRepository,
            @Nullable LifeCycleObserverUxrContentLimiter uxrContentLimiter,
            int uxrConfigurationId) {
      // ...
    }

    public void setShowTimeForActiveQueueItem(boolean show) {
        mShowTimeForActiveQueueItem = show;
    }

    public void setShowIconForActiveQueueItem(boolean show) {
        mShowIconForActiveQueueItem = show;
    }

    public void setShowThumbnailForQueueItem(boolean show) {
        mShowThumbnailForQueueItem = show;
    }

    public void setShowSubtitleForQueueItem(boolean show) {
        mShowSubtitleForQueueItem = show;
    }

    /** Calls {@link RecyclerView#setVerticalFadingEdgeEnabled(boolean)} */
    public void setVerticalFadingEdgeLengthEnabled(boolean enabled) {
        mQueue.setVerticalFadingEdgeEnabled(enabled);
    }

    public void setCallback(PlaybackQueueCallback callback) {
        mPlaybackQueueCallback = callback;
    }

Her sıra öğesinin düzeni, yapacağı Görünümler için kimlikleri içermelidir. QueueViewHolder iç sınıfında kullanılanlara karşılık gelecek şekilde gösterilir.

QueueViewHolder(View itemView) {
            super(itemView);
            mView = itemView;
            mThumbnailContainer = itemView.findViewById(R.id.thumbnail_container);
            mThumbnail = itemView.findViewById(R.id.thumbnail);
            mSpacer = itemView.findViewById(R.id.spacer);
            mTitle = itemView.findViewById(R.id.queue_list_item_title);
            mSubtitle = itemView.findViewById(R.id.queue_list_item_subtitle);
            mCurrentTime = itemView.findViewById(R.id.current_time);
            mMaxTime = itemView.findViewById(R.id.max_time);
            mTimeSeparator = itemView.findViewById(R.id.separator);
            mActiveIcon = itemView.findViewById(R.id.now_playing_icon);

            // ...
}

PlaybackCardController ile oluşturulan medya kartında bir sıranın gösterilmesi için (veya bir alt sınıfta) PlaybackQueueController, mDataModel ve mItemsRepository kullanan PlaybackCardController oluşturucu sırasıyla PlaybackViewModel ve MediaItemsRepository örnekleri için.

Önceden oynatılan MediaSource'ların geçmişini göster

Bu bölümde, daha önce oynatılan medya kaynaklarının geçmişini nasıl göstereceğinizi ve bu geçmişi nasıl bulacağınızı öğreneceksiniz.

OynatmaCardViewModel API'si ile geçmiş listesini alma

PlaybackCardViewModel, şunlar için getHistoryList() adında bir LiveData API'si sağlar: geçmişi listesini al. Aşağıdakilerin listesini içeren bir LiveData döndürür: Daha önce çalınan medya kaynakları. Bu veriler, ilgili alanı doldurmak için CarUiRecyclerView nesnesini ifade eder. PlaybackQueueController ile benzer bir sınıf PlaybackHistoryController adlı içerik car-media-common listesine eklendi kitaplığını kullanarak süreci kolaylaştırır.

public class PlaybackCardViewModel extends AndroidViewModel {

    public PlaybackCardViewModel(@NonNull Application application) {
    }

    /** Initialize the PlaybackCardViewModel */
    public void init(MediaModels models) {
    }

    public LiveData<List<MediaSource>> getHistoryList() {
        return mHistoryListData;
    }
}

PlaybackHistoryController ile Surface geçmişi kullanıcı arayüzü

Geçmiş verilerinin doldurulmasına yardımcı olması için yeni PlaybackHistoryController özelliğini kullanın CarUiRecyclerView olarak değiştirdik. Bu sınıfın kurucuları ve ana fonksiyonları şunlardır: aşağıdaki gibi ekleyebilirsiniz. İstemci uygulamasından geçirilen container, bir history_list kimlikli CarUiRecyclerView. CarUiRecyclerView liste öğelerini ve isteğe bağlı bir üstbilgi gösterir. Liste öğesi için her iki düzen de ve başlık istemci uygulamasından iletilebilir. Resources.ID_NULL ayarlanmışsa üstbilgisini almazsanız başlık gösterilmez. PlaybackCardViewModel, kontrolöre aktarıldıktan sonra playbackCardViewModel.getHistoryList()'den alınan LiveData<List<MediaSource>>'ı izler.

public class PlaybackHistoryController {

    public PlaybackHistoryController(
            LifecycleOwner lifecycleOwner,
            PlaybackCardViewModel playbackCardViewModel,
            ViewGroup container,
            @LayoutRes int itemResource,
            @LayoutRes int headerResource,
            int uxrConfigurationId) {
    }

    /**
     * Renders the view.
     */
    public void setupView() {
    }
}

Her öğenin düzeni, istediği Görünümlerin kimliklerini içermelidir. ViewHolder iç sınıfında kullanılanlara karşılık gelecek şekilde gösterilir.

HistoryItemViewHolder(View itemView) {
            super(itemView);
            mContext = itemView.getContext();
            mActiveView = itemView.findViewById(R.id.history_card_container_active);
            mInactiveView = itemView.findViewById(R.id.history_card_container_inactive);
            mMetadataTitleView = itemView.findViewById(R.id.history_card_title_active);
            mAdditionalInfo = itemView.findViewById(R.id.history_card_subtitle_active);
            mAppIcon = itemView.findViewById(R.id.history_card_app_thumbnail);
            mAlbumArt = itemView.findViewById(R.id.history_card_album_art);
            mAppTitleInactive = itemView.findViewById(R.id.history_card_app_title_inactive);
            mAppIconInactive = itemView.findViewById(R.id.history_item_app_icon_inactive);
// ...
}

Şununla oluşturulan bir medya kartında geçmiş listesini göstermek için: PlaybackCardController (veya bir alt sınıf) durumunda, PlaybackHistoryController olabilir. PlaybackCardController inşaatçısında inşa edilmiştir.