/** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ package com.facebook.react.views.toolbar; import javax.annotation.Nullable; import java.util.Map; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Color; import android.os.SystemClock; import android.view.MenuItem; import android.view.View; import com.facebook.react.R; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; import com.facebook.react.common.MapBuilder; import com.facebook.react.uimanager.ReactProp; import com.facebook.react.uimanager.ThemedReactContext; import com.facebook.react.uimanager.UIManagerModule; import com.facebook.react.uimanager.ViewGroupManager; import com.facebook.react.uimanager.events.EventDispatcher; import com.facebook.react.views.toolbar.events.ToolbarClickEvent; /** * Manages instances of ReactToolbar. */ public class ReactToolbarManager extends ViewGroupManager<ReactToolbar> { private static final String REACT_CLASS = "ToolbarAndroid"; @Override public String getName() { return REACT_CLASS; } @Override protected ReactToolbar createViewInstance(ThemedReactContext reactContext) { return new ReactToolbar(reactContext); } @ReactProp(name = "logo") public void setLogo(ReactToolbar view, @Nullable ReadableMap logo) { view.setLogoSource(logo); } @ReactProp(name = "navIcon") public void setNavIcon(ReactToolbar view, @Nullable ReadableMap navIcon) { view.setNavIconSource(navIcon); } @ReactProp(name = "overflowIcon") public void setOverflowIcon(ReactToolbar view, @Nullable ReadableMap overflowIcon) { view.setOverflowIconSource(overflowIcon); } @ReactProp(name = "subtitle") public void setSubtitle(ReactToolbar view, @Nullable String subtitle) { view.setSubtitle(subtitle); } @ReactProp(name = "subtitleColor", customType = "Color") public void setSubtitleColor(ReactToolbar view, @Nullable Integer subtitleColor) { int[] defaultColors = getDefaultColors(view.getContext()); if (subtitleColor != null) { view.setSubtitleTextColor(subtitleColor); } else { view.setSubtitleTextColor(defaultColors[1]); } } @ReactProp(name = "title") public void setTitle(ReactToolbar view, @Nullable String title) { view.setTitle(title); } @ReactProp(name = "titleColor", customType = "Color") public void setTitleColor(ReactToolbar view, @Nullable Integer titleColor) { int[] defaultColors = getDefaultColors(view.getContext()); if (titleColor != null) { view.setTitleTextColor(titleColor); } else { view.setTitleTextColor(defaultColors[0]); } } @ReactProp(name = "actions") public void setActions(ReactToolbar view, @Nullable ReadableArray actions) { view.setActions(actions); } @Override protected void addEventEmitters(final ThemedReactContext reactContext, final ReactToolbar view) { final EventDispatcher mEventDispatcher = reactContext.getNativeModule(UIManagerModule.class) .getEventDispatcher(); view.setNavigationOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { mEventDispatcher.dispatchEvent( new ToolbarClickEvent(view.getId(), SystemClock.uptimeMillis(), -1)); } }); view.setOnMenuItemClickListener( new ReactToolbar.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem menuItem) { mEventDispatcher.dispatchEvent( new ToolbarClickEvent( view.getId(), SystemClock.uptimeMillis(), menuItem.getOrder())); return true; } }); } @Nullable @Override public Map<String, Object> getExportedViewConstants() { return MapBuilder.<String, Object>of( "ShowAsAction", MapBuilder.of( "never", MenuItem.SHOW_AS_ACTION_NEVER, "always", MenuItem.SHOW_AS_ACTION_ALWAYS, "ifRoom", MenuItem.SHOW_AS_ACTION_IF_ROOM)); } @Override public boolean needsCustomLayoutForChildren() { return true; } private static int[] getDefaultColors(Context context) { Resources.Theme theme = context.getTheme(); TypedArray toolbarStyle = null; TypedArray textAppearances = null; TypedArray titleTextAppearance = null; TypedArray subtitleTextAppearance = null; try { toolbarStyle = theme .obtainStyledAttributes(new int[]{R.attr.toolbarStyle}); int toolbarStyleResId = toolbarStyle.getResourceId(0, 0); textAppearances = theme.obtainStyledAttributes( toolbarStyleResId, new int[]{ R.attr.titleTextAppearance, R.attr.subtitleTextAppearance, }); int titleTextAppearanceResId = textAppearances.getResourceId(0, 0); int subtitleTextAppearanceResId = textAppearances.getResourceId(1, 0); titleTextAppearance = theme .obtainStyledAttributes(titleTextAppearanceResId, new int[]{android.R.attr.textColor}); subtitleTextAppearance = theme .obtainStyledAttributes(subtitleTextAppearanceResId, new int[]{android.R.attr.textColor}); int titleTextColor = titleTextAppearance.getColor(0, Color.BLACK); int subtitleTextColor = subtitleTextAppearance.getColor(0, Color.BLACK); return new int[] {titleTextColor, subtitleTextColor}; } finally { recycleQuietly(toolbarStyle); recycleQuietly(textAppearances); recycleQuietly(titleTextAppearance); recycleQuietly(subtitleTextAppearance); } } private static void recycleQuietly(@Nullable TypedArray style) { if (style != null) { style.recycle(); } } }