react-native-navigation的迁移库

TitleBar.java 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. package com.reactnativenavigation.views;
  2. import android.animation.Animator;
  3. import android.animation.AnimatorListenerAdapter;
  4. import android.app.Activity;
  5. import android.content.Context;
  6. import android.graphics.drawable.Drawable;
  7. import android.graphics.Typeface;
  8. import android.support.annotation.Nullable;
  9. import android.support.v7.widget.ActionMenuView;
  10. import android.support.v7.widget.Toolbar;
  11. import android.text.TextUtils;
  12. import android.view.Menu;
  13. import android.view.View;
  14. import android.view.animation.AccelerateDecelerateInterpolator;
  15. import android.view.animation.AccelerateInterpolator;
  16. import android.widget.TextView;
  17. import com.reactnativenavigation.params.BaseScreenParams;
  18. import com.reactnativenavigation.params.BaseTitleBarButtonParams;
  19. import com.reactnativenavigation.params.StyleParams;
  20. import com.reactnativenavigation.params.TitleBarButtonParams;
  21. import com.reactnativenavigation.params.TitleBarLeftButtonParams;
  22. import com.reactnativenavigation.utils.ViewUtils;
  23. import java.util.List;
  24. public class TitleBar extends Toolbar {
  25. private static final int TITLE_VISIBILITY_ANIMATION_DURATION = 320;
  26. private LeftButton leftButton;
  27. private ActionMenuView actionMenuView;
  28. private List<TitleBarButtonParams> rightButtons;
  29. public TitleBar(Context context) {
  30. super(context);
  31. }
  32. @Override
  33. public void onViewAdded(View child) {
  34. super.onViewAdded(child);
  35. if (child instanceof ActionMenuView) {
  36. actionMenuView = (ActionMenuView) child;
  37. }
  38. }
  39. public void setRightButtons(List<TitleBarButtonParams> rightButtons, String navigatorEventId) {
  40. this.rightButtons = rightButtons;
  41. Menu menu = getMenu();
  42. menu.clear();
  43. if (rightButtons == null) {
  44. return;
  45. }
  46. addButtonsToTitleBar(navigatorEventId, menu);
  47. }
  48. public void setLeftButton(TitleBarLeftButtonParams leftButtonParams,
  49. LeftButtonOnClickListener leftButtonOnClickListener,
  50. String navigatorEventId,
  51. boolean overrideBackPressInJs) {
  52. if (shouldSetLeftButton(leftButtonParams)) {
  53. createAndSetLeftButton(leftButtonParams, leftButtonOnClickListener, navigatorEventId, overrideBackPressInJs);
  54. } else if (hasLeftButton()) {
  55. if (leftButtonParams.hasDefaultIcon() || leftButtonParams.hasCustomIcon()) {
  56. updateLeftButton(leftButtonParams);
  57. } else {
  58. removeLeftButton();
  59. }
  60. }
  61. }
  62. private void removeLeftButton() {
  63. setNavigationIcon(null);
  64. leftButton = null;
  65. }
  66. public void setStyle(StyleParams params) {
  67. setVisibility(params.titleBarHidden);
  68. setTitleTextColor(params);
  69. setTitleTextFont(params);
  70. setTitleTextFontSize(params);
  71. setTitleTextFontWeight(params);
  72. setSubtitleTextColor(params);
  73. setSubtitleFontSize(params);
  74. setSubtitleFont(params);
  75. colorOverflowButton(params);
  76. setBackground(params);
  77. centerTitle(params);
  78. }
  79. public void setVisibility(boolean titleBarHidden) {
  80. setVisibility(titleBarHidden ? GONE : VISIBLE);
  81. }
  82. public void setTitle(String title, StyleParams styleParams) {
  83. setTitle(title);
  84. setTitleTextFont(styleParams);
  85. centerTitle(styleParams);
  86. }
  87. public void setSubtitle(CharSequence subtitle, StyleParams styleParams) {
  88. super.setSubtitle(subtitle);
  89. setSubtitleFontSize(styleParams);
  90. setSubtitleFont(styleParams);
  91. }
  92. private void setSubtitleFontSize(StyleParams params) {
  93. TextView subtitleView = getSubtitleView();
  94. if (subtitleView != null && params.titleBarSubtitleFontSize > 0) {
  95. subtitleView.setTextSize(params.titleBarSubtitleFontSize);
  96. }
  97. }
  98. private void setSubtitleFont(StyleParams params) {
  99. if (params.titleBarSubtitleFontFamily.hasFont()) {
  100. TextView subtitleView = getSubtitleView();
  101. if (subtitleView != null) {
  102. subtitleView.setTypeface(params.titleBarSubtitleFontFamily.get());
  103. }
  104. }
  105. }
  106. private void centerTitle(final StyleParams params) {
  107. final View titleView = getTitleView();
  108. if (titleView == null) {
  109. return;
  110. }
  111. ViewUtils.runOnPreDraw(titleView, new Runnable() {
  112. @Override
  113. public void run() {
  114. if (params.titleBarTitleTextCentered) {
  115. titleView.setX(ViewUtils.getWindowWidth((Activity) getContext()) / 2 - titleView.getWidth() / 2);
  116. }
  117. }
  118. });
  119. }
  120. private void colorOverflowButton(StyleParams params) {
  121. Drawable overflowIcon = actionMenuView.getOverflowIcon();
  122. if (shouldColorOverflowButton(params, overflowIcon)) {
  123. ViewUtils.tintDrawable(overflowIcon, params.titleBarButtonColor.getColor(), true);
  124. }
  125. }
  126. protected void setBackground(StyleParams params) {
  127. setTranslucent(params);
  128. }
  129. protected void setTranslucent(StyleParams params) {
  130. if (params.topBarTranslucent) {
  131. setBackground(new TranslucentDrawable());
  132. }
  133. }
  134. private boolean shouldColorOverflowButton(StyleParams params, Drawable overflowIcon) {
  135. return overflowIcon != null && params.titleBarButtonColor.hasColor();
  136. }
  137. protected void setTitleTextColor(StyleParams params) {
  138. if (params.titleBarTitleColor.hasColor()) {
  139. setTitleTextColor(params.titleBarTitleColor.getColor());
  140. }
  141. }
  142. protected void setTitleTextFont(StyleParams params) {
  143. if (!params.titleBarTitleFont.hasFont()) {
  144. return;
  145. }
  146. View titleView = getTitleView();
  147. if (titleView instanceof TextView) {
  148. ((TextView) titleView).setTypeface(params.titleBarTitleFont.get());
  149. }
  150. }
  151. protected void setTitleTextFontSize(StyleParams params) {
  152. if (params.titleBarTitleFontSize > 0) {
  153. View titleView = getTitleView();
  154. if (titleView instanceof TextView) {
  155. ((TextView) titleView).setTextSize(((float) params.titleBarTitleFontSize));
  156. }
  157. }
  158. }
  159. protected void setTitleTextFontWeight(StyleParams params) {
  160. if (params.titleBarTitleFontBold) {
  161. View titleView = getTitleView();
  162. if (titleView instanceof TextView) {
  163. ((TextView) titleView).setTypeface(((TextView) titleView).getTypeface(), Typeface.BOLD);
  164. }
  165. }
  166. }
  167. protected void setSubtitleTextColor(StyleParams params) {
  168. if (params.titleBarSubtitleColor.hasColor()) {
  169. setSubtitleTextColor(params.titleBarSubtitleColor.getColor());
  170. }
  171. }
  172. private void addButtonsToTitleBar(String navigatorEventId, Menu menu) {
  173. for (int i = 0; i < rightButtons.size(); i++) {
  174. final TitleBarButton button = new TitleBarButton(menu, this, rightButtons.get(i), navigatorEventId);
  175. addButtonInReverseOrder(rightButtons, i, button);
  176. }
  177. }
  178. protected void addButtonInReverseOrder(List<? extends BaseTitleBarButtonParams> buttons, int i, TitleBarButton button) {
  179. final int index = buttons.size() - i - 1;
  180. button.addToMenu(index);
  181. }
  182. private boolean hasLeftButton() {
  183. return leftButton != null;
  184. }
  185. private void updateLeftButton(TitleBarLeftButtonParams leftButtonParams) {
  186. if (leftButtonParams.hasDefaultIcon()) {
  187. leftButton.setIconState(leftButtonParams);
  188. setNavigationIcon(leftButton);
  189. } else if (leftButtonParams.hasCustomIcon()) {
  190. leftButton.setCustomIcon(leftButtonParams);
  191. setNavigationIcon(leftButtonParams.icon);
  192. }
  193. }
  194. private boolean shouldSetLeftButton(TitleBarLeftButtonParams leftButtonParams) {
  195. return leftButton == null && leftButtonParams != null && (leftButtonParams.hasDefaultIcon() || leftButtonParams.hasCustomIcon());
  196. }
  197. private void createAndSetLeftButton(TitleBarLeftButtonParams leftButtonParams,
  198. LeftButtonOnClickListener leftButtonOnClickListener,
  199. String navigatorEventId,
  200. boolean overrideBackPressInJs) {
  201. leftButton = new LeftButton(getContext(), leftButtonParams, leftButtonOnClickListener, navigatorEventId,
  202. overrideBackPressInJs);
  203. setNavigationOnClickListener(leftButton);
  204. if (leftButtonParams.hasCustomIcon()) {
  205. setNavigationIcon(leftButtonParams.icon);
  206. } else {
  207. setNavigationIcon(leftButton);
  208. }
  209. }
  210. public void hide() {
  211. hide(null);
  212. }
  213. public void hide(@Nullable final Runnable onHidden) {
  214. animate()
  215. .alpha(0)
  216. .setDuration(200)
  217. .setInterpolator(new AccelerateInterpolator())
  218. .setListener(new AnimatorListenerAdapter() {
  219. @Override
  220. public void onAnimationEnd(Animator animation) {
  221. if (onHidden != null) {
  222. onHidden.run();
  223. }
  224. }
  225. });
  226. }
  227. public void show() {
  228. this.show(null);
  229. }
  230. public void show(final @Nullable Runnable onDisplayed) {
  231. setAlpha(0);
  232. animate()
  233. .alpha(1)
  234. .setDuration(200)
  235. .setInterpolator(new AccelerateDecelerateInterpolator())
  236. .setListener(new AnimatorListenerAdapter() {
  237. @Override
  238. public void onAnimationEnd(Animator animation) {
  239. if (onDisplayed != null) {
  240. onDisplayed.run();
  241. }
  242. }
  243. });
  244. }
  245. public void showTitle() {
  246. animateTitle(1);
  247. }
  248. public void hideTitle() {
  249. animateTitle(0);
  250. }
  251. private void animateTitle(int alpha) {
  252. View titleView = getTitleView();
  253. if (titleView != null) {
  254. titleView.animate()
  255. .alpha(alpha)
  256. .setDuration(TITLE_VISIBILITY_ANIMATION_DURATION);
  257. }
  258. }
  259. @Nullable
  260. protected View getTitleView() {
  261. return ViewUtils.findChildByClass(this, TextView.class, new ViewUtils.Matcher<TextView>() {
  262. @Override
  263. public boolean match(TextView child) {
  264. return child.getText().equals(getTitle());
  265. }
  266. });
  267. }
  268. @Nullable
  269. private TextView getSubtitleView() {
  270. if (TextUtils.isEmpty(getSubtitle())) return null;
  271. return ViewUtils.findChildByClass(this, TextView.class, new ViewUtils.Matcher<TextView>() {
  272. @Override
  273. public boolean match(TextView child) {
  274. return child.getText().equals(getSubtitle());
  275. }
  276. });
  277. }
  278. public void setButtonColor(StyleParams.Color titleBarButtonColor) {
  279. if (!titleBarButtonColor.hasColor()) {
  280. return;
  281. }
  282. updateButtonColor(titleBarButtonColor);
  283. setLeftButtonColor(titleBarButtonColor);
  284. setButtonsIconColor();
  285. setButtonTextColor();
  286. }
  287. private void setLeftButtonColor(StyleParams.Color titleBarButtonColor) {
  288. if (leftButton != null) {
  289. leftButton.setColor(titleBarButtonColor.getColor());
  290. }
  291. }
  292. private void updateButtonColor(StyleParams.Color titleBarButtonColor) {
  293. if (rightButtons != null) {
  294. for (TitleBarButtonParams rightButton : rightButtons) {
  295. rightButton.color = titleBarButtonColor;
  296. }
  297. }
  298. }
  299. private void setButtonTextColor() {
  300. final ActionMenuView buttonsContainer = ViewUtils.findChildByClass(this, ActionMenuView.class);
  301. if (buttonsContainer != null) {
  302. for (int i = 0; i < buttonsContainer.getChildCount(); i++) {
  303. if (buttonsContainer.getChildAt(i) instanceof TextView) {
  304. ((TextView) buttonsContainer.getChildAt(i)).setTextColor(getButton(i).getColor().getColor());
  305. }
  306. }
  307. }
  308. }
  309. private void setButtonsIconColor() {
  310. final Menu menu = getMenu();
  311. for (int i = 0; i < menu.size(); i++) {
  312. if (menu.getItem(i).getIcon() != null) {
  313. ViewUtils.tintDrawable(menu.getItem(i).getIcon(),
  314. getButton(i).getColor().getColor(),
  315. getButton(i).enabled);
  316. }
  317. }
  318. }
  319. BaseTitleBarButtonParams getButton(int index) {
  320. return rightButtons.get(rightButtons.size() - index - 1);
  321. }
  322. public void onViewPagerScreenChanged(BaseScreenParams screenParams) {
  323. if (hasLeftButton()) {
  324. leftButton.updateNavigatorEventId(screenParams.getNavigatorEventId());
  325. }
  326. }
  327. public void destroy() {
  328. unmountCustomButtons();
  329. }
  330. private void unmountCustomButtons() {
  331. for (int i = 0; i < actionMenuView.getChildCount(); i++) {
  332. if (actionMenuView.getChildAt(i) instanceof TitleBarButtonComponent) {
  333. ((ContentView) actionMenuView.getChildAt(i)).unmountReactView();
  334. }
  335. }
  336. }
  337. }