From b08fd9ab143a1648e5b82aff3e21c5f8175c13bb Mon Sep 17 00:00:00 2001 From: Adrian Ulrich Date: Thu, 31 Dec 2015 17:28:53 +0100 Subject: [PATCH 1/9] Add tabs code from GOOG --- .../iosched/tabs/SlidingTabLayout.java | 322 ++++++++++++++++++ .../support/iosched/tabs/SlidingTabStrip.java | 166 +++++++++ 2 files changed, 488 insertions(+) create mode 100644 src/android/support/iosched/tabs/SlidingTabLayout.java create mode 100644 src/android/support/iosched/tabs/SlidingTabStrip.java diff --git a/src/android/support/iosched/tabs/SlidingTabLayout.java b/src/android/support/iosched/tabs/SlidingTabLayout.java new file mode 100644 index 00000000..86b0997e --- /dev/null +++ b/src/android/support/iosched/tabs/SlidingTabLayout.java @@ -0,0 +1,322 @@ +// imported from https://raw.githubusercontent.com/google/iosched/2531cbdbe27e5795eb78bf47d27e8c1be494aad4/android/src/main/java/com/google/samples/apps/iosched/ui/widget/SlidingTabLayout.java +/* + * 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. + */ + +package android.support.iosched.tabs; + +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; + +/** + * To be used with ViewPager to provide a tab indicator component which give constant feedback as to + * the user's scroll progress. + *

+ * 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. + *

+ * 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. + *

