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