Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ repositories {

dependencies {
compile fileTree(dir: "libs", include: ["*.jar"])
compile "com.aurelhubert:ahbottomnavigation:1.2.3"
compile "com.android.support:appcompat-v7:23.0.1"
compile 'com.android.support:design:23.1.1'
compile "com.facebook.react:react-native:+" // From node_modules
Expand Down
1 change: 1 addition & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

<application>
<activity android:name="com.reactnativenavigation.activities.TabActivity" />
<activity android:name="com.reactnativenavigation.activities.BottomTabActivity" />
<activity android:name="com.reactnativenavigation.activities.SingleScreenActivity" />
</application>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ protected ReactRootView createRootView() {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ContextProvider.setActivityContext(this);
mReactInstanceManager = createReactInstanceManager();
handleOnCreate();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
package com.reactnativenavigation.activities;

import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.widget.FrameLayout;

import com.aurelhubert.ahbottomnavigation.AHBottomNavigation;
import com.aurelhubert.ahbottomnavigation.AHBottomNavigationItem;
import com.reactnativenavigation.R;
import com.reactnativenavigation.core.RctManager;
import com.reactnativenavigation.core.objects.Screen;
import com.reactnativenavigation.views.RnnToolBar;
import com.reactnativenavigation.views.ScreenStack;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;

/**
* Created by guyc on 02/04/16.
*/
public class BottomTabActivity extends BaseReactActivity implements AHBottomNavigation.OnTabSelectedListener {
public static final String EXTRA_SCREENS = "extraScreens";

private static final String TAB_STYLE_BUTTON_COLOR = "tabBarButtonColor";
private static final String TAB_STYLE_SELECTED_COLOR = "tabBarSelectedButtonColor";
private static final String TAB_STYLE_BAR_BG_COLOR = "tabBarBackgroundColor";
private static final String TAB_STYLE_INACTIVE_TITLES = "tabShowInactiveTitles";

private static int DEFAULT_TAB_BAR_BG_COLOR = 0xFFFFFFFF;
private static int DEFAULT_TAB_BUTTON_COLOR = Color.GRAY;
private static int DEFAULT_TAB_SELECTED_COLOR = 0xFF0000FF;
private static boolean DEFAULT_TAB_INACTIVE_TITLES = true;

private AHBottomNavigation mBottomNavigation;
private FrameLayout mContentFrame;
private ArrayList<ScreenStack> mScreenStacks;
private int mCurrentStackPosition = 0;

@Override
protected void handleOnCreate() {
mReactInstanceManager = RctManager.getInstance().getReactInstanceManager();

setContentView(R.layout.bottom_tab_activity);
mToolbar = (RnnToolBar) findViewById(R.id.toolbar);
mBottomNavigation = (AHBottomNavigation) findViewById(R.id.bottom_tab_bar);
mContentFrame = (FrameLayout) findViewById(R.id.contentFrame);

ArrayList<Screen> screens = (ArrayList<Screen>) getIntent().getSerializableExtra(EXTRA_SCREENS);
mBottomNavigation.setForceTint(true);
setupToolbar(screens);
setupTabs(getIntent().getExtras());
setupPages(screens);
}

private void setupPages(ArrayList<Screen> screens) {
new SetupTabsTask(this, screens).execute();
}

private void setupToolbar(ArrayList<Screen> screens) {
Screen initialScreen = screens.get(0);
setNavigationStyle(initialScreen);
mToolbar.setScreens(screens);
mToolbar.setTitle(initialScreen.title);
setSupportActionBar(mToolbar);
}

@Override
public void setNavigationStyle(Screen screen) {
super.setNavigationStyle(screen);
mToolbar.setTitle(screen.title);
}

private void setupTabs(Bundle style) {

mBottomNavigation.setForceTitlesDisplay(style.getBoolean(TAB_STYLE_INACTIVE_TITLES, DEFAULT_TAB_INACTIVE_TITLES));
mBottomNavigation.setForceTint(true);
mBottomNavigation.setDefaultBackgroundColor(getColor(style, TAB_STYLE_BAR_BG_COLOR, DEFAULT_TAB_BAR_BG_COLOR));
mBottomNavigation.setInactiveColor(getColor(style, TAB_STYLE_BUTTON_COLOR, DEFAULT_TAB_BUTTON_COLOR));
mBottomNavigation.setAccentColor(getColor(style, TAB_STYLE_SELECTED_COLOR, DEFAULT_TAB_SELECTED_COLOR));
}

private static int getColor(Bundle bundle, String key, int defaultColor) {
if (bundle.containsKey(key)) {
return Color.parseColor(bundle.getString(key));
}
else {
return defaultColor;
}
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
boolean ret = super.onCreateOptionsMenu(menu);
mToolbar.handleOnCreateOptionsMenuAsync();
return ret;
}

@Override
public void push(Screen screen) {
super.push(screen);
mScreenStacks.get(mCurrentStackPosition).push(screen);
}

@Override
public Screen pop(String navigatorId) {
super.pop(navigatorId);
Screen screen = mScreenStacks.get(mCurrentStackPosition).pop();
setNavigationStyle(screen);
return screen;
}

@Override
protected Screen getCurrentScreen() {
return mScreenStacks.get(mCurrentStackPosition).peek();
}

@Override
protected String getCurrentNavigatorId() {
return mScreenStacks.get(mCurrentStackPosition).peek().navigatorId;
}

@Override
public int getScreenStackSize() {
return mScreenStacks.get(mCurrentStackPosition).getStackSize();
}

@Override
public void onTabSelected(int position, boolean wasSelected) {
if (wasSelected) {
return;
}
mContentFrame.removeAllViews();
mContentFrame.addView(mScreenStacks.get(position), new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
mCurrentStackPosition = position;
setNavigationStyle(mScreenStacks.get(mCurrentStackPosition).peek());
}

private static class SetupTabsTask extends AsyncTask<Void, Void, Map<Screen, Drawable>> {
private BottomTabActivity mActivity;
private ArrayList<Screen> mScreens;

public SetupTabsTask(BottomTabActivity context, ArrayList<Screen> screens) {
mActivity = context;
mScreens = screens;
}

@Override
protected Map<Screen, Drawable> doInBackground(Void... params) {
Map<Screen, Drawable> icons = new HashMap<>();
for (Screen screen : mScreens) {
if (screen.icon != null) {
icons.put(screen, screen.getIcon(this.mActivity));
}
}
return icons;
}

@Override
protected void onPostExecute(Map<Screen, Drawable> icons) {
mActivity.setTabsWithIcons(mScreens, icons);
}
}

private void setTabsWithIcons(ArrayList<Screen> screens, Map<Screen, Drawable> icons) {
mScreenStacks = new ArrayList<>();
for(Screen screen: screens) {
ScreenStack stack = new ScreenStack(this);
stack.push(screen);
mScreenStacks.add(stack);
AHBottomNavigationItem item = new AHBottomNavigationItem(screen.label, icons.get(screen), Color.GRAY);
mBottomNavigation.addItem(item);
mBottomNavigation.setOnTabSelectedListener(this);
}
this.onTabSelected(0, false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ private void setupToolbar(ArrayList<Screen> screens) {
setNavigationStyle(initialScreen);
mToolbar.setScreens(screens);
mToolbar.setTitle(initialScreen.title);
mToolbar.setupToolbarButtonsAsync(initialScreen);
setSupportActionBar(mToolbar);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import com.facebook.react.bridge.ReadableMap;
import com.reactnativenavigation.BuildConfig;
import com.reactnativenavigation.utils.IconUtils;
import com.reactnativenavigation.utils.ResourceDrawableIdHelper;

import java.io.Serializable;
Expand All @@ -24,13 +25,10 @@
public class Button extends JsonObject implements Serializable {
private static final long serialVersionUID = -570145217281069067L;

public static final String LOCAL_RESOURCE_URI_SCHEME = "res";
private static final String KEY_ID = "id";
private static final String KEY_TITLE = "title";
private static final String KEY_ICON = "icon";

private static ResourceDrawableIdHelper sResDrawableIdHelper = new ResourceDrawableIdHelper();

public String id;
public String title;
private String mIconSource;
Expand All @@ -49,47 +47,7 @@ public boolean hasIcon() {
}

public Drawable getIcon(Context ctx) {
if (mIconSource == null) {
return null;
}

try {
Drawable icon;
Uri iconUri = getIconUri(ctx);

if (LOCAL_RESOURCE_URI_SCHEME.equals(iconUri.getScheme())) {
icon = sResDrawableIdHelper.getResourceDrawable(ctx, mIconSource);
} else {
URL url = new URL(iconUri.toString());
Bitmap bitmap = BitmapFactory.decodeStream(url.openStream());
icon = new BitmapDrawable(bitmap);
}
return icon;
} catch (Exception e) {
if (BuildConfig.DEBUG) {
e.printStackTrace();
}
}
return null;
}

private Uri getIconUri(Context context) {
Uri ret = null;
if (mIconSource != null) {
try {
ret = Uri.parse(mIconSource);
// Verify scheme is set, so that relative uri (used by static resources) are not handled.
if (ret.getScheme() == null) {
ret = null;
}
} catch (Exception e) {
// Ignore malformed uri, then attempt to extract resource ID.
}
if (ret == null) {
ret = sResDrawableIdHelper.getResourceDrawableUri(context, mIconSource);
}
}
return ret;
return IconUtils.getIcon(ctx, mIconSource);
}

public int getItemId() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package com.reactnativenavigation.core.objects;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableNativeMap;
import com.reactnativenavigation.utils.IconUtils;

import java.io.Serializable;
import java.util.ArrayList;
Expand Down Expand Up @@ -37,15 +40,15 @@ public class Screen extends JsonObject implements Serializable {
private static final String KEY_TAB_NORMAL_TEXT_COLOR = "tabNormalTextColor";
private static final String KEY_TAB_SELECTED_TEXT_COLOR = "tabSelectedTextColor";
private static final String KEY_TAB_INDICATOR_COLOR = "tabIndicatorColor";
public static final String KEY_PROPS = "passProps";
private static final String KEY_PROPS = "passProps";

public final String title;
public final String label;
public final String screenId;
public final String screenInstanceId;
public final String navigatorId;
public final String navigatorEventId;
public final int icon;
public final String icon;
public final ArrayList<Button> buttons;
public HashMap<String, Object> passedProps = new HashMap<>();

Expand All @@ -71,7 +74,7 @@ public Screen(ReadableMap screen) {
screenInstanceId = getString(screen, KEY_SCREEN_INSTANCE_ID);
navigatorId = getString(screen, KEY_NAVIGATOR_ID);
navigatorEventId = getString(screen, KEY_NAVIGATOR_EVENT_ID);
icon = getInt(screen, KEY_ICON);
icon = getString(screen, KEY_ICON);
if(screen.hasKey(KEY_PROPS)) {
passedProps = ((ReadableNativeMap) screen.getMap(KEY_PROPS)).toHashMap();
}
Expand All @@ -90,6 +93,10 @@ private ArrayList<Button> getButtons(ReadableMap screen) {
return ret;
}

public Drawable getIcon(Context ctx) {
return IconUtils.getIcon(ctx, icon);
}

public void setToolbarStyle(ReadableMap screen) {
ReadableMap style = getMap(screen, KEY_TOOL_BAR_STYLE);
if (style != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableNativeMap;
import com.reactnativenavigation.activities.BaseReactActivity;
import com.reactnativenavigation.activities.BottomTabActivity;
import com.reactnativenavigation.activities.SingleScreenActivity;
import com.reactnativenavigation.activities.TabActivity;
import com.reactnativenavigation.controllers.ModalController;
import com.reactnativenavigation.core.objects.Screen;
import com.reactnativenavigation.modal.RnnModal;
import com.reactnativenavigation.utils.BridgeUtils;
import com.reactnativenavigation.utils.ContextProvider;

import java.util.ArrayList;
Expand All @@ -35,14 +37,17 @@ public String getName() {
}

@ReactMethod
public void startTabBasedApp(ReadableArray screens) {
public void startTabBasedApp(ReadableArray screens, ReadableMap style) {
Activity context = ContextProvider.getActivityContext();
if (context != null && !context.isFinishing()) {
Intent intent = new Intent(context, TabActivity.class);
Intent intent = new Intent(context, BottomTabActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);

Bundle extras = new Bundle();
extras.putSerializable(TabActivity.EXTRA_SCREENS, createScreens(screens));
extras.putSerializable(BottomTabActivity.EXTRA_SCREENS, createScreens(screens));
if (style != null) {
BridgeUtils.addMapToBundle(((ReadableNativeMap) style).toHashMap(), extras);
}
intent.putExtras(extras);

context.startActivity(intent);
Expand Down
Loading