+ * 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 = 16; + 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 mContentDescriptions = new SparseArray(); + 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); + } + + /** + * 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; + } + } + } + } + +} diff --git a/src/android/support/iosched/tabs/SlidingTabStrip.java b/src/android/support/iosched/tabs/SlidingTabStrip.java new file mode 100644 index 00000000..7d709925 --- /dev/null +++ b/src/android/support/iosched/tabs/SlidingTabStrip.java @@ -0,0 +1,166 @@ +// imported from https://raw.githubusercontent.com/google/iosched/2531cbdbe27e5795eb78bf47d27e8c1be494aad4/android/src/main/java/com/google/samples/apps/iosched/ui/widget/SlidingTabStrip.java +/* + * 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. + */ + +package android.support.iosched.tabs; + +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; + +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 static final int DEFAULT_SELECTED_INDICATOR_COLOR = 0xFF33B5E5; + + 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(DEFAULT_SELECTED_INDICATOR_COLOR); + + 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; + } + } +} From 9a319f9e053707e6039ac4caf0b3cff30156580e Mon Sep 17 00:00:00 2001 From: Adrian Ulrich Date: Thu, 31 Dec 2015 20:53:39 +0100 Subject: [PATCH 2/9] Migrate to SlidingTabLayout --- AndroidManifest.xml | 1 - res/layout/library_content.xml | 13 ++- res/values-v21/colors.xml | 4 + res/values/colors.xml | 11 +++ res/values/theme.xml | 7 -- .../iosched/tabs/VanillaTabLayout.java | 85 +++++++++++++++++ .../android/vanilla/CompatHoneycomb.java | 93 ------------------- .../android/vanilla/LibraryActivity.java | 9 +- 8 files changed, 112 insertions(+), 111 deletions(-) create mode 100644 res/values/colors.xml create mode 100644 src/android/support/iosched/tabs/VanillaTabLayout.java delete mode 100644 src/ch/blinkenlights/android/vanilla/CompatHoneycomb.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index af749b73..5351b2c6 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -42,7 +42,6 @@ THE SOFTWARE. diff --git a/res/layout/library_content.xml b/res/layout/library_content.xml index 3862eba3..104852e9 100644 --- a/res/layout/library_content.xml +++ b/res/layout/library_content.xml @@ -27,13 +27,12 @@ THE SOFTWARE. android:layout_width="fill_parent" android:layout_height="fill_parent"> - + + @color/vanillaAccent + + @color/vanillaPrimary + @android:color/primary_text_dark + #ffeeeeee #f000 diff --git a/res/values/colors.xml b/res/values/colors.xml new file mode 100644 index 00000000..bb127083 --- /dev/null +++ b/res/values/colors.xml @@ -0,0 +1,11 @@ + + + + @android:color/holo_blue_dark + #fff5f5f5 + + @android:color/holo_blue_dark + + #ff1e1e1e + @android:color/holo_blue_dark + diff --git a/res/values/theme.xml b/res/values/theme.xml index 3e952ffc..577738c2 100644 --- a/res/values/theme.xml +++ b/res/values/theme.xml @@ -21,13 +21,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --> - - @android:color/holo_blue_dark - #fff5f5f5 - - - @android:color/holo_blue_dark - @@ -62,10 +61,6 @@ Copyright (C) 2015 Adrian Ulrich @color/material_grey_300 - - From 6910376b1717d7a4d8d47034d63cbc630f59aea5 Mon Sep 17 00:00:00 2001 From: Adrian Ulrich Date: Thu, 31 Dec 2015 21:03:23 +0100 Subject: [PATCH 4/9] remove obsoleted theming --- res/values-v21/theme.xml | 9 --------- res/values/theme.xml | 5 ----- 2 files changed, 14 deletions(-) diff --git a/res/values-v21/theme.xml b/res/values-v21/theme.xml index 7de71fb1..4240a4f2 100644 --- a/res/values-v21/theme.xml +++ b/res/values-v21/theme.xml @@ -40,7 +40,6 @@ Copyright (C) 2015 Adrian Ulrich @@ -52,13 +51,6 @@ Copyright (C) 2015 Adrian Ulrich - - @@ -82,7 +74,6 @@ Copyright (C) 2015 Adrian Ulrich diff --git a/res/values/theme.xml b/res/values/theme.xml index 577738c2..b02f6eb1 100644 --- a/res/values/theme.xml +++ b/res/values/theme.xml @@ -47,14 +47,9 @@ THE SOFTWARE. - From 1d5ce6d239e95590ba334e1d6b5309ad0ef245fa Mon Sep 17 00:00:00 2001 From: Adrian Ulrich Date: Thu, 31 Dec 2015 21:30:20 +0100 Subject: [PATCH 5/9] Make scrolling nice again --- src/ch/blinkenlights/android/vanilla/LibraryActivity.java | 2 +- src/ch/blinkenlights/android/vanilla/LibraryPagerAdapter.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ch/blinkenlights/android/vanilla/LibraryActivity.java b/src/ch/blinkenlights/android/vanilla/LibraryActivity.java index 9c6f28c1..a4ecb57f 100644 --- a/src/ch/blinkenlights/android/vanilla/LibraryActivity.java +++ b/src/ch/blinkenlights/android/vanilla/LibraryActivity.java @@ -185,7 +185,6 @@ public class LibraryActivity mViewPager = pager; SharedPreferences settings = PlaybackService.getSettings(this); - pager.setOnPageChangeListener(pagerAdapter); View controls = getLayoutInflater().inflate(R.layout.actionbar_controls, null); mTitle = (TextView)controls.findViewById(R.id.title); @@ -204,6 +203,7 @@ public class LibraryActivity mVanillaTabLayout = (VanillaTabLayout)findViewById(R.id.sliding_tabs); mVanillaTabLayout.inheritElevation(getActionBar()); + mVanillaTabLayout.setOnPageChangeListener(pagerAdapter); loadTabOrder(); int page = settings.getInt(PrefKeys.LIBRARY_PAGE, PrefDefaults.LIBRARY_PAGE); diff --git a/src/ch/blinkenlights/android/vanilla/LibraryPagerAdapter.java b/src/ch/blinkenlights/android/vanilla/LibraryPagerAdapter.java index 92ccbc75..f056a716 100644 --- a/src/ch/blinkenlights/android/vanilla/LibraryPagerAdapter.java +++ b/src/ch/blinkenlights/android/vanilla/LibraryPagerAdapter.java @@ -812,7 +812,7 @@ public class LibraryPagerAdapter // onPageSelected and setPrimaryItem are called in similar cases, and it // would be nice to use just one of them, but each has caveats: // - onPageSelected isn't called when the ViewPager is first - // initialized + // initialized if there is no scrolling to do // - setPrimaryItem isn't called until scrolling is complete, which // makes tab bar and limiter updates look bad // So we use both. From ed67cb0af237f79c387d260f189f7933eed956f6 Mon Sep 17 00:00:00 2001 From: Adrian Ulrich Date: Sat, 2 Jan 2016 11:42:54 +0100 Subject: [PATCH 6/9] use platform default text size for tab text --- src/android/support/iosched/tabs/VanillaTabLayout.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/android/support/iosched/tabs/VanillaTabLayout.java b/src/android/support/iosched/tabs/VanillaTabLayout.java index ec94a519..440480eb 100644 --- a/src/android/support/iosched/tabs/VanillaTabLayout.java +++ b/src/android/support/iosched/tabs/VanillaTabLayout.java @@ -52,6 +52,7 @@ public class VanillaTabLayout extends SlidingTabLayout { TextView view = super.createDefaultTabView(context); int color = getResources().getColor(android.R.color.primary_text_dark); view.setTextColor(color); + view.setTextSize(14); return view; } From fbc5b0732b3df21ac41cda5fd0d2810992080ce6 Mon Sep 17 00:00:00 2001 From: Adrian Ulrich Date: Sat, 2 Jan 2016 12:01:26 +0100 Subject: [PATCH 7/9] use setSelectedIndicatorColors instead of a colorizer class --- .../support/iosched/tabs/VanillaTabLayout.java | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/android/support/iosched/tabs/VanillaTabLayout.java b/src/android/support/iosched/tabs/VanillaTabLayout.java index 440480eb..f0a538cb 100644 --- a/src/android/support/iosched/tabs/VanillaTabLayout.java +++ b/src/android/support/iosched/tabs/VanillaTabLayout.java @@ -40,7 +40,7 @@ public class VanillaTabLayout extends SlidingTabLayout { public VanillaTabLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); - setCustomTabColorizer(new TabColorizer(context)); + setSelectedIndicatorColors(context.getResources().getColor(ch.blinkenlights.android.vanilla.R.color.tabs_active_indicator)); setDistributeEvenly(true); } @@ -71,16 +71,5 @@ public class VanillaTabLayout extends SlidingTabLayout { } - private static class TabColorizer implements SlidingTabLayout.TabColorizer { - private final int mTabIndicatorColor; - TabColorizer(Context context) { - mTabIndicatorColor = context.getResources().getColor(ch.blinkenlights.android.vanilla.R.color.tabs_active_indicator); - } - @Override - public final int getIndicatorColor(int position) { - return mTabIndicatorColor; - } - } - } From bd15ec5e588e377fa75ec8486a2efb694752b3a1 Mon Sep 17 00:00:00 2001 From: Adrian Ulrich Date: Sat, 2 Jan 2016 12:53:07 +0100 Subject: [PATCH 8/9] use selector for tab font color --- res/color/tab_text_selector.xml | 5 +++++ src/android/support/iosched/tabs/VanillaTabLayout.java | 3 +-- 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 res/color/tab_text_selector.xml diff --git a/res/color/tab_text_selector.xml b/res/color/tab_text_selector.xml new file mode 100644 index 00000000..438fd917 --- /dev/null +++ b/res/color/tab_text_selector.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/src/android/support/iosched/tabs/VanillaTabLayout.java b/src/android/support/iosched/tabs/VanillaTabLayout.java index f0a538cb..9bd6625d 100644 --- a/src/android/support/iosched/tabs/VanillaTabLayout.java +++ b/src/android/support/iosched/tabs/VanillaTabLayout.java @@ -50,8 +50,7 @@ public class VanillaTabLayout extends SlidingTabLayout { @Override protected TextView createDefaultTabView(Context context) { TextView view = super.createDefaultTabView(context); - int color = getResources().getColor(android.R.color.primary_text_dark); - view.setTextColor(color); + view.setTextColor(getResources().getColorStateList(ch.blinkenlights.android.vanilla.R.color.tab_text_selector)); view.setTextSize(14); return view; } From dab9401c23188b886acda30c1da94fbc7948d623 Mon Sep 17 00:00:00 2001 From: Adrian Ulrich Date: Sat, 2 Jan 2016 13:35:25 +0100 Subject: [PATCH 9/9] Change folder icon size --- orig/folder.svgz | Bin 1058 -> 1064 bytes res/drawable-hdpi/folder.png | Bin 239 -> 757 bytes res/drawable-mdpi/folder.png | Bin 172 -> 632 bytes res/drawable-xhdpi/folder.png | Bin 171 -> 875 bytes res/drawable-xxhdpi/folder.png | Bin 561 -> 1301 bytes .../android/vanilla/FileSystemAdapter.java | 5 ++++- .../vanilla/FilebrowserStartAdapter.java | 8 +++++--- 7 files changed, 9 insertions(+), 4 deletions(-) diff --git a/orig/folder.svgz b/orig/folder.svgz index 44315d19f90380244dad9828c0c5b6047c1c1391..5622bf2627af77e1507f4923a28b49dd730d24bf 100644 GIT binary patch delta 1057 zcmV++1m63i2&f2<7Jnr{O+6^dk{ro<*kFMLdTO`mSr!?Yh$IRm9Xt8;9a2x{ftH3r za_0Ny#Ubtd+of&L3zLeAu5bd^cM$6;L3vjf&fmX&;M74%mmMt|(Xqnmg!65GlmCV> z`Yu_i8AWHVkLYLjtg5nS=zw^BF`Rwvh=n7eT_Xy+t&3{dndcLa z5DW;cUOQc0@HG`;{ESL`-}gYbApaj~r=Xxcd}sJ1aFsa8iai03xgFEq^UCX0k$=0gWvVYLro2gR`Dae`v2eDL-5nXPk9yv6S~w6d$s1lV~WDE*O4u_5jH#dr}5EI5a!(m^jF@+S!0%(-+Rp z3-(Z|Aq|B3vW6pXge;ufCp$*PK}c{nskU}psRWdT>wnjw$w%8$UdHOI_dnOGV@bui zaL9Y*n-Fc`r0>PmrEoAw-7wlho*%T}h!EG0ViE-(lqV^n{c%&iGRVeG6G$D!xt69X zTAtW@rqSTTL0mpp!{MCF#lokKYiQp7@*Z*K9b}2eehIQL`T{ZaP(Y%uAP@xkk`MXg zuXJsB;eRcEW00i3PW!|uQ(q)*bnDE=wrZI!X{pPlnI;LzGT$~Ppx`0c{rUJ~*ulQ4 zcK-G`F}MDAxT?9gD6YWzwP%ab!K`G%8}R8v zNUN3`lJ}S9P4m+@88cfM<+@>uF!#pj$K1SCa(}ruWp8)&QkAP7o2%NC2i6qMA4Z8j zXlp4>eJdy%>7!oDvQs8|a}uy@;8)_#--P6TDtA4_zk))oB){B+ZoKi~V`iL?(1q7J z+~6<{VmFEJor!5;u7fCuqgkZ%Yh&IWDAevYwd28T@OZO#!F+UiU+Uv>5X;3AUB@ad zB!7l0_)_YVWJ?R0VfqIVKXv0U@Z(LEC8$F1PLnhX!i{g1pdpZhOCl1GwZP7(LH;Iy zw8A8gf$JM2JiG{|kZhw7hpuVB3L?t^9~H8cEi5M#9@y*sNb@&1HN>s;HAZS9HsQ@c z{E>+R;zrxly7V`RJ4c%&mQO+xoMlc6P=Adz*bIny9gm^RQGk)bhE=Xm#LY&h=~Mzk z3Earvl8GLY#Kug_D{q-un4)1$;#mMmB$l@rF}BfnL;~AcsX0Mg3M)zCWNSrs2iSNx z;^^und8MYr=vfIY;!LX>q^?YzH#{qQpnDb2c)HKOA?uM^(4{oVFA z-$&miXPTGjTrV(dRA~1j&jRC*QGx0JQ~^4k=NBxPsh64c@Qtnv)G;&?LY>A zGqssCIEb=ZHdX>(!B! z;tVx=uY41t1u+d0nnomjuP!d23}~9Am}ECf6AumuNpXB*xHw4(L*O^;l|xeYLmWsQ z#krEEI9i_gd#2I&hl99$tcEK(nep;ZU9F*o`^$U8x$YoY-*pX1vYV1P#MnuBeiOb! zKn$OeA%A(Ae4=aFrEcpt4jEqMe5y;XKFQkXmT9}zYPn`5(`;_2Q9|<^+vWrmyak&- zAAbxdI2Xm{A0eOJ5tae4gE&F9-hL8q%VGo5+cLecTWAwA_`k!nZo^q|1=g=UpN$S? zB_E!F58uMFXlp|X|I&5S{4`EnW(%XWZus8%9DlZB7NJYSB^fTV+=gQr?5Uc|bJb~6 zc^h`%&CdJ7DAA3!lH%02qU4V5^jfk`nKGCwfo%i77+>(p&%Tazuf{|^g!&Y(19-5r zm7ix(5P$VXxCyi(5s9Nor1Wb8{-2;soBPbJ2XpY z>3@4+`Xu?>zh;^4K@?{}ye2qa<#~z<1P?XMa$Z<#)! zL6l_HC0?b$6m6PXK3$vOEOXp|%GF>sAb+NP>_VBM03(A9t6ZRHkUOW@SOP;KL4*@J z($_S#F;nx-TV}q_(C|&;NdQTtmNy$Qw$XP)iR&x4L0bwdN#iuJB6|XCJY4bHq619h zN$8Pv7R3wk`~wC%T*`xkc0=+f8;004m!2KWE~ diff --git a/res/drawable-hdpi/folder.png b/res/drawable-hdpi/folder.png index 438f50c696df1a3eede514488cea4e86aa834374..77d7e869d0b6315fe7c91ecd94a4a67f797c0b36 100644 GIT binary patch literal 757 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGoEX7WqAsj$Z!;#Vf4nJ zh#UrCM$rOaC!nBYiEBhjaDG}zd16s2LwR|*US?i)adKios$PCk`s{Z$QVa}CMV>B> zAr*7p-Zjh?2^492XzpmxrC^q{^vEf-R)rboLSyj*JCbM69brFG_amWR9) zDe2wDE}vjuU~24dc5l6p=7Ffqp?~rOcPQK{FJ8*veKzdlcIHF1=1?6cqt|E*`wT>hJ{ zu%YhUci9IFf4|tZS|hnO;w<;Z>jyq}eSUVZdmnQaYXti{_aocAKD#Y;YnU!rxc$(a zz*QfmJ}f!Zb8(g6f#q}M*mg?Kn(2LDqhi|mnQuFOgxpG4ar@%x1DhMu&QI>2`BPwr zpkV&;+y}245@nh67^P#SEgYm@$NB?F_ucaf7!273im6U)lw$1r|2WyqwU;4#X62Lq z<9gvUthr40t*8~aapp|)0qF-^qW|VUi@5S@*&nWg<(Jk3e(c_Wh%q2*DpO6~wywSF zKSxYsvXM$qOukyF|l3?zm1T2})pg8-ip*Z=?j_w@91c6PSI05ZD+ z18}f8M*;Qnmjw9*GlvLk{R&8LSZEv!*b5sO3!sSvIDJR@O1TaS?83{1OQ!6 BUz`8{ diff --git a/res/drawable-mdpi/folder.png b/res/drawable-mdpi/folder.png index 58bff4d025fcd57f1341c6f9fca113a6fe4fd497..137b88cf5d0f973c0b1742ef89c89f1762ec53cc 100644 GIT binary patch literal 632 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=EX7WqAsj$Z!;#Vf2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4tn=k4lfZhmoo#f$!ew`w~$RXc;IT)YM{cujA`28K0mfQx7u0?0M zIXPB)Cm79)`61+(D5~H&NjzRj<5``^wW#vW6|c`6F+Nix%W|-C{dMVDx%els3EeZT zxvQ>vrd!Q@Cv@@P^MlLovVGsrZ=&nK2{K-p@d8tZ3do@#-%n)7U^Ee8&~0#ITEKe2 zgJBDU6sn@ohPwUxKN$wDoEo|RuYLq;#`fFCU0j+ECY+The&N0{E=Rx7#P@RGyyxFt zw!Cy+k@xIpe!=OjEJ8O~E&{D_IC>-bt=QK{8oRzfx?7rgXnE(7+>!stDTwEfj z<%+p(jBO8%)mWN$*g&WDUby4}&l74LP)Eiweltk>c&WrG5|~ODJYD@<);T3K0RVuX B36%f< literal 172 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaN3?zjj6;6XV0X`wF|NsB*?Ck95=xB!lAR7p7 z>+f&_s$nk)@(X4NiD_7H;NL8_#9E+`ji-xah(vgDf&#aOw6vnd)2B~0WRjDUoh{fo zPA!m0PZnq>nsHF3L-Xkyfz~Y#T9k`VO|&?5%tKE>l7ZoEg4P6u`pMZqa~M2b{an^L HB{Ts5+1fd! diff --git a/res/drawable-xhdpi/folder.png b/res/drawable-xhdpi/folder.png index 3bc354020adb6f85949a152bc78ba1ddaa71ce1f..669b0ea5ec497d3e9d160432b911fae81ac95971 100644 GIT binary patch literal 875 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSEX7WqAsj$Z!;#Vf4nJ zNUsNB#yF{oGC)De64!{5;QX|b^2DN4hVt@qz0ADq;^f4FRK5J7^x5xhq!<{OUU<4V zhE&XXdsi`EBv7R7VZNq$5lJv%-l2c?#=vpPkrT!G^6h-pVQPQ-<%s;8ms*w9736`rYS!FVIvBz7@e!JkSKyj$>fx2HJkIyC^^IXOGAPmk-m}+;l zqIgE(q#ZmaKx@$K-uY^GW3ag3`sni;T<0#4pVa52d3+}K)jPaTRy)7_Gx5u+DWBA` z8T}Y9m$_cDQks{l>%j2&gHrZ!76bn6o6CF{J{RZ$ImrHiS#YzQ`M=jKk6&t?>+^gA z(irxu*lI1U@rz+rPMyaTSM*`IzHtM8=kH_FmaqnR{hYZqKZie@5$L>_$^5N)ZbP0l+XkKZ6sN( literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDB3?!H8JlO)IgaUj*T>t<7-`?Kd+1c3v1IkXa zKuHGHk|4ie29MdR|5a7b_67<#d%8G=Se#Bykl;LEBEr$M(W9k_QB-xo0nX_z9D1Dr zk5pJTR12)`ULbTLjrH*)4%w*-*0m@AC9*tcEb3zK@0i2GP@L5;=a%RMGmr(Iu6{1- HoD!M4nJ zXtsecqtcuEJwQRp64!{5;QX|b^2DN4hVt@qz0ADq;^f4FRK5J7^x5xhq<{uZ@^oEt$N;=-ss+NcBzjEZ}oxl15>ZvdcL>);>DX1#Y$^d zy<@gxii`Q>a=BRWM&8=L*Qy0{?>}HzmBsv{>F@tPn(G+OZ@p$?Z)Kdkk2z=Z)}M+0 zE4NqkFMKL3eBj!p-GZ_5zYP-Hp_;qLVvuXxcW8#qY zm4!b{LcgZIm%Mi2{(=4j<_DIq-5PIo{sPf`@iVe5urq5kuLd#duUNVDoAZ0eDal%lG3@8IUaNa&+p)>#sr7-~ zd39e6rZVh%W!qrntJ;vgmpx#aC(DJX->bj#oHFTTSQ5wMa1n@>eUf|NuLa-J+Rumeu=XA)P9E`akd2+#GquR9s9m$E_o`k$NV_UhqoQ3m$Z29%}!?ek#j^U zQz*KRG{Xl@z8aB0_P+lEDwq@cgd@!z}Sv?bpv1B);QPgg&e IbxsLQ0Cjc_%m4rY delta 497 zcmbQrwUI@!Gr-TCmrII^fq{Y7)59eQNPB=V2OE$KeY@FxqM}bd<2p|l$B>FSZ|~Up z9d-~n`ms{X_f^Q9W;+=LC#Q)TFLpMmhA%sP+_9;}rFjQ~ZTfEM++Me}-Tf&-ENu(n{!Ksl0jqyn7Ys1$n+x4qn-MjnTQk|v1 zLax95_p(er%j4g5Ed?6HjiVV(*l9LQof(_X|03{{5c39$uS*1te=V{Fo7eHg*XmT- z=1Lty@dN4COV8)tE))FB#?7)o*RtL%^#RP1B)DDdRw-8_5Jz5g5Pc(zZ<{(_S@Mrbr+}gIXzEJouixd#|dugx~VI`@B7#yMJ>zeCv;FV|wu5-R~!lzg!pje_75&Ltvpp f3zHxh2E+bYRq)S`4y^xxvB==*>gTe~DWM4fz1qq5 diff --git a/src/ch/blinkenlights/android/vanilla/FileSystemAdapter.java b/src/ch/blinkenlights/android/vanilla/FileSystemAdapter.java index 6548d554..36557a4a 100644 --- a/src/ch/blinkenlights/android/vanilla/FileSystemAdapter.java +++ b/src/ch/blinkenlights/android/vanilla/FileSystemAdapter.java @@ -201,7 +201,10 @@ public class FileSystemAdapter holder = new ViewHolder(); holder.text = (TextView)view.findViewById(R.id.text); holder.divider = (View)view.findViewById(R.id.divider); + holder.cover = (LazyCoverView)view.findViewById(R.id.cover); holder.arrow = (ImageView)view.findViewById(R.id.arrow); + + holder.cover.setImageDrawable(mFolderIcon); holder.arrow.setOnClickListener(this); view.setTag(holder); } else { @@ -215,7 +218,7 @@ public class FileSystemAdapter holder.text.setText(file.getName()); holder.arrow.setVisibility(isDirectory ? View.VISIBLE : View.GONE); holder.divider.setVisibility(isDirectory ? View.VISIBLE : View.GONE); - holder.text.setCompoundDrawablesWithIntrinsicBounds(isDirectory ? mFolderIcon : null, null, null, null); + holder.cover.setVisibility(isDirectory ? View.VISIBLE : View.GONE); return view; } diff --git a/src/ch/blinkenlights/android/vanilla/FilebrowserStartAdapter.java b/src/ch/blinkenlights/android/vanilla/FilebrowserStartAdapter.java index 72a5bfb1..e4b4aa9b 100644 --- a/src/ch/blinkenlights/android/vanilla/FilebrowserStartAdapter.java +++ b/src/ch/blinkenlights/android/vanilla/FilebrowserStartAdapter.java @@ -55,8 +55,13 @@ public class FilebrowserStartAdapter holder = new ViewHolder(); holder.text = (TextView)view.findViewById(R.id.text); holder.divider = view.findViewById(R.id.divider); + holder.cover = (LazyCoverView)view.findViewById(R.id.cover); + holder.arrow = (ImageView)view.findViewById(R.id.arrow); + + holder.cover.setImageDrawable(mFolderIcon); holder.text.setOnClickListener(this); + holder.cover.setVisibility(View.VISIBLE); view.setTag(holder); } else { view = convertView; @@ -66,9 +71,6 @@ public class FilebrowserStartAdapter String label = getItem(pos); holder.id = pos; holder.text.setText(label); - holder.divider.setVisibility(View.GONE); - holder.arrow.setVisibility(View.GONE); - holder.text.setCompoundDrawablesWithIntrinsicBounds(mFolderIcon, null, null, null); return view; }