TabLayout + NavigationDrawer
This commit is contained in:
parent
96fb4323f8
commit
263275659a
14 changed files with 278 additions and 637 deletions
|
@ -32,11 +32,10 @@
|
|||
android:icon="${appIcon}"
|
||||
android:label="@string/app_name"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
android:theme="@style/AppTheme.NoActionBar">
|
||||
<activity android:name=".MainActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
@ -171,7 +170,10 @@
|
|||
android:name=".setupwizard.SetupWizardActivity"
|
||||
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||
android:theme="@style/AppTheme.SetupWizard"
|
||||
android:label="@string/title_activity_setup_wizard"></activity>
|
||||
android:label="@string/title_activity_setup_wizard" />
|
||||
|
||||
<activity android:name=".SingleFragmentActivity"
|
||||
android:theme="@style/AppTheme" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
|
@ -6,20 +6,30 @@ import android.content.DialogInterface;
|
|||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.PersistableBundle;
|
||||
import android.os.PowerManager;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.NavigationView;
|
||||
import android.support.design.widget.TabLayout;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.support.v4.widget.DrawerLayout;
|
||||
import android.support.v7.app.ActionBarDrawerToggle;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.PopupMenu;
|
||||
import android.text.SpannableString;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.text.util.Linkify;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SubMenu;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
@ -34,10 +44,14 @@ import com.squareup.otto.Subscribe;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.events.EventAppExit;
|
||||
import info.nightscout.androidaps.events.EventFeatureRunning;
|
||||
import info.nightscout.androidaps.events.EventPreferenceChange;
|
||||
import info.nightscout.androidaps.events.EventRefreshGui;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
|
@ -45,7 +59,6 @@ import info.nightscout.androidaps.plugins.Food.FoodPlugin;
|
|||
import info.nightscout.androidaps.plugins.Overview.events.EventSetWakeLock;
|
||||
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||
import info.nightscout.androidaps.setupwizard.SetupWizardActivity;
|
||||
import info.nightscout.androidaps.tabs.SlidingTabLayout;
|
||||
import info.nightscout.androidaps.tabs.TabPageAdapter;
|
||||
import info.nightscout.utils.AndroidPermission;
|
||||
import info.nightscout.utils.ImportExportPrefs;
|
||||
|
@ -55,13 +68,13 @@ import info.nightscout.utils.OKDialog;
|
|||
import info.nightscout.utils.PasswordProtection;
|
||||
import info.nightscout.utils.SP;
|
||||
|
||||
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
private static Logger log = LoggerFactory.getLogger(MainActivity.class);
|
||||
|
||||
ImageButton menuButton;
|
||||
|
||||
protected PowerManager.WakeLock mWakeLock;
|
||||
|
||||
private ActionBarDrawerToggle actionBarDrawerToggle;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
@ -71,9 +84,17 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
|
||||
Iconify.with(new FontAwesomeModule());
|
||||
LocaleHelper.onCreate(this, "en");
|
||||
|
||||
setContentView(R.layout.activity_main);
|
||||
menuButton = (ImageButton) findViewById(R.id.overview_menuButton);
|
||||
menuButton.setOnClickListener(this);
|
||||
setSupportActionBar(findViewById(R.id.toolbar));
|
||||
getSupportActionBar().setDisplayShowTitleEnabled(false);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
getSupportActionBar().setHomeButtonEnabled(true);
|
||||
|
||||
DrawerLayout drawerLayout = findViewById(R.id.drawer_layout);
|
||||
actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.open_navigation, R.string.close_navigation);
|
||||
drawerLayout.addDrawerListener(actionBarDrawerToggle);
|
||||
actionBarDrawerToggle.syncState();
|
||||
|
||||
onStatusEvent(new EventSetWakeLock(SP.getBoolean("lockscreen", false)));
|
||||
|
||||
|
@ -83,6 +104,12 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
setUpTabs(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPostCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
|
||||
super.onPostCreate(savedInstanceState, persistentState);
|
||||
actionBarDrawerToggle.syncState();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
@ -151,13 +178,30 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
|
||||
private void setUpTabs(boolean switchToLast) {
|
||||
TabPageAdapter pageAdapter = new TabPageAdapter(getSupportFragmentManager(), this);
|
||||
NavigationView navigationView = findViewById(R.id.navigation_view);
|
||||
navigationView.setNavigationItemSelectedListener(menuItem -> {
|
||||
Log.d("asdasdasdsada", "ASFASFASFSFASF");
|
||||
return true;
|
||||
});
|
||||
Menu menu = navigationView.getMenu();
|
||||
menu.clear();
|
||||
for (PluginBase p : MainApp.getPluginsList()) {
|
||||
pageAdapter.registerNewFragment(p);
|
||||
if (p.hasFragment() && !p.isFragmentVisible() && p.isEnabled(p.pluginDescription.getType())) {
|
||||
MenuItem menuItem = menu.add(p.getName());
|
||||
menuItem.setCheckable(true);
|
||||
menuItem.setOnMenuItemClickListener(item -> {
|
||||
Intent intent = new Intent(this, SingleFragmentActivity.class);
|
||||
intent.putExtra("plugin", MainApp.getPluginsList().indexOf(p));
|
||||
startActivity(intent);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
ViewPager mPager = (ViewPager) findViewById(R.id.pager);
|
||||
}
|
||||
ViewPager mPager = findViewById(R.id.pager);
|
||||
mPager.setAdapter(pageAdapter);
|
||||
SlidingTabLayout mTabs = (SlidingTabLayout) findViewById(R.id.tabs);
|
||||
mTabs.setViewPager(mPager);
|
||||
TabLayout tabLayout = findViewById(R.id.tabs);
|
||||
tabLayout.setupWithViewPager(mPager, true);
|
||||
if (switchToLast)
|
||||
mPager.setCurrentItem(pageAdapter.getCount() - 1, false);
|
||||
}
|
||||
|
@ -257,65 +301,56 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onClick(final View v) {
|
||||
final Activity activity = this;
|
||||
switch (v.getId()) {
|
||||
case R.id.overview_menuButton:
|
||||
PopupMenu popup = new PopupMenu(v.getContext(), v);
|
||||
MenuInflater inflater = popup.getMenuInflater();
|
||||
inflater.inflate(R.menu.menu_main, popup.getMenu());
|
||||
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_main, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int id = item.getItemId();
|
||||
switch (id) {
|
||||
case R.id.nav_preferences:
|
||||
PasswordProtection.QueryPassword(v.getContext(), R.string.settings_password, "settings_password", new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Intent i = new Intent(v.getContext(), PreferencesActivity.class);
|
||||
PasswordProtection.QueryPassword(this, R.string.settings_password, "settings_password", () -> {
|
||||
Intent i = new Intent(this, PreferencesActivity.class);
|
||||
i.putExtra("id", -1);
|
||||
startActivity(i);
|
||||
}
|
||||
}, null);
|
||||
break;
|
||||
return true;
|
||||
case R.id.nav_historybrowser:
|
||||
startActivity(new Intent(v.getContext(), HistoryBrowseActivity.class));
|
||||
break;
|
||||
startActivity(new Intent(this, HistoryBrowseActivity.class));
|
||||
return true;
|
||||
case R.id.nav_setupwizard:
|
||||
startActivity(new Intent(v.getContext(), SetupWizardActivity.class));
|
||||
break;
|
||||
startActivity(new Intent(this, SetupWizardActivity.class));
|
||||
return true;
|
||||
case R.id.nav_resetdb:
|
||||
new AlertDialog.Builder(v.getContext())
|
||||
new AlertDialog.Builder(this)
|
||||
.setTitle(R.string.nav_resetdb)
|
||||
.setMessage(R.string.reset_db_confirm)
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
|
||||
MainApp.getDbHelper().resetDatabases();
|
||||
// should be handled by Plugin-Interface and
|
||||
// additional service interface and plugin registry
|
||||
FoodPlugin.getPlugin().getService().resetFood();
|
||||
TreatmentsPlugin.getPlugin().getService().resetTreatments();
|
||||
}
|
||||
})
|
||||
.create()
|
||||
.show();
|
||||
break;
|
||||
return true;
|
||||
case R.id.nav_export:
|
||||
ImportExportPrefs.verifyStoragePermissions(activity);
|
||||
ImportExportPrefs.exportSharedPreferences(activity);
|
||||
break;
|
||||
ImportExportPrefs.verifyStoragePermissions(this);
|
||||
ImportExportPrefs.exportSharedPreferences(this);
|
||||
return true;
|
||||
case R.id.nav_import:
|
||||
ImportExportPrefs.verifyStoragePermissions(activity);
|
||||
ImportExportPrefs.importSharedPreferences(activity);
|
||||
break;
|
||||
ImportExportPrefs.verifyStoragePermissions(this);
|
||||
ImportExportPrefs.importSharedPreferences(this);
|
||||
return true;
|
||||
case R.id.nav_show_logcat:
|
||||
LogDialog.showLogcat(v.getContext());
|
||||
break;
|
||||
LogDialog.showLogcat(this);
|
||||
return true;
|
||||
case R.id.nav_about:
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle(MainApp.gs(R.string.app_name) + " " + BuildConfig.VERSION);
|
||||
if (Config.NSCLIENT || Config.G5UPLOADER)
|
||||
builder.setIcon(R.mipmap.yellowowl);
|
||||
|
@ -334,7 +369,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
AlertDialog alertDialog = builder.create();
|
||||
alertDialog.show();
|
||||
((TextView) alertDialog.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());
|
||||
break;
|
||||
return true;
|
||||
case R.id.nav_exit:
|
||||
log.debug("Exiting");
|
||||
MainApp.instance().stopKeepAliveService();
|
||||
|
@ -343,13 +378,8 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
|
|||
finish();
|
||||
System.runFinalization();
|
||||
System.exit(0);
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
popup.show();
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
return actionBarDrawerToggle.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
package info.nightscout.androidaps;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
|
||||
public class SingleFragmentActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_single_fragment);
|
||||
|
||||
PluginBase plugin = MainApp.getPluginsList().get(getIntent().getIntExtra("plugin", -1));
|
||||
setTitle(plugin.getName());
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
getSupportActionBar().setDisplayShowHomeEnabled(true);
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout,
|
||||
Fragment.instantiate(this, plugin.pluginDescription.getFragmentClass())).commit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) finish();
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -87,9 +87,9 @@ public class ConfigBuilderPlugin extends PluginBase {
|
|||
super(new PluginDescription()
|
||||
.mainType(PluginType.GENERAL)
|
||||
.fragmentClass(ConfigBuilderFragment.class.getName())
|
||||
.showInList(false)
|
||||
.showInList(true)
|
||||
.alwaysEnabled(true)
|
||||
.alwayVisible(true)
|
||||
.alwayVisible(false)
|
||||
.pluginName(R.string.configbuilder)
|
||||
.shortName(R.string.configbuilder_shortname)
|
||||
);
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
package info.nightscout.androidaps.tabs;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
public class NonConsumingToolbar extends Toolbar {
|
||||
public NonConsumingToolbar(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public NonConsumingToolbar(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public NonConsumingToolbar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent ev) {
|
||||
if (ev.getAction() == MotionEvent.ACTION_DOWN || ev.getAction() == MotionEvent.ACTION_POINTER_DOWN)
|
||||
return performClick();
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,322 +0,0 @@
|
|||
package info.nightscout.androidaps.tabs;/*
|
||||
* Copyright 2014 Google Inc. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Typeface;
|
||||
import android.support.v4.view.PagerAdapter;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.SparseArray;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.HorizontalScrollView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import info.nightscout.androidaps.R;
|
||||
|
||||
/**
|
||||
* To be used with ViewPager to provide a tab indicator component which give constant feedback as to
|
||||
* the user's scroll progress.
|
||||
* <p>
|
||||
* To use the component, simply add it to your view hierarchy. Then in your
|
||||
* {@link android.app.Activity} or {@link android.support.v4.app.Fragment} call
|
||||
* {@link #setViewPager(ViewPager)} providing it the ViewPager this layout is being used for.
|
||||
* <p>
|
||||
* The colors can be customized in two ways. The first and simplest is to provide an array of colors
|
||||
* via {@link #setSelectedIndicatorColors(int...)}. The
|
||||
* alternative is via the {@link TabColorizer} interface which provides you complete control over
|
||||
* which color is used for any individual position.
|
||||
* <p>
|
||||
* The views used as tabs can be customized by calling {@link #setCustomTabView(int, int)},
|
||||
* providing the layout ID of your custom layout.
|
||||
*/
|
||||
public class SlidingTabLayout extends HorizontalScrollView {
|
||||
/**
|
||||
* Allows complete control over the colors drawn in the tab layout. Set with
|
||||
* {@link #setCustomTabColorizer(TabColorizer)}.
|
||||
*/
|
||||
public interface TabColorizer {
|
||||
|
||||
/**
|
||||
* @return return the color of the indicator used when {@code position} is selected.
|
||||
*/
|
||||
int getIndicatorColor(int position);
|
||||
|
||||
}
|
||||
|
||||
private static final int TITLE_OFFSET_DIPS = 24;
|
||||
private static final int TAB_VIEW_PADDING_DIPS = 9;
|
||||
private static final int TAB_VIEW_TEXT_SIZE_SP = 12;
|
||||
|
||||
private int mTitleOffset;
|
||||
|
||||
private int mTabViewLayoutId;
|
||||
private int mTabViewTextViewId;
|
||||
private boolean mDistributeEvenly;
|
||||
|
||||
private ViewPager mViewPager;
|
||||
private SparseArray<String> mContentDescriptions = new SparseArray<String>();
|
||||
private ViewPager.OnPageChangeListener mViewPagerPageChangeListener;
|
||||
|
||||
private final SlidingTabStrip mTabStrip;
|
||||
|
||||
public SlidingTabLayout(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public SlidingTabLayout(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public SlidingTabLayout(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
|
||||
// Disable the Scroll Bar
|
||||
setHorizontalScrollBarEnabled(false);
|
||||
// Make sure that the Tab Strips fills this View
|
||||
setFillViewport(true);
|
||||
|
||||
mTitleOffset = (int) (TITLE_OFFSET_DIPS * getResources().getDisplayMetrics().density);
|
||||
|
||||
mTabStrip = new SlidingTabStrip(context);
|
||||
addView(mTabStrip, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
|
||||
setBackgroundColor(context.getResources().getColor(R.color.tabBgColor));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the custom {@link TabColorizer} to be used.
|
||||
*
|
||||
* If you only require simple custmisation then you can use
|
||||
* {@link #setSelectedIndicatorColors(int...)} to achieve
|
||||
* similar effects.
|
||||
*/
|
||||
public void setCustomTabColorizer(TabColorizer tabColorizer) {
|
||||
mTabStrip.setCustomTabColorizer(tabColorizer);
|
||||
}
|
||||
|
||||
public void setDistributeEvenly(boolean distributeEvenly) {
|
||||
mDistributeEvenly = distributeEvenly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the colors to be used for indicating the selected tab. These colors are treated as a
|
||||
* circular array. Providing one color will mean that all tabs are indicated with the same color.
|
||||
*/
|
||||
public void setSelectedIndicatorColors(int... colors) {
|
||||
mTabStrip.setSelectedIndicatorColors(colors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link ViewPager.OnPageChangeListener}. When using {@link SlidingTabLayout} you are
|
||||
* required to set any {@link ViewPager.OnPageChangeListener} through this method. This is so
|
||||
* that the layout can update it's scroll position correctly.
|
||||
*
|
||||
* @see ViewPager#setOnPageChangeListener(ViewPager.OnPageChangeListener)
|
||||
*/
|
||||
public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
|
||||
mViewPagerPageChangeListener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the custom layout to be inflated for the tab views.
|
||||
*
|
||||
* @param layoutResId Layout id to be inflated
|
||||
* @param textViewId id of the {@link TextView} in the inflated view
|
||||
*/
|
||||
public void setCustomTabView(int layoutResId, int textViewId) {
|
||||
mTabViewLayoutId = layoutResId;
|
||||
mTabViewTextViewId = textViewId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the associated view pager. Note that the assumption here is that the pager content
|
||||
* (number of tabs and tab titles) does not change after this call has been made.
|
||||
*/
|
||||
public void setViewPager(ViewPager viewPager) {
|
||||
mTabStrip.removeAllViews();
|
||||
|
||||
mViewPager = viewPager;
|
||||
if (viewPager != null) {
|
||||
viewPager.setOnPageChangeListener(new InternalViewPagerListener());
|
||||
populateTabStrip();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a default view to be used for tabs. This is called if a custom tab view is not set via
|
||||
* {@link #setCustomTabView(int, int)}.
|
||||
*/
|
||||
protected TextView createDefaultTabView(Context context) {
|
||||
TextView textView = new TextView(context);
|
||||
textView.setGravity(Gravity.CENTER);
|
||||
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP);
|
||||
textView.setTypeface(Typeface.DEFAULT_BOLD);
|
||||
textView.setLayoutParams(new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
|
||||
TypedValue outValue = new TypedValue();
|
||||
getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground,
|
||||
outValue, true);
|
||||
textView.setBackgroundResource(outValue.resourceId);
|
||||
textView.setAllCaps(true);
|
||||
|
||||
int padding = (int) (TAB_VIEW_PADDING_DIPS * getResources().getDisplayMetrics().density);
|
||||
textView.setPadding(padding, padding, padding, padding);
|
||||
|
||||
return textView;
|
||||
}
|
||||
|
||||
private void populateTabStrip() {
|
||||
final PagerAdapter adapter = mViewPager.getAdapter();
|
||||
final View.OnClickListener tabClickListener = new TabClickListener();
|
||||
|
||||
for (int i = 0; i < adapter.getCount(); i++) {
|
||||
View tabView = null;
|
||||
TextView tabTitleView = null;
|
||||
|
||||
if (mTabViewLayoutId != 0) {
|
||||
// If there is a custom tab view layout id set, try and inflate it
|
||||
tabView = LayoutInflater.from(getContext()).inflate(mTabViewLayoutId, mTabStrip,
|
||||
false);
|
||||
tabTitleView = (TextView) tabView.findViewById(mTabViewTextViewId);
|
||||
}
|
||||
|
||||
if (tabView == null) {
|
||||
tabView = createDefaultTabView(getContext());
|
||||
}
|
||||
|
||||
if (tabTitleView == null && TextView.class.isInstance(tabView)) {
|
||||
tabTitleView = (TextView) tabView;
|
||||
}
|
||||
|
||||
if (mDistributeEvenly) {
|
||||
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) tabView.getLayoutParams();
|
||||
lp.width = 0;
|
||||
lp.weight = 1;
|
||||
}
|
||||
|
||||
tabTitleView.setText(adapter.getPageTitle(i));
|
||||
tabView.setOnClickListener(tabClickListener);
|
||||
String desc = mContentDescriptions.get(i, null);
|
||||
if (desc != null) {
|
||||
tabView.setContentDescription(desc);
|
||||
}
|
||||
|
||||
mTabStrip.addView(tabView);
|
||||
if (i == mViewPager.getCurrentItem()) {
|
||||
tabView.setSelected(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setContentDescription(int i, String desc) {
|
||||
mContentDescriptions.put(i, desc);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
|
||||
if (mViewPager != null) {
|
||||
scrollToTab(mViewPager.getCurrentItem(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
private void scrollToTab(int tabIndex, int positionOffset) {
|
||||
final int tabStripChildCount = mTabStrip.getChildCount();
|
||||
if (tabStripChildCount == 0 || tabIndex < 0 || tabIndex >= tabStripChildCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
View selectedChild = mTabStrip.getChildAt(tabIndex);
|
||||
if (selectedChild != null) {
|
||||
int targetScrollX = selectedChild.getLeft() + positionOffset;
|
||||
|
||||
if (tabIndex > 0 || positionOffset > 0) {
|
||||
// If we're not at the first child and are mid-scroll, make sure we obey the offset
|
||||
targetScrollX -= mTitleOffset;
|
||||
}
|
||||
|
||||
scrollTo(targetScrollX, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private class InternalViewPagerListener implements ViewPager.OnPageChangeListener {
|
||||
private int mScrollState;
|
||||
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
int tabStripChildCount = mTabStrip.getChildCount();
|
||||
if ((tabStripChildCount == 0) || (position < 0) || (position >= tabStripChildCount)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mTabStrip.onViewPagerPageChanged(position, positionOffset);
|
||||
|
||||
View selectedTitle = mTabStrip.getChildAt(position);
|
||||
int extraOffset = (selectedTitle != null)
|
||||
? (int) (positionOffset * selectedTitle.getWidth())
|
||||
: 0;
|
||||
scrollToTab(position, extraOffset);
|
||||
|
||||
if (mViewPagerPageChangeListener != null) {
|
||||
mViewPagerPageChangeListener.onPageScrolled(position, positionOffset,
|
||||
positionOffsetPixels);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int state) {
|
||||
mScrollState = state;
|
||||
|
||||
if (mViewPagerPageChangeListener != null) {
|
||||
mViewPagerPageChangeListener.onPageScrollStateChanged(state);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageSelected(int position) {
|
||||
if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
|
||||
mTabStrip.onViewPagerPageChanged(position, 0f);
|
||||
scrollToTab(position, 0);
|
||||
}
|
||||
for (int i = 0; i < mTabStrip.getChildCount(); i++) {
|
||||
mTabStrip.getChildAt(i).setSelected(position == i);
|
||||
}
|
||||
if (mViewPagerPageChangeListener != null) {
|
||||
mViewPagerPageChangeListener.onPageSelected(position);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class TabClickListener implements View.OnClickListener {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
for (int i = 0; i < mTabStrip.getChildCount(); i++) {
|
||||
if (v == mTabStrip.getChildAt(i)) {
|
||||
mViewPager.setCurrentItem(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,165 +0,0 @@
|
|||
package info.nightscout.androidaps.tabs;/*
|
||||
* Copyright 2014 Google Inc. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.TypedValue;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
|
||||
class SlidingTabStrip extends LinearLayout {
|
||||
|
||||
private static final int DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS = 0;
|
||||
private static final byte DEFAULT_BOTTOM_BORDER_COLOR_ALPHA = 0x26;
|
||||
private static final int SELECTED_INDICATOR_THICKNESS_DIPS = 3;
|
||||
|
||||
private final int mBottomBorderThickness;
|
||||
private final Paint mBottomBorderPaint;
|
||||
|
||||
private final int mSelectedIndicatorThickness;
|
||||
private final Paint mSelectedIndicatorPaint;
|
||||
|
||||
private int mSelectedPosition;
|
||||
private float mSelectionOffset;
|
||||
|
||||
private SlidingTabLayout.TabColorizer mCustomTabColorizer;
|
||||
private final SimpleTabColorizer mDefaultTabColorizer;
|
||||
|
||||
SlidingTabStrip(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
SlidingTabStrip(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setWillNotDraw(false);
|
||||
|
||||
final float density = getResources().getDisplayMetrics().density;
|
||||
|
||||
TypedValue outValue = new TypedValue();
|
||||
context.getTheme().resolveAttribute(android.R.attr.colorForeground, outValue, true);
|
||||
final int themeForegroundColor = outValue.data;
|
||||
|
||||
int defaultBottomBorderColor = setColorAlpha(themeForegroundColor,
|
||||
DEFAULT_BOTTOM_BORDER_COLOR_ALPHA);
|
||||
|
||||
mDefaultTabColorizer = new SimpleTabColorizer();
|
||||
mDefaultTabColorizer.setIndicatorColors(MainApp.gc(R.color.tabBgColorSelected));
|
||||
|
||||
mBottomBorderThickness = (int) (DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS * density);
|
||||
mBottomBorderPaint = new Paint();
|
||||
mBottomBorderPaint.setColor(defaultBottomBorderColor);
|
||||
|
||||
mSelectedIndicatorThickness = (int) (SELECTED_INDICATOR_THICKNESS_DIPS * density);
|
||||
mSelectedIndicatorPaint = new Paint();
|
||||
}
|
||||
|
||||
void setCustomTabColorizer(SlidingTabLayout.TabColorizer customTabColorizer) {
|
||||
mCustomTabColorizer = customTabColorizer;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void setSelectedIndicatorColors(int... colors) {
|
||||
// Make sure that the custom colorizer is removed
|
||||
mCustomTabColorizer = null;
|
||||
mDefaultTabColorizer.setIndicatorColors(colors);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void onViewPagerPageChanged(int position, float positionOffset) {
|
||||
mSelectedPosition = position;
|
||||
mSelectionOffset = positionOffset;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
final int height = getHeight();
|
||||
final int childCount = getChildCount();
|
||||
final SlidingTabLayout.TabColorizer tabColorizer = mCustomTabColorizer != null
|
||||
? mCustomTabColorizer
|
||||
: mDefaultTabColorizer;
|
||||
|
||||
// Thick colored underline below the current selection
|
||||
if (childCount > 0) {
|
||||
View selectedTitle = getChildAt(mSelectedPosition);
|
||||
int left = selectedTitle.getLeft();
|
||||
int right = selectedTitle.getRight();
|
||||
int color = tabColorizer.getIndicatorColor(mSelectedPosition);
|
||||
|
||||
if (mSelectionOffset > 0f && mSelectedPosition < (getChildCount() - 1)) {
|
||||
int nextColor = tabColorizer.getIndicatorColor(mSelectedPosition + 1);
|
||||
if (color != nextColor) {
|
||||
color = blendColors(nextColor, color, mSelectionOffset);
|
||||
}
|
||||
|
||||
// Draw the selection partway between the tabs
|
||||
View nextTitle = getChildAt(mSelectedPosition + 1);
|
||||
left = (int) (mSelectionOffset * nextTitle.getLeft() +
|
||||
(1.0f - mSelectionOffset) * left);
|
||||
right = (int) (mSelectionOffset * nextTitle.getRight() +
|
||||
(1.0f - mSelectionOffset) * right);
|
||||
}
|
||||
|
||||
mSelectedIndicatorPaint.setColor(color);
|
||||
|
||||
canvas.drawRect(left, height - mSelectedIndicatorThickness, right,
|
||||
height, mSelectedIndicatorPaint);
|
||||
}
|
||||
|
||||
// Thin underline along the entire bottom edge
|
||||
canvas.drawRect(0, height - mBottomBorderThickness, getWidth(), height, mBottomBorderPaint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the alpha value of the {@code color} to be the given {@code alpha} value.
|
||||
*/
|
||||
private static int setColorAlpha(int color, byte alpha) {
|
||||
return Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color));
|
||||
}
|
||||
|
||||
/**
|
||||
* Blend {@code color1} and {@code color2} using the given ratio.
|
||||
*
|
||||
* @param ratio of which to blend. 1.0 will return {@code color1}, 0.5 will give an even blend,
|
||||
* 0.0 will return {@code color2}.
|
||||
*/
|
||||
private static int blendColors(int color1, int color2, float ratio) {
|
||||
final float inverseRation = 1f - ratio;
|
||||
float r = (Color.red(color1) * ratio) + (Color.red(color2) * inverseRation);
|
||||
float g = (Color.green(color1) * ratio) + (Color.green(color2) * inverseRation);
|
||||
float b = (Color.blue(color1) * ratio) + (Color.blue(color2) * inverseRation);
|
||||
return Color.rgb((int) r, (int) g, (int) b);
|
||||
}
|
||||
|
||||
private static class SimpleTabColorizer implements SlidingTabLayout.TabColorizer {
|
||||
private int[] mIndicatorColors;
|
||||
|
||||
@Override
|
||||
public final int getIndicatorColor(int position) {
|
||||
return mIndicatorColors[position % mIndicatorColors.length];
|
||||
}
|
||||
|
||||
void setIndicatorColors(int... colors) {
|
||||
mIndicatorColors = colors;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,46 +1,64 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/drawer_layout"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<RelativeLayout
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false">
|
||||
|
||||
<LinearLayout
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
android:background="@color/colorPrimary"
|
||||
android:elevation="4dp"
|
||||
app:contentInsetEnd="0dp"
|
||||
app:contentInsetEndWithActions="0dp"
|
||||
app:contentInsetStart="0dp"
|
||||
app:contentInsetStartWithNavigation="0dp">
|
||||
|
||||
|
||||
<info.nightscout.androidaps.tabs.SlidingTabLayout
|
||||
<android.support.design.widget.TabLayout
|
||||
android:id="@+id/tabs"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:paddingEnd="30dp" />
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/transparent"
|
||||
android:paddingRight="64dp"
|
||||
android:paddingLeft="64dp"
|
||||
app:tabIndicatorColor="@color/colorAccent"
|
||||
app:tabMode="scrollable" />
|
||||
</android.support.v7.widget.Toolbar>
|
||||
|
||||
<info.nightscout.androidaps.tabs.NonConsumingToolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/transparent"
|
||||
android:translationZ="4dp" />
|
||||
</FrameLayout>
|
||||
|
||||
<android.support.v4.widget.DrawerLayout
|
||||
android:id="@+id/drawer_layout"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp">
|
||||
|
||||
<android.support.v4.view.ViewPager
|
||||
android:id="@+id/pager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<android.support.design.widget.NavigationView
|
||||
android:id="@+id/navigation_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
app:itemBackground="@android:color/transparent"
|
||||
app:itemTextColor="#FFFFFF"
|
||||
android:layout_gravity="start" />
|
||||
</android.support.v4.widget.DrawerLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/overview_menuButton"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:background="@color/tabBgColor"
|
||||
android:paddingTop="5dp"
|
||||
app:srcCompat="@drawable/ic_more_vert_black_24dp" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</android.support.v4.widget.DrawerLayout>
|
7
app/src/main/res/layout/activity_single_fragment.xml
Normal file
7
app/src/main/res/layout/activity_single_fragment.xml
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/frame_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
</FrameLayout>
|
|
@ -1,31 +1,41 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
tools:context=".MainActivity">
|
||||
<item
|
||||
android:id="@+id/nav_preferences"
|
||||
app:showAsAction="never"
|
||||
android:title="@string/nav_preferences" />
|
||||
<item
|
||||
android:id="@+id/nav_historybrowser"
|
||||
app:showAsAction="never"
|
||||
android:title="@string/nav_historybrowser" />
|
||||
<item
|
||||
android:id="@+id/nav_setupwizard"
|
||||
app:showAsAction="never"
|
||||
android:title="@string/nav_setupwizard" />
|
||||
<item
|
||||
android:id="@+id/nav_resetdb"
|
||||
app:showAsAction="never"
|
||||
android:title="@string/nav_resetdb" />
|
||||
<item
|
||||
android:id="@+id/nav_export"
|
||||
app:showAsAction="never"
|
||||
android:title="@string/nav_export" />
|
||||
<item
|
||||
android:id="@+id/nav_import"
|
||||
app:showAsAction="never"
|
||||
android:title="@string/nav_import" />
|
||||
<item
|
||||
android:id="@+id/nav_show_logcat"
|
||||
app:showAsAction="never"
|
||||
android:title="@string/nav_show_logcat" />
|
||||
<item
|
||||
android:id="@+id/nav_about"
|
||||
app:showAsAction="never"
|
||||
android:title="@string/nav_about" />
|
||||
<item
|
||||
android:id="@+id/nav_exit"
|
||||
app:showAsAction="never"
|
||||
android:title="@string/nav_exit" />
|
||||
</menu>
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<style name="AppTheme" parent="AppTheme.base">
|
||||
|
||||
</style>
|
||||
</resources>
|
|
@ -37,9 +37,9 @@
|
|||
<color name="tempTargetDisabledBackground">#303F9F</color>
|
||||
|
||||
|
||||
<color name="colorPrimary">#3F51B5</color>
|
||||
<color name="colorPrimaryDark">#303F9F</color>
|
||||
<color name="colorAccent">#FF4081</color>
|
||||
<color name="colorPrimary">#212121</color>
|
||||
<color name="colorPrimaryDark">#000000</color>
|
||||
<color name="colorAccent">#FFEB3B</color>
|
||||
<color name="colorInitializingBorder">#00695c</color>
|
||||
|
||||
<color name="cardColorBackground">#121212</color>
|
||||
|
|
|
@ -1088,4 +1088,6 @@
|
|||
<string name="request">Request</string>
|
||||
<string name="insulinsourcesetup">Configure Insulin plugin</string>
|
||||
<string name="exit">Exit</string>
|
||||
<string name="open_navigation">Open navigation</string>
|
||||
<string name="close_navigation">Close navigation</string>
|
||||
</resources>
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="android:Theme.Material">
|
||||
<!-- Customize your theme here. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat">
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.NoActionBar">
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
|
|
Loading…
Reference in a new issue