TabLayout

This commit is contained in:
serso 2016-02-21 20:53:47 +01:00
parent 65fb876c5e
commit b4ca63a39e
29 changed files with 407 additions and 462 deletions

View File

@ -23,49 +23,74 @@
package org.solovyev.android.calculator;
import android.app.Activity;
import android.app.KeyguardManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.LayoutRes;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import butterknife.Bind;
import butterknife.ButterKnife;
import org.solovyev.android.Activities;
import org.solovyev.android.Check;
import org.solovyev.android.Views;
import org.solovyev.android.calculator.history.History;
import org.solovyev.android.calculator.language.Language;
import org.solovyev.android.calculator.language.Languages;
import org.solovyev.android.sherlock.tabs.ActionBarFragmentTabListener;
import org.solovyev.android.calculator.view.Tabs;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject;
public class ActivityUi extends BaseUi {
import static org.solovyev.android.calculator.App.cast;
public class ActivityUi {
@Nonnull
private final AppCompatActivity activity;
private final int layoutId;
@Nonnull
private final Tabs tabs;
@Inject
SharedPreferences preferences;
@Inject
Editor editor;
@Inject
History history;
@Inject
Keyboard keyboard;
@Inject
Calculator calculator;
@Inject
Typeface typeface;
@Bind(R.id.main)
ViewGroup mainView;
@Nullable
@Bind(R.id.toolbar)
Toolbar toolbar;
@Nonnull
private Preferences.Gui.Theme theme = Preferences.Gui.Theme.material_theme;
@Nonnull
private Preferences.Gui.Layout layout = Preferences.Gui.Layout.main_calculator;
@Nonnull
private Language language = Languages.SYSTEM_LANGUAGE;
private int selectedNavigationIndex = 0;
public ActivityUi(@LayoutRes int layoutId, @Nonnull String logTag) {
super(logTag);
public ActivityUi(@Nonnull AppCompatActivity activity, @LayoutRes int layoutId) {
this.activity = activity;
this.layoutId = layoutId;
tabs = new Tabs(activity);
}
public static boolean restartIfThemeChanged(@Nonnull Activity activity, @Nonnull Preferences.Gui.Theme oldTheme) {
@ -96,6 +121,20 @@ public class ActivityUi extends BaseUi {
App.getGa().getAnalytics().reportActivityStart(activity);
}
@Nonnull
private static String makeLastTabKey(@Nonnull Activity activity) {
return "tab_" + activity.getClass().getSimpleName();
}
public static void setFont(@Nonnull TextView view, @Nonnull Typeface newTypeface) {
final Typeface oldTypeface = view.getTypeface();
if (oldTypeface == newTypeface) {
return;
}
final int style = oldTypeface != null ? oldTypeface.getStyle() : Typeface.NORMAL;
view.setTypeface(newTypeface, style);
}
public void onPreCreate(@Nonnull Activity activity) {
final SharedPreferences preferences = App.getPreferences();
@ -106,9 +145,16 @@ public class ActivityUi extends BaseUi {
language = App.getLanguages().getCurrent();
}
@Override
public void onCreate(@Nonnull Activity activity) {
super.onCreate(activity);
public void onCreate() {
cast(activity.getApplication()).getComponent().inject(this);
// let's disable locking of screen for monkeyrunner
if (App.isMonkeyRunner(activity)) {
final KeyguardManager km = (KeyguardManager) activity.getSystemService(Context.KEYGUARD_SERVICE);
//noinspection deprecation
km.newKeyguardLock(activity.getClass().getName()).disableKeyguard();
}
App.getLanguages().updateContextLocale(activity, false);
if (activity instanceof CalculatorEventListener) {
@ -116,51 +162,31 @@ public class ActivityUi extends BaseUi {
}
activity.setContentView(layoutId);
ButterKnife.bind(this, activity);
final View root = activity.findViewById(R.id.main);
if (root != null) {
fixFonts(root);
addHelpInfo(activity, root);
}
fixFonts(mainView);
addHelpInfo(activity, mainView);
initToolbar();
}
public void onCreate(@Nonnull final AppCompatActivity activity) {
onCreate((Activity) activity);
final ActionBar actionBar = activity.getSupportActionBar();
if (actionBar != null) {
initActionBar(activity, actionBar);
private void initToolbar() {
if (toolbar == null) {
return;
}
}
private void initActionBar(@Nonnull Activity activity, @Nonnull ActionBar actionBar) {
actionBar.setDisplayUseLogoEnabled(false);
final boolean homeAsUp = !(activity instanceof CalculatorActivity);
actionBar.setDisplayHomeAsUpEnabled(homeAsUp);
actionBar.setHomeButtonEnabled(false);
actionBar.setDisplayShowHomeEnabled(true);
actionBar.setElevation(0);
toggleTitle(activity, actionBar, true);
if (!homeAsUp) {
actionBar.setIcon(R.drawable.ab_logo);
}
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
}
private void toggleTitle(@Nonnull Activity activity, @Nonnull ActionBar actionBar, boolean showTitle) {
if (activity instanceof CalculatorActivity) {
if (Views.getScreenOrientation(activity) == Configuration.ORIENTATION_PORTRAIT) {
actionBar.setDisplayShowTitleEnabled(true);
} else {
actionBar.setDisplayShowTitleEnabled(false);
}
} else {
actionBar.setDisplayShowTitleEnabled(showTitle);
return;
}
toolbar.setNavigationIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
activity.onBackPressed();
}
});
toolbar.setTitle(activity.getTitle());
}
public void restoreSavedTab(@Nonnull AppCompatActivity activity) {
public void restoreSavedTab() {
final ActionBar actionBar = activity.getSupportActionBar();
if (actionBar != null) {
if (selectedNavigationIndex >= 0 && selectedNavigationIndex < actionBar.getTabCount()) {
@ -169,25 +195,7 @@ public class ActivityUi extends BaseUi {
}
}
public void onSaveInstanceState(@Nonnull AppCompatActivity activity, @Nonnull Bundle outState) {
onSaveInstanceState((Activity) activity, outState);
}
public void onSaveInstanceState(@Nonnull Activity activity, @Nonnull Bundle outState) {
}
public void onResume(@Nonnull Activity activity) {
if (!restartIfThemeChanged(activity, theme)) {
restartIfLanguageChanged(activity, language);
}
}
public void onPause(@Nonnull Activity activity) {
}
public void onPause(@Nonnull AppCompatActivity activity) {
onPause((Activity) activity);
public void onPause() {
final ActionBar actionBar = activity.getSupportActionBar();
if (actionBar != null) {
final int selectedNavigationIndex = actionBar.getSelectedNavigationIndex();
@ -200,71 +208,23 @@ public class ActivityUi extends BaseUi {
}
}
@Nonnull
private static String makeLastTabKey(@Nonnull Activity activity) {
return "tab_" + activity.getClass().getSimpleName();
public void onDestroy() {
}
@Override
public void onDestroy(@Nonnull Activity activity) {
super.onDestroy(activity);
if (activity instanceof CalculatorEventListener) {
Locator.getInstance().getCalculator().removeCalculatorEventListener((CalculatorEventListener) activity);
}
}
public void onDestroy(@Nonnull AppCompatActivity activity) {
this.onDestroy((Activity) activity);
}
public void addTab(@Nonnull AppCompatActivity activity,
@Nonnull String tag,
@Nonnull Class<? extends Fragment> fragmentClass,
public void addTab(@Nonnull Class<? extends Fragment> fragmentClass,
@Nullable Bundle fragmentArgs,
int title,
int parentViewId) {
addTab(activity, tag, fragmentClass, fragmentArgs, activity.getString(title), parentViewId);
int title) {
addTab(fragmentClass, fragmentArgs, activity.getString(title));
}
public void addTab(@Nonnull AppCompatActivity activity,
@Nonnull String tag,
@Nonnull Class<? extends Fragment> fragmentClass,
public void addTab(@Nonnull Class<? extends Fragment> fragmentClass,
@Nullable Bundle fragmentArgs,
@Nullable CharSequence title,
int parentViewId) {
final ActionBar actionBar = activity.getSupportActionBar();
Check.isNotNull(actionBar);
final ActionBar.Tab tab = actionBar.newTab();
tab.setTag(tag);
tab.setText(title);
final ActionBarFragmentTabListener listener = new ActionBarFragmentTabListener(activity, tag, fragmentClass, fragmentArgs, parentViewId);
tab.setTabListener(listener);
actionBar.addTab(tab);
@Nonnull CharSequence title) {
tabs.addTab(fragmentClass, fragmentArgs, title);
}
public void addTab(@Nonnull AppCompatActivity activity, @Nonnull FragmentTab tab, @Nullable Bundle fragmentArgs, int parentViewId) {
addTab(activity, tab.tag, tab.type, fragmentArgs, tab.title, parentViewId);
}
public void setFragment(@Nonnull AppCompatActivity activity, @Nonnull FragmentTab tab, @Nullable Bundle fragmentArgs, int parentViewId) {
final FragmentManager fm = activity.getSupportFragmentManager();
Fragment fragment = fm.findFragmentByTag(tab.tag);
if (fragment == null) {
fragment = Fragment.instantiate(activity, tab.type.getName(), fragmentArgs);
final FragmentTransaction ft = fm.beginTransaction();
ft.add(parentViewId, fragment, tab.tag);
ft.commit();
} else {
if (fragment.isDetached()) {
final FragmentTransaction ft = fm.beginTransaction();
ft.attach(fragment);
ft.commit();
}
}
public void addTab(@Nonnull FragmentTab tab, @Nullable Bundle fragmentArgs) {
addTab(tab.type, fragmentArgs, tab.title);
}
@Nonnull
@ -277,12 +237,19 @@ public class ActivityUi extends BaseUi {
return layout;
}
public void onResume(@Nonnull AppCompatActivity activity) {
onResume((Activity) activity);
@Nonnull
public Preferences.Gui.Theme getTheme() {
return theme;
}
public void onResume() {
if (!restartIfThemeChanged(activity, theme)) {
restartIfLanguageChanged(activity, language);
}
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
selectedNavigationIndex = preferences.getInt(makeLastTabKey(activity), -1);
restoreSavedTab(activity);
restoreSavedTab();
}
private void addHelpInfo(@Nonnull Activity activity, @Nonnull View root) {
@ -351,4 +318,23 @@ public class ActivityUi extends BaseUi {
public void onStart(@Nonnull Activity activity) {
reportActivityStart(activity);
}
protected void fixFonts(@Nonnull View root) {
// some devices ship own fonts which causes issues with rendering. Let's use our own font for all text views
Views.processViewsOfType(root, TextView.class, new Views.ViewProcessor<TextView>() {
@Override
public void process(@Nonnull TextView view) {
setFont(view, typeface);
}
});
}
public void onPostCreate() {
tabs.onCreate();
}
@Nonnull
public Tabs getTabs() {
return tabs;
}
}

View File

@ -26,7 +26,7 @@ import javax.inject.Singleton;
public interface AppComponent {
void inject(CalculatorApplication application);
void inject(EditorFragment fragment);
void inject(BaseUi ui);
void inject(ActivityUi ui);
void inject(FloatingCalculatorService service);
void inject(BaseHistoryFragment fragment);
void inject(BaseDialogFragment fragment);

View File

@ -5,11 +5,9 @@ import android.support.annotation.LayoutRes;
import android.support.v7.app.AppCompatActivity;
import android.view.KeyEvent;
import android.view.MenuItem;
import org.solovyev.android.calculator.entities.BaseEntitiesFragment;
import org.solovyev.android.calculator.entities.Category;
import org.solovyev.android.calculator.view.Tabs;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import static org.solovyev.android.calculator.App.cast;
@ -19,11 +17,11 @@ public class BaseActivity extends AppCompatActivity {
protected final ActivityUi ui;
public BaseActivity() {
this(R.layout.main_empty);
this(R.layout.activity_empty);
}
public BaseActivity(@LayoutRes int layout) {
this.ui = new ActivityUi(layout, getClass().getSimpleName());
this.ui = new ActivityUi(this, layout);
}
@Nonnull
@ -36,18 +34,17 @@ public class BaseActivity extends AppCompatActivity {
ui.onPreCreate(this);
super.onCreate(savedInstanceState);
inject(cast(getApplication()).getComponent());
ui.onCreate(this);
ui.onCreate();
populateTabs(ui.getTabs());
ui.onPostCreate();
}
protected void populateTabs(@Nonnull Tabs tabs) {
}
protected void inject(@Nonnull AppComponent component) {
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
ui.onSaveInstanceState(this, outState);
}
@Override
protected void onStart() {
super.onStart();
@ -72,19 +69,19 @@ public class BaseActivity extends AppCompatActivity {
@Override
protected void onResume() {
super.onResume();
ui.onResume(this);
ui.onResume();
}
@Override
protected void onPause() {
this.ui.onPause(this);
this.ui.onPause();
super.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
ui.onDestroy(this);
ui.onDestroy();
}
@Override
@ -96,16 +93,4 @@ public class BaseActivity extends AppCompatActivity {
}
return super.onOptionsItemSelected(item);
}
protected final void addTab(@Nonnull Category category, @Nonnull FragmentTab tab) {
final CharSequence title = getString(category.title());
addTab(category, tab, title);
}
protected final void addTab(@Nonnull Category category, @Nonnull FragmentTab tab, @Nullable CharSequence title) {
final Bundle arguments = new Bundle(1);
arguments.putString(BaseEntitiesFragment.ARG_CATEGORY, category.name());
final String fragmentTag = tab.subTag(category.name());
ui.addTab(this, fragmentTag, tab.type, arguments, title, R.id.main);
}
}

View File

@ -1,115 +0,0 @@
/*
* Copyright 2013 serso aka se.solovyev
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Contact details
*
* Email: se.solovyev@gmail.com
* Site: http://se.solovyev.org
*/
package org.solovyev.android.calculator;
import android.app.Activity;
import android.app.KeyguardManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Typeface;
import android.view.View;
import android.widget.TextView;
import org.solovyev.android.Views;
import org.solovyev.android.calculator.history.History;
import javax.annotation.Nonnull;
import javax.inject.Inject;
import static org.solovyev.android.calculator.App.cast;
public abstract class BaseUi {
@Nonnull
protected Preferences.Gui.Layout layout;
@Nonnull
protected Preferences.Gui.Theme theme;
protected BaseUi() {
}
protected BaseUi(@Nonnull String logTag) {
}
@Inject
SharedPreferences preferences;
@Inject
Editor editor;
@Inject
History history;
@Inject
Keyboard keyboard;
@Inject
Calculator calculator;
@Inject
PreferredPreferences preferredPreferences;
@Inject
ActivityLauncher launcher;
@Inject
Typeface typeface;
protected void onCreate(@Nonnull Activity activity) {
inject(cast(activity.getApplication()).getComponent());
layout = Preferences.Gui.layout.getPreferenceNoError(preferences);
theme = Preferences.Gui.theme.getPreferenceNoError(preferences);
// let's disable locking of screen for monkeyrunner
if (App.isMonkeyRunner(activity)) {
final KeyguardManager km = (KeyguardManager) activity.getSystemService(Context.KEYGUARD_SERVICE);
//noinspection deprecation
km.newKeyguardLock(activity.getClass().getName()).disableKeyguard();
}
}
protected void inject(@Nonnull AppComponent component) {
component.inject(this);
}
@Nonnull
public Preferences.Gui.Theme getTheme() {
return theme;
}
public void onDestroy(@Nonnull Activity activity) {
}
protected void fixFonts(@Nonnull View root) {
// some devices ship own fonts which causes issues with rendering. Let's use our own font for all text views
Views.processViewsOfType(root, TextView.class, new Views.ViewProcessor<TextView>() {
@Override
public void process(@Nonnull TextView view) {
setFont(view, typeface);
}
});
}
public static void setFont(@Nonnull TextView view, @Nonnull Typeface newTypeface) {
final Typeface oldTypeface = view.getTypeface();
if (oldTypeface == newTypeface) {
return;
}
final int style = oldTypeface != null ? oldTypeface.getStyle() : Typeface.NORMAL;
view.setTypeface(newTypeface, style);
}
}

View File

@ -290,22 +290,20 @@ public final class Preferences {
public enum Theme {
default_theme(R.style.Cpp_Theme_Gray, R.style.Cpp_Theme_Gray_NoActionBar),
violet_theme(R.style.Cpp_Theme_Violet, R.style.Cpp_Theme_Violet_NoActionBar),
light_blue_theme(R.style.Cpp_Theme_Blue, R.style.Cpp_Theme_Blue_NoActionBar),
metro_blue_theme(R.style.Cpp_Theme_Metro_Blue, R.style.Cpp_Theme_Metro_Blue_NoActionBar),
metro_purple_theme(R.style.Cpp_Theme_Metro_Purple, R.style.Cpp_Theme_Metro_Purple_NoActionBar),
metro_green_theme(R.style.Cpp_Theme_Metro_Green, R.style.Cpp_Theme_Metro_Green_NoActionBar),
material_theme(R.style.Cpp_Theme_Material, R.style.Cpp_Theme_Material_NoActionBar),
material_light_theme(R.style.Cpp_Theme_Material_Light, R.style.Cpp_Theme_Material_Light_NoActionBar, R.style.Cpp_Theme_Wizard_Light, R.style.Cpp_Theme_Material_Light_Dialog, R.style.Cpp_Theme_Material_Light_Dialog_Alert);
default_theme(R.style.Cpp_Theme_Gray),
violet_theme(R.style.Cpp_Theme_Violet),
light_blue_theme(R.style.Cpp_Theme_Blue),
metro_blue_theme(R.style.Cpp_Theme_Metro_Blue),
metro_purple_theme(R.style.Cpp_Theme_Metro_Purple),
metro_green_theme(R.style.Cpp_Theme_Metro_Green),
material_theme(R.style.Cpp_Theme_Material),
material_light_theme(R.style.Cpp_Theme_Material_Light, R.style.Cpp_Theme_Wizard_Light, R.style.Cpp_Theme_Material_Light_Dialog, R.style.Cpp_Theme_Material_Light_Dialog_Alert);
private static final SparseArray<TextColor> textColors = new SparseArray<>();
@StyleRes
public final int theme;
@StyleRes
public final int mainTheme;
@StyleRes
public final int wizardTheme;
@StyleRes
public final int dialogTheme;
@ -313,13 +311,12 @@ public final class Preferences {
public final int alertDialogTheme;
public final boolean light;
Theme(@StyleRes int theme, int mainTheme) {
this(theme, mainTheme, R.style.Cpp_Theme_Wizard, R.style.Cpp_Theme_Material_Dialog, R.style.Cpp_Theme_Material_Dialog_Alert);
Theme(@StyleRes int theme) {
this(theme, R.style.Cpp_Theme_Wizard, R.style.Cpp_Theme_Material_Dialog, R.style.Cpp_Theme_Material_Dialog_Alert);
}
Theme(@StyleRes int theme, int mainTheme, @StyleRes int wizardTheme, @StyleRes int dialogTheme, @StyleRes int alertDialogTheme) {
Theme(@StyleRes int theme, @StyleRes int wizardTheme, @StyleRes int dialogTheme, @StyleRes int alertDialogTheme) {
this.theme = theme;
this.mainTheme = mainTheme;
this.wizardTheme = wizardTheme;
this.dialogTheme = dialogTheme;
this.alertDialogTheme = alertDialogTheme;
@ -327,9 +324,6 @@ public final class Preferences {
}
public int getThemeFor(@Nullable Context context) {
if (context instanceof CalculatorActivity) {
return mainTheme;
}
if (context instanceof WizardActivity) {
return wizardTheme;
}

View File

@ -22,20 +22,18 @@
package org.solovyev.android.calculator.about;
import android.os.Bundle;
import org.solovyev.android.calculator.BaseActivity;
import org.solovyev.android.calculator.FragmentTab;
import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.view.Tabs;
import javax.annotation.Nullable;
import javax.annotation.Nonnull;
public class AboutActivity extends BaseActivity {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getUi().addTab(this, FragmentTab.about, null, R.id.main);
getUi().addTab(this, FragmentTab.release_notes, null, R.id.main);
protected void populateTabs(@Nonnull Tabs tabs) {
super.populateTabs(tabs);
tabs.addTab(FragmentTab.about);
tabs.addTab(FragmentTab.release_notes);
}
}

View File

@ -22,16 +22,6 @@
package org.solovyev.android.calculator.floating;
import static android.view.HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING;
import static android.view.HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING;
import static android.view.HapticFeedbackConstants.KEYBOARD_TAP;
import static android.view.HapticFeedbackConstants.LONG_PRESS;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
import static org.solovyev.android.calculator.App.cast;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
@ -43,23 +33,10 @@ import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.*;
import android.widget.ImageView;
import android.widget.TextView;
import org.solovyev.android.calculator.AppModule;
import org.solovyev.android.calculator.BaseUi;
import org.solovyev.android.calculator.DisplayState;
import org.solovyev.android.calculator.DisplayView;
import org.solovyev.android.calculator.Editor;
import org.solovyev.android.calculator.EditorState;
import org.solovyev.android.calculator.EditorView;
import org.solovyev.android.calculator.Keyboard;
import org.solovyev.android.calculator.Preferences;
import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.*;
import org.solovyev.android.calculator.buttons.CppButton;
import org.solovyev.android.calculator.keyboard.BaseKeyboardUi;
import org.solovyev.android.views.Adjuster;
@ -68,6 +45,10 @@ import javax.annotation.Nonnull;
import javax.inject.Inject;
import javax.inject.Named;
import static android.view.HapticFeedbackConstants.*;
import static android.view.WindowManager.LayoutParams.*;
import static org.solovyev.android.calculator.App.cast;
public class FloatingCalculatorView {
private static class MyTouchListener implements View.OnTouchListener {
@ -376,7 +357,7 @@ public class FloatingCalculatorView {
BaseKeyboardUi.adjustButton(button);
}
if (button instanceof TextView) {
BaseUi.setFont((TextView) button, typeface);
ActivityUi.setFont((TextView) button, typeface);
}
}

View File

@ -27,31 +27,18 @@ import org.solovyev.android.calculator.BaseActivity;
import org.solovyev.android.calculator.FragmentTab;
import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.operators.OperatorCategory;
import org.solovyev.android.calculator.view.Tabs;
import javax.annotation.Nullable;
import javax.annotation.Nonnull;
public class FunctionsActivity extends BaseActivity {
public static final String EXTRA_FUNCTION = "function";
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
for (FunctionCategory category : FunctionCategory.values()) {
addTab(category, FragmentTab.functions);
}
for (OperatorCategory category : OperatorCategory.values()) {
final String title;
if (category == OperatorCategory.common || category == OperatorCategory.other) {
title = getString(R.string.c_operators) + ": " + getString(category.title());
} else {
title = getString(category.title());
}
addTab(category, FragmentTab.operators, title);
}
if (savedInstanceState == null) {
final Bundle extras = getIntent().getExtras();
final CppFunction function = extras != null ? (CppFunction) extras.getParcelable(EXTRA_FUNCTION) : null;
@ -60,4 +47,23 @@ public class FunctionsActivity extends BaseActivity {
}
}
}
@Override
protected void populateTabs(@Nonnull Tabs tabs) {
super.populateTabs(tabs);
for (FunctionCategory category : FunctionCategory.values()) {
tabs.addTab(category, FragmentTab.functions);
}
for (OperatorCategory category : OperatorCategory.values()) {
final String title;
if (category == OperatorCategory.common || category == OperatorCategory.other) {
title = getString(R.string.c_operators) + ": " + getString(category.title());
} else {
title = getString(category.title());
}
tabs.addTab(category, FragmentTab.operators, title);
}
}
}

View File

@ -25,8 +25,9 @@ package org.solovyev.android.calculator.history;
import android.os.Bundle;
import org.solovyev.android.calculator.BaseActivity;
import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.view.Tabs;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import static org.solovyev.android.calculator.FragmentTab.history;
@ -35,10 +36,9 @@ import static org.solovyev.android.calculator.FragmentTab.saved_history;
public class HistoryActivity extends BaseActivity {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ui.addTab(this, history, null, R.id.main);
ui.addTab(this, saved_history, null, R.id.main);
protected void populateTabs(@Nonnull Tabs tabs) {
super.populateTabs(tabs);
tabs.addTab(history);
tabs.addTab(saved_history);
}
}

View File

@ -108,7 +108,7 @@ public abstract class BaseKeyboardUi implements SharedPreferences.OnSharedPrefer
button.setVibrateOnDrag(keyboard.isVibrateOnKeypress());
prepareButton((View) button);
button.setOnDragListener(listener);
BaseUi.setFont(button, typeface);
ActivityUi.setFont(button, typeface);
button.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
Adjuster.adjustText(button, TEXT_SCALE);
}

View File

@ -25,17 +25,15 @@ package org.solovyev.android.calculator.matrix;
import android.os.Bundle;
import org.solovyev.android.calculator.BaseActivity;
import org.solovyev.android.calculator.FragmentTab;
import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.view.Tabs;
import static android.support.v7.app.ActionBar.NAVIGATION_MODE_STANDARD;
import javax.annotation.Nonnull;
public class CalculatorMatrixActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().setNavigationMode(NAVIGATION_MODE_STANDARD);
getUi().setFragment(this, FragmentTab.matrix_edit, null, R.id.main);
protected void populateTabs(@Nonnull Tabs tabs) {
super.populateTabs(tabs);
tabs.addTab(FragmentTab.matrix_edit);
}
}

View File

@ -22,20 +22,19 @@
package org.solovyev.android.calculator.operators;
import android.os.Bundle;
import org.solovyev.android.calculator.BaseActivity;
import org.solovyev.android.calculator.FragmentTab;
import org.solovyev.android.calculator.view.Tabs;
import javax.annotation.Nullable;
import javax.annotation.Nonnull;
public class OperatorsActivity extends BaseActivity {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
protected void populateTabs(@Nonnull Tabs tabs) {
super.populateTabs(tabs);
for (OperatorCategory category : OperatorCategory.values()) {
addTab(category, FragmentTab.operators);
tabs.addTab(category, FragmentTab.operators);
}
}
}

View File

@ -44,10 +44,6 @@ public class PreferencesActivity extends BaseActivity implements SharedPreferenc
@Inject
Products products;
public PreferencesActivity() {
super(R.layout.main_empty);
}
@Nonnull
static SparseArray<PrefDef> getPreferences() {
return preferences;
@ -90,8 +86,6 @@ public class PreferencesActivity extends BaseActivity implements SharedPreferenc
.commit();
}
getSupportActionBar().setNavigationMode(NAVIGATION_MODE_STANDARD);
checkout = Checkout.forActivity(this, billing, products);
checkout.start();
}

View File

@ -25,7 +25,9 @@ package org.solovyev.android.calculator.variables;
import android.os.Bundle;
import org.solovyev.android.calculator.BaseActivity;
import org.solovyev.android.calculator.FragmentTab;
import org.solovyev.android.calculator.view.Tabs;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class VariablesActivity extends BaseActivity {
@ -36,10 +38,6 @@ public class VariablesActivity extends BaseActivity {
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
for (VariableCategory category : VariableCategory.values()) {
addTab(category, FragmentTab.variables);
}
if (savedInstanceState == null) {
final Bundle extras = getIntent().getExtras();
final CppVariable variable = extras != null ? (CppVariable) extras.getParcelable(EXTRA_VARIABLE) : null;
@ -48,4 +46,12 @@ public class VariablesActivity extends BaseActivity {
}
}
}
@Override
protected void populateTabs(@Nonnull Tabs tabs) {
super.populateTabs(tabs);
for (VariableCategory category : VariableCategory.values()) {
tabs.addTab(category, FragmentTab.variables);
}
}
}

View File

@ -0,0 +1,139 @@
package org.solovyev.android.calculator.view;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.ViewTreeObserver;
import butterknife.Bind;
import butterknife.ButterKnife;
import org.solovyev.android.calculator.FragmentTab;
import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.entities.BaseEntitiesFragment;
import org.solovyev.android.calculator.entities.Category;
import org.solovyev.android.views.Adjuster;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.List;
public class Tabs {
@Nonnull
private final AppCompatActivity activity;
@Nonnull
private final TabFragments adapter;
@Nullable
@Bind(R.id.tabs)
TabLayout tabLayout;
@Nullable
@Bind(R.id.viewpager)
ViewPager viewpager;
public Tabs(@Nonnull AppCompatActivity activity) {
this.activity = activity;
this.adapter = new TabFragments(activity.getSupportFragmentManager());
}
public void onCreate() {
ButterKnife.bind(this, activity);
if (tabLayout == null || viewpager == null) {
return;
}
viewpager.setAdapter(adapter);
tabLayout.setupWithViewPager(viewpager);
if (ViewCompat.isLaidOut(tabLayout)) {
tabLayout.setupWithViewPager(viewpager);
} else {
final ViewTreeObserver treeObserver = Adjuster.getTreeObserver(tabLayout);
if (treeObserver != null) {
treeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
final ViewTreeObserver anotherTreeObserver = Adjuster.getTreeObserver(tabLayout);
if(anotherTreeObserver != null) {
//noinspection deprecation
anotherTreeObserver.removeGlobalOnLayoutListener(this);
}
tabLayout.setupWithViewPager(viewpager);
}
});
}
}
}
public void addTab(@Nonnull Category category, @Nonnull FragmentTab tab) {
addTab(category, tab, activity.getString(category.title()));
}
public final void addTab(@Nonnull Category category, @Nonnull FragmentTab tab, @Nonnull CharSequence title) {
final Bundle arguments = new Bundle(1);
arguments.putString(BaseEntitiesFragment.ARG_CATEGORY, category.name());
addTab(tab.type, arguments, title);
}
public void addTab(@Nonnull FragmentTab tab) {
addTab(tab.type, null, activity.getString(tab.title));
}
public void addTab(@Nonnull Class<? extends Fragment> fragmentClass, @Nullable Bundle fragmentArgs, @Nonnull CharSequence title) {
adapter.add(new TabFragment(fragmentClass, fragmentArgs, title));
}
private final class TabFragments extends FragmentPagerAdapter {
@Nonnull
private final List<TabFragment> list = new ArrayList<>();
public TabFragments(@Nonnull FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
return list.get(position).makeFragment();
}
public void add(@Nonnull TabFragment tabFragment) {
list.add(tabFragment);
notifyDataSetChanged();
}
@Override
public CharSequence getPageTitle(int position) {
return list.get(position).title;
}
@Override
public int getCount() {
return list.size();
}
}
private final class TabFragment {
@Nonnull
final Class<? extends Fragment> fragmentClass;
@Nullable
final Bundle fragmentArgs;
@Nonnull
final CharSequence title;
public TabFragment(@Nonnull Class<? extends Fragment> fragmentClass, @Nullable Bundle fragmentArgs, @Nonnull CharSequence title) {
this.fragmentClass = fragmentClass;
this.fragmentArgs = fragmentArgs;
this.title = title;
}
@Nonnull
public Fragment makeFragment() {
return Fragment.instantiate(activity, fragmentClass.getName(), fragmentArgs);
}
}
}

View File

@ -22,16 +22,13 @@
package org.solovyev.android.calculator.wizard;
import static org.solovyev.android.calculator.App.cast;
import android.graphics.PointF;
import android.graphics.Typeface;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
import org.solovyev.android.calculator.BaseUi;
import org.solovyev.android.calculator.ActivityUi;
import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.keyboard.BaseKeyboardUi;
import org.solovyev.android.views.Adjuster;
@ -40,11 +37,12 @@ import org.solovyev.android.views.dragbutton.DragButton;
import org.solovyev.android.views.dragbutton.DragDirection;
import org.solovyev.android.views.dragbutton.SimpleDragListener;
import java.util.Arrays;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject;
import java.util.Arrays;
import static org.solovyev.android.calculator.App.cast;
public class DragButtonWizardStep extends WizardFragment {
@ -77,7 +75,7 @@ public class DragButtonWizardStep extends WizardFragment {
dragButton.setOnClickListener(this);
dragButton.setOnDragListener(
new SimpleDragListener(new DragButtonProcessor(), getActivity()));
BaseUi.setFont(dragButton, typeface);
ActivityUi.setFont(dragButton, typeface);
Adjuster.adjustText(dragButton, BaseKeyboardUi.TEXT_SCALE);
actionTextView = (TextView) root.findViewById(R.id.wizard_dragbutton_action_textview);
if (savedInstanceState != null) {

View File

@ -1,7 +1,5 @@
package org.solovyev.android.views;
import static android.graphics.Matrix.MSCALE_Y;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@ -11,6 +9,8 @@ import android.view.ViewTreeObserver;
import android.widget.ImageView;
import android.widget.TextView;
import static android.graphics.Matrix.MSCALE_Y;
public class Adjuster {
private static final float[] MATRIX = new float[9];
@ -24,7 +24,7 @@ public class Adjuster {
}
@Nullable
private static ViewTreeObserver getTreeObserver(@NonNull View view) {
public static ViewTreeObserver getTreeObserver(@NonNull View view) {
final ViewTreeObserver treeObserver = view.getViewTreeObserver();
if (treeObserver == null) {
return null;

View File

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright 2013 serso aka se.solovyev
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
~
~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~ Contact details
~
~ Email: se.solovyev@gmail.com
~ Site: http://se.solovyev.org
-->
<android.support.design.widget.CoordinatorLayout
android:id="@+id/main"
style="@style/CppMain"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|enterAlways" />
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/main"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:my="http://schemas.android.com/apk/res-auto"
style="@style/MaterialActivity"

View File

@ -1,31 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright 2013 serso aka se.solovyev
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
~
~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~ Contact details
~
~ Email: se.solovyev@gmail.com
~ Site: http://se.solovyev.org
-->
<LinearLayout
xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/main"
style="@style/CppMain"
a:orientation="vertical">
</LinearLayout>

View File

@ -22,20 +22,13 @@
<resources>
<style name="Cpp.Theme.NoActionBar" parent="@style/Cpp.Theme">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="Cpp.Theme" parent="@style/Theme.AppCompat">
<style name="Cpp.Theme" parent="@style/Theme.AppCompat.NoActionBar">
<item name="colorPrimary">@color/cpp_metro_button</item>
<item name="colorPrimaryDark">@color/cpp_metro_button_dark</item>
<item name="colorAccent">@color/cpp_material_accent</item>
<item name="android:windowBackground">@color/cpp_main_bg</item>
<item name="actionBarStyle">@style/CppActionBar</item>
<item name="cpp_main_bg">@color/cpp_main_bg</item>
<item name="cpp_pane_bg">@drawable/pane</item>
<item name="cpp_fab_bg">@color/grey_900</item>
@ -86,15 +79,13 @@
<item name="android:listDivider">@drawable/divider_dark</item>
</style>
<style name="Cpp.Theme.Light" parent="@style/Theme.AppCompat.Light.DarkActionBar">
<style name="Cpp.Theme.Light" parent="@style/Theme.AppCompat.Light.NoActionBar">
<item name="android:windowBackground">@color/cpp_main_bg_light</item>
<item name="colorPrimary">@color/cpp_material_light</item>
<item name="colorPrimaryDark">@color/cpp_material_light</item>
<item name="colorAccent">@color/cpp_material_light</item>
<item name="actionBarStyle">@style/CppActionBar.Light</item>
<item name="cpp_main_bg">@color/cpp_main_bg_light</item>
<item name="cpp_pane_bg">@drawable/pane_light</item>
<item name="cpp_fab_bg">@color/cpp_material_light</item>

View File

@ -59,11 +59,6 @@
<item name="android:textSize">@dimen/cpp_widget_keyboard_button_text_size</item>
</style>
<style name="Cpp.Theme.Material.NoActionBar" parent="Cpp.Theme.Material">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="Cpp.Theme.Material" parent="Cpp.Theme">
<item name="cpp_button_style_digit">@style/CppKeyboardButton.Material.Digit</item>
<item name="cpp_button_style_control">@style/CppKeyboardButton.Material.Digit</item>

View File

@ -59,11 +59,6 @@
<item name="android:textSize">@dimen/cpp_widget_keyboard_button_text_size</item>
</style>
<style name="Cpp.Theme.Material.Light.NoActionBar" parent="Cpp.Theme.Material.Light">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="Cpp.Theme.Material.Light" parent="Cpp.Theme.Light">
<item name="cpp_button_style_digit">@style/CppKeyboardButton.Material.Light.Digit</item>
<item name="cpp_button_style_control">@style/CppKeyboardButton.Material.Light.Digit</item>

View File

@ -65,11 +65,6 @@
<item name="android:padding">@dimen/cpp_keyboard_simple_image_button_padding</item>
</style>
<style name="Cpp.Theme.Metro.Blue.NoActionBar" parent="Cpp.Theme.Metro.Blue">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="Cpp.Theme.Metro.Blue" parent="Cpp.Theme">
<item name="cpp_button_style_digit">@style/CppKeyboardButton.Metro.Blue.Digit</item>
<item name="cpp_button_style_control">@style/CppKeyboardButton.Metro.Blue.Control</item>

View File

@ -26,11 +26,6 @@
<item name="android:background">@drawable/metro_button_green</item>
</style>
<style name="Cpp.Theme.Metro.Green.NoActionBar" parent="Cpp.Theme.Metro.Green">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="Cpp.Theme.Metro.Green" parent="Cpp.Theme.Metro.Blue">
<item name="cpp_button_style_operation">@style/metro_green_operation_button_style</item>
</style>

View File

@ -26,11 +26,6 @@
<item name="android:background">@drawable/metro_button_purple</item>
</style>
<style name="Cpp.Theme.Metro.Purple.NoActionBar" parent="Cpp.Theme.Metro.Purple">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="Cpp.Theme.Metro.Purple" parent="Cpp.Theme.Metro.Blue">
<item name="cpp_button_style_operation">@style/metro_purple_operation_button_style</item>
</style>

View File

@ -36,11 +36,6 @@
<style name="CppKeyboardButton.Blue.Control.Image" parent="CppKeyboardButton.Blue.Control"/>
<style name="Cpp.Theme.Blue.NoActionBar" parent="Cpp.Theme.Blue">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="Cpp.Theme.Blue" parent="Cpp.Theme">
<item name="cpp_button_style_digit">@style/CppKeyboardButton.Blue.Digit</item>
<item name="cpp_button_style_control">@style/CppKeyboardButton.Blue.Control</item>

View File

@ -36,11 +36,6 @@
<style name="CppKeyboardButton.Gray.Control.Image" parent="CppKeyboardButton.Gray.Control"/>
<style name="Cpp.Theme.Gray.NoActionBar" parent="Cpp.Theme.Gray">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="Cpp.Theme.Gray" parent="Cpp.Theme">
<item name="cpp_button_style_digit">@style/CppKeyboardButton.Gray.Digit</item>
<item name="cpp_button_style_control">@style/CppKeyboardButton.Gray.Control</item>

View File

@ -36,11 +36,6 @@
<style name="CppKeyboardButton.Violet.Control.Image" parent="CppKeyboardButton.Violet.Control"/>
<style name="Cpp.Theme.Violet.NoActionBar" parent="Cpp.Theme.Violet">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="Cpp.Theme.Violet" parent="Cpp.Theme">
<item name="cpp_button_style_digit">@style/CppKeyboardButton.Violet.Digit</item>
<item name="cpp_button_style_control">@style/CppKeyboardButton.Violet.Control</item>