【发布时间】:2014-08-10 09:39:49
【问题描述】:
我正在使用 Google 的方法向我的应用程序添加一个 Cast 按钮,但它默认为白色图标,在我的白色菜单栏上是不可见的。如何将 Cast 图标的颜色更改为黑色?
【问题讨论】:
标签: android chromecast
我正在使用 Google 的方法向我的应用程序添加一个 Cast 按钮,但它默认为白色图标,在我的白色菜单栏上是不可见的。如何将 Cast 图标的颜色更改为黑色?
【问题讨论】:
标签: android chromecast
我刚刚像这样扩展了 MediaRouteActionProvider:
public class ThemeableMediaRouteActionProvider extends MediaRouteActionProvider {
public ThemeableMediaRouteActionProvider(Context context) {
super(context);
}
@Override
public MediaRouteButton onCreateMediaRouteButton() {
MediaRouteButton button = super.onCreateMediaRouteButton();
colorWorkaroundForCastIcon(button);
return button;
}
@Nullable
@Override
public MediaRouteButton getMediaRouteButton() {
MediaRouteButton button = super.getMediaRouteButton();
colorWorkaroundForCastIcon(button);
return button;
}
private void colorWorkaroundForCastIcon(MediaRouteButton button) {
if (button == null) return;
Context castContext = new ContextThemeWrapper(getContext(), androidx.mediarouter.R.style.Theme_MediaRouter);
TypedArray a = castContext.obtainStyledAttributes(null, androidx.mediarouter.R.styleable.MediaRouteButton, androidx.mediarouter.R.attr.mediaRouteButtonStyle, 0);
Drawable drawable = a.getDrawable(androidx.mediarouter.R.styleable.MediaRouteButton_externalRouteEnabledDrawable);
a.recycle();
DrawableCompat.setTint(drawable, getContext().getResources().getColor(R.color.primary));
drawable.setState(button.getDrawableState());
button.setRemoteIndicatorDrawable(drawable);
}
}
R.color.primary 是我想要的颜色。
然后只需将菜单中的 actionProviderClass 从 MediaRouteActionProvider 替换为您的那样:
<item
android:id="@+id/media_route_menu_item"
android:title="@string/media_route_menu_title"
bwq:actionProviderClass="tv.test.playback.chromecast.ThemeableMediaRouteActionProvider"
bwq:showAsAction="always">
</item>
【讨论】:
如果上述解决方案均无效,请尝试此处的说明。您可能需要使用 colorFilter 属性而不是 tint。
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.some_menu, menu);
setColorForCast(menu);
}
private void setColorForCast(@NonNull Menu menu) {
MediaRouteButton castButton = (MediaRouteButton) menu.findItem(R.id.cast_button).getActionView();
if (castButton != null) {
Drawable drawable = getResources().getDrawable(R.drawable.chromecast);
int color = ContextCompat.getColor(getContext(), R.color.colorPrimary);
drawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
drawable.setState(castButton.getDrawableState());
castButton.setRemoteIndicatorDrawable(drawable);
}
}
【讨论】:
如果您为视图的投射图标使用一种颜色,请为片段或活动使用主题。
<item name="mediaRouteButtonTint">@color/red</item>
如果您想以编程方式设置颜色,请使用以下代码。
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/menu_item"
android:title="@string/media_route_menu_title"
app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider" />
</menu>
import androidx.core.content.ContextCompat
import androidx.appcompat.view.ContextThemeWrapper
import androidx.core.graphics.drawable.DrawableCompat
...
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater?) {
val tintColor = ContextCompat.getColor(context, R.color.my_color)
val item = menu.findItem(R.id.menu_item)
val button = item.actionView
val castContext = ContextThemeWrapper(context, androidx.mediarouter.R.style.Theme_MediaRouter)
val attrs = castContext.obtainStyledAttributes(null, androidx.mediarouter.R.styleable.MediaRouteButton, androidx.mediarouter.R.attr.mediaRouteButtonStyle, 0)
val drawable = attrs.getDrawable(androidx.mediarouter.R.styleable.MediaRouteButton_externalRouteEnabledDrawable)
attrs.recycle()
DrawableCompat.setTint(drawable, tintColor)
drawable.state = button.getDrawableState()
button.setRemoteIndicatorDrawable(drawable)
【讨论】:
官方答案在这里:
https://developers.google.com/cast/docs/android_sender/customize_ui#customize_cast_button
自定义投射按钮
要将自定义
mediaRouteTheme添加到您应用的主题中:<style name="Theme.CastVideosTheme" parent="Theme.AppCompat.Light.NoActionBar"> <!-- ... --> <item name="mediaRouteTheme">@style/CustomMediaRouterTheme</item> </style>声明您的自定义媒体路由器主题并声明一个自定义
mediaRouteButtonStyle:<style name="CustomMediaRouterTheme" parent="Theme.MediaRouter"> <item name="mediaRouteButtonStyle">@style/CustomMediaRouteButtonStyle</item> </style> <style name="CustomMediaRouteButtonStyle" parent="Widget.MediaRouter.Light.MediaRouteButton"> <item name="mediaRouteButtonTint">#EEFF41</item> </style>如果支持库版本,应该使用
mediaRouteButtonTint比 26.0.0 更新。对于较旧的支持库版本,请使用buttonTint代替。
【讨论】:
绝对简单答案在这里:
https://developers.google.com/cast/docs/android_sender_advanced#customize_cast_button
因此,只需将该链接中的 mediaRouteTheme 复制到您应用的主题,然后将接下来的两个样式复制到 styles.xml。
【讨论】:
我扩展了 MediaRouteButton。请参阅下面的代码。然后我可以调用 applyTint() 并将颜色应用于 RemoteIndicatorDrawable 的所有状态
public class ColorableMediaRouteButton extends MediaRouteButton {
protected Drawable mRemoteIndicatorDrawable;
public ColorableMediaRouteButton(Context context) {
super(context);
}
public ColorableMediaRouteButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ColorableMediaRouteButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void setRemoteIndicatorDrawable(Drawable d) {
mRemoteIndicatorDrawable = d;
super.setRemoteIndicatorDrawable(d);
}
public void applyTint(int color) {
Drawable wrapDrawable = DrawableCompat.wrap(mRemoteIndicatorDrawable);
DrawableCompat.setTint(wrapDrawable, color);
}
}
【讨论】:
your_button_view.post() -> { your_button_view.applyTint(color); }); 就会解决它,因为它会在 setRemoteIndicatorDrawable() 完成其接收到的可绘制对象后立即触发。
我自己也遇到过这个问题,并通过将android:theme 和app:popuptheme 值更改为@style/ThemeOverlay.AppCompat.Dark.ActionBar 解决了这个问题。
参见下面的示例代码:
<android.support.v7.widget.Toolbar
android:id="@+id/my_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#4dffffff"
android:elevation="4dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
【讨论】:
如果只是因为风格(深色与浅色),如果风格定义正确(即根据深色与浅色扩展正确的主题),您应该没问题。对于一般样式,请查看此post,如果这不能解决您的问题,请回来告诉我们。
【讨论】: