improved quickreturn

This commit is contained in:
Mariotaku Lee 2014-10-22 22:55:26 +08:00
parent 90cfd1866d
commit 84534f577c
15 changed files with 209 additions and 666 deletions

View File

@ -155,7 +155,7 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
private SupportTabsAdapter mPagerAdapter;
private ExtendedViewPager mViewPager;
private TabPagerIndicator mIndicator;
private TabPagerIndicator mTabIndicator;
private HomeSlidingMenu mSlidingMenu;
private View mEmptyTabHint;
private ProgressBar mSmartBarProgress;
@ -189,7 +189,7 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
@Override
public void setControlBarOffset(float offset) {
mIndicator.setTranslationY(getControlBarHeight() * (offset - 1));
mTabIndicator.setTranslationY(getControlBarHeight() * (offset - 1));
mActionsButton.setTranslationY(mActionsButton.getHeight() * (1 - offset));
}
@ -244,7 +244,7 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
mViewPager = (ExtendedViewPager) findViewById(R.id.main_pager);
mEmptyTabHint = findViewById(R.id.empty_tab_hint);
mActionsButton = (HomeActionsActionView) findViewById(R.id.actions_button_bottom);
mIndicator = (TabPagerIndicator) findViewById(android.R.id.tabs);
mTabIndicator = (TabPagerIndicator) findViewById(android.R.id.tabs);
}
@Override
@ -265,7 +265,7 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
@Override
public boolean getSystemWindowsInsets(Rect insets) {
final int height = mIndicator.getHeight();
final int height = mTabIndicator.getHeight();
insets.top = height != 0 ? height : Utils.getActionBarHeight(this);
return true;
}
@ -438,12 +438,12 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
@Override
public float getControlBarOffset() {
final float totalHeight = getControlBarHeight();
return 1 + mIndicator.getTranslationY() / totalHeight;
return 1 + mTabIndicator.getTranslationY() / totalHeight;
}
@Override
public int getControlBarHeight() {
return mIndicator.getHeight() - mIndicator.getStripHeight();
return mTabIndicator.getHeight() - mTabIndicator.getStripHeight();
}
@Override
@ -454,9 +454,9 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
}
public void updateUnreadCount() {
if (mIndicator == null || mUpdateUnreadCountTask != null
if (mTabIndicator == null || mUpdateUnreadCountTask != null
&& mUpdateUnreadCountTask.getStatus() == AsyncTask.Status.RUNNING) return;
mUpdateUnreadCountTask = new UpdateUnreadCountTask(mIndicator, mPreferences.getBoolean(KEY_UNREAD_COUNT, true));
mUpdateUnreadCountTask = new UpdateUnreadCountTask(mTabIndicator, mPreferences.getBoolean(KEY_UNREAD_COUNT, true));
mUpdateUnreadCountTask.execute();
}
@ -528,18 +528,18 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
actionBar.hide();
}
ThemeUtils.applyBackground(mIndicator);
mPagerAdapter = new SupportTabsAdapter(this, getSupportFragmentManager(), mIndicator, 1);
ThemeUtils.applyBackground(mTabIndicator);
mPagerAdapter = new SupportTabsAdapter(this, getSupportFragmentManager(), mTabIndicator, 1);
mViewPager.setAdapter(mPagerAdapter);
mViewPager.setOffscreenPageLimit(3);
mIndicator.setViewPager(mViewPager);
mIndicator.setOnPageChangeListener(this);
mTabIndicator.setViewPager(mViewPager);
mTabIndicator.setOnPageChangeListener(this);
if (mTabDisplayOption != 0) {
mIndicator.setDisplayLabel((mTabDisplayOption & VALUE_TAB_DIPLAY_OPTION_CODE_LABEL) != 0);
mIndicator.setDisplayIcon((mTabDisplayOption & VALUE_TAB_DIPLAY_OPTION_CODE_ICON) != 0);
mTabIndicator.setDisplayLabel((mTabDisplayOption & VALUE_TAB_DIPLAY_OPTION_CODE_LABEL) != 0);
mTabIndicator.setDisplayIcon((mTabDisplayOption & VALUE_TAB_DIPLAY_OPTION_CODE_ICON) != 0);
} else {
mIndicator.setDisplayLabel(false);
mIndicator.setDisplayIcon(true);
mTabIndicator.setDisplayLabel(false);
mTabIndicator.setDisplayIcon(true);
}
mActionsButton.setOnClickListener(this);
mActionsButton.setOnLongClickListener(this);
@ -633,9 +633,9 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
}
protected void setPagingEnabled(final boolean enabled) {
if (mIndicator != null && mViewPager != null) {
if (mTabIndicator != null && mViewPager != null) {
mViewPager.setEnabled(!mPreferences.getBoolean(KEY_DISABLE_TAB_SWIPE, false));
mIndicator.setEnabled(enabled);
mTabIndicator.setEnabled(enabled);
}
}
@ -697,8 +697,8 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
}
private void initUnreadCount() {
for (int i = 0, j = mIndicator.getCount(); i < j; i++) {
mIndicator.setBadge(i, 0);
for (int i = 0, j = mTabIndicator.getCount(); i < j; i++) {
mTabIndicator.setBadge(i, 0);
}
}
@ -867,7 +867,8 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
public void moveControlBarBy(int delta) {
final int min = -getControlBarHeight(), max = 0;
mIndicator.setTranslationY(MathUtils.clamp(mIndicator.getTranslationY() + delta, max, min));
mTabIndicator.setTranslationY(MathUtils.clamp(mTabIndicator.getTranslationY() + delta, max, min));
mActionsButton.setTranslationY(MathUtils.clamp(mActionsButton.getTranslationY() - delta, mActionsButton.getHeight(), 0));
}

View File

@ -19,106 +19,107 @@
package org.mariotaku.twidere.adapter;
import static org.mariotaku.twidere.util.CustomTabUtils.getTabIconDrawable;
import static org.mariotaku.twidere.util.Utils.announceForAccessibilityCompat;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v13.app.FragmentStatePagerAdapter;
import android.view.View;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.model.TabSpec;
import org.mariotaku.twidere.view.TabPageIndicator2;
import org.mariotaku.twidere.view.iface.PagerIndicator;
import org.mariotaku.twidere.view.iface.PagerIndicator.TabListener;
import org.mariotaku.twidere.view.iface.PagerIndicator.TabProvider;
import java.util.ArrayList;
import java.util.Collection;
import static org.mariotaku.twidere.util.CustomTabUtils.getTabIconDrawable;
import static org.mariotaku.twidere.util.Utils.announceForAccessibilityCompat;
public class TabsAdapter extends FragmentStatePagerAdapter implements TabProvider, TabListener, Constants {
private final ArrayList<TabSpec> mTabs = new ArrayList<TabSpec>();
private final ArrayList<TabSpec> mTabs = new ArrayList<TabSpec>();
private final Context mContext;
private final TabPageIndicator2 mIndicator;
private final Context mContext;
private final PagerIndicator mIndicator;
public TabsAdapter(final Context context, final FragmentManager fm, final TabPageIndicator2 indicator) {
super(fm);
mContext = context;
mIndicator = indicator;
clear();
}
public TabsAdapter(final Context context, final FragmentManager fm, final PagerIndicator indicator) {
super(fm);
mContext = context;
mIndicator = indicator;
clear();
}
public void addTab(final Class<? extends Fragment> cls, final Bundle args, final CharSequence title,
final Integer icon, final int position) {
addTab(new TabSpec(title, icon, cls, args, position));
}
public void addTab(final Class<? extends Fragment> cls, final Bundle args, final CharSequence title,
final Integer icon, final int position) {
addTab(new TabSpec(title, icon, cls, args, position));
}
public void addTab(final TabSpec spec) {
mTabs.add(spec);
notifyDataSetChanged();
}
public void addTab(final TabSpec spec) {
mTabs.add(spec);
notifyDataSetChanged();
}
public void addTabs(final Collection<? extends TabSpec> specs) {
mTabs.addAll(specs);
notifyDataSetChanged();
}
public void addTabs(final Collection<? extends TabSpec> specs) {
mTabs.addAll(specs);
notifyDataSetChanged();
}
public void clear() {
mTabs.clear();
notifyDataSetChanged();
}
public void clear() {
mTabs.clear();
notifyDataSetChanged();
}
@Override
public int getCount() {
return mTabs.size();
}
@Override
public int getCount() {
return mTabs.size();
}
@Override
public Fragment getItem(final int position) {
final Fragment fragment = Fragment.instantiate(mContext, mTabs.get(position).cls.getName());
fragment.setArguments(mTabs.get(position).args);
return fragment;
}
@Override
public Fragment getItem(final int position) {
final Fragment fragment = Fragment.instantiate(mContext, mTabs.get(position).cls.getName());
fragment.setArguments(mTabs.get(position).args);
return fragment;
}
@Override
public Drawable getPageIcon(final int position) {
return getTabIconDrawable(mContext, mTabs.get(position).icon);
}
@Override
public Drawable getPageIcon(final int position) {
return getTabIconDrawable(mContext, mTabs.get(position).icon);
}
@Override
public CharSequence getPageTitle(final int position) {
return mTabs.get(position).name;
}
@Override
public CharSequence getPageTitle(final int position) {
return mTabs.get(position).name;
}
public TabSpec getTab(final int position) {
return position >= 0 && position < mTabs.size() ? mTabs.get(position) : null;
}
public TabSpec getTab(final int position) {
return position >= 0 && position < mTabs.size() ? mTabs.get(position) : null;
}
@Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
if (mIndicator != null) {
mIndicator.notifyDataSetChanged();
}
}
@Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
if (mIndicator != null) {
mIndicator.notifyDataSetChanged();
}
}
@Override
public void onPageReselected(final int position) {
}
@Override
public void onPageReselected(final int position) {
}
@Override
public void onPageSelected(final int position) {
if (mIndicator == null) return;
announceForAccessibilityCompat(mContext, mIndicator, getPageTitle(position), getClass());
}
@Override
public void onPageSelected(final int position) {
if (mIndicator == null) return;
announceForAccessibilityCompat(mContext, (View) mIndicator, getPageTitle(position), getClass());
}
@Override
public boolean onTabLongClick(final int position) {
return true;
}
@Override
public boolean onTabLongClick(final int position) {
return true;
}
}

View File

@ -433,7 +433,7 @@ public class BaseSupportListFragment extends ListFragment implements IBaseFragme
@Override
public void onScrollDistanceChanged(int delta, int total) {
final FragmentActivity a = getActivity();
if (a instanceof HomeActivity && getTabPosition() >= 0) {
if (a instanceof HomeActivity && getTabPosition() >= 0 && getUserVisibleHint()) {
final HomeActivity home = (HomeActivity) a;
home.moveControlBarBy(delta);
}

View File

@ -5,6 +5,7 @@ import android.os.Environment;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Map.Entry;
@ -13,55 +14,60 @@ import java.util.Set;
public class BuildProperties {
private final Properties properties;
private final Properties properties;
private BuildProperties() throws IOException {
properties = new Properties();
properties.load(new FileInputStream(new File(Environment.getRootDirectory(), "build.prop")));
}
private BuildProperties() throws IOException {
properties = new Properties();
final InputStream is = new FileInputStream(new File(Environment.getRootDirectory(), "build.prop"));
try {
properties.load(is);
} finally {
Utils.closeSilently(is);
}
}
public boolean containsKey(final Object key) {
return properties.containsKey(key);
}
public boolean containsKey(final Object key) {
return properties.containsKey(key);
}
public boolean containsValue(final Object value) {
return properties.containsValue(value);
}
public boolean containsValue(final Object value) {
return properties.containsValue(value);
}
public Set<Entry<Object, Object>> entrySet() {
return properties.entrySet();
}
public Set<Entry<Object, Object>> entrySet() {
return properties.entrySet();
}
public String getProperty(final String name) {
return properties.getProperty(name);
}
public String getProperty(final String name) {
return properties.getProperty(name);
}
public String getProperty(final String name, final String defaultValue) {
return properties.getProperty(name, defaultValue);
}
public String getProperty(final String name, final String defaultValue) {
return properties.getProperty(name, defaultValue);
}
public boolean isEmpty() {
return properties.isEmpty();
}
public boolean isEmpty() {
return properties.isEmpty();
}
public Enumeration<Object> keys() {
return properties.keys();
}
public Enumeration<Object> keys() {
return properties.keys();
}
public Set<Object> keySet() {
return properties.keySet();
}
public Set<Object> keySet() {
return properties.keySet();
}
public int size() {
return properties.size();
}
public int size() {
return properties.size();
}
public Collection<Object> values() {
return properties.values();
}
public Collection<Object> values() {
return properties.values();
}
public static BuildProperties newInstance() throws IOException {
return new BuildProperties();
}
public static BuildProperties newInstance() throws IOException {
return new BuildProperties();
}
}

View File

@ -4,18 +4,18 @@ import java.io.IOException;
public final class MIUIUtils {
private static final String KEY_MIUI_VERSION_CODE = "ro.miui.ui.version.code";
private static final String KEY_MIUI_VERSION_NAME = "ro.miui.ui.version.name";
private static final String KEY_MIUI_INTERNAL_STORAGE = "ro.miui.internal.storage";
private static final String KEY_MIUI_VERSION_CODE = "ro.miui.ui.version.code";
private static final String KEY_MIUI_VERSION_NAME = "ro.miui.ui.version.name";
private static final String KEY_MIUI_INTERNAL_STORAGE = "ro.miui.internal.storage";
public static boolean isMIUI() {
try {
final BuildProperties prop = BuildProperties.newInstance();
return prop.getProperty(KEY_MIUI_VERSION_CODE, null) != null
|| prop.getProperty(KEY_MIUI_VERSION_NAME, null) != null
|| prop.getProperty(KEY_MIUI_INTERNAL_STORAGE, null) != null;
} catch (final IOException e) {
return false;
}
}
public static boolean isMIUI() {
try {
final BuildProperties prop = BuildProperties.newInstance();
return prop.getProperty(KEY_MIUI_VERSION_CODE, null) != null
|| prop.getProperty(KEY_MIUI_VERSION_NAME, null) != null
|| prop.getProperty(KEY_MIUI_INTERNAL_STORAGE, null) != null;
} catch (final IOException e) {
return false;
}
}
}

View File

@ -611,12 +611,20 @@ public final class Utils implements Constants, TwitterConstants {
final ListAdapter adapter = view.getAdapter();
if (adapter == null) return;
view.clearChoices();
view.setChoiceMode(AbsListView.CHOICE_MODE_NONE);
for (int i = 0, j = view.getChildCount(); i < j; i++) {
view.setItemChecked(i, false);
}
view.post(new Runnable() {
@Override
public void run() {
view.setChoiceMode(AbsListView.CHOICE_MODE_NONE);
}
});
// Workaround for Android bug
// http://stackoverflow.com/questions/9754170/listview-selection-remains-persistent-after-exiting-choice-mode
final int position = view.getFirstVisiblePosition(), offset = Utils.getFirstChildOffset(view);
view.setAdapter(adapter);
Utils.scrollListToPosition(view, position, offset);
// final int position = view.getFirstVisiblePosition(), offset = Utils.getFirstChildOffset(view);
// view.setAdapter(adapter);
// Utils.scrollListToPosition(view, position, offset);
}
public static void clearListViewChoices(final StaggeredGridView view) {
@ -1701,7 +1709,11 @@ public final class Utils implements Constants, TwitterConstants {
public static int getFirstChildOffset(final AbsListView list) {
if (list == null || list.getChildCount() == 0) return 0;
return list.getChildAt(0).getTop();
final View child = list.getChildAt(0);
final int[] location = new int[2];
child.getLocationOnScreen(location);
Log.d(LOGTAG, String.format("getFirstChildOffset %d vs %d", child.getTop(), location[1]));
return child.getTop();
}
public static HttpClientWrapper getHttpClient(final Context context, final int timeoutMillis,

View File

@ -60,8 +60,7 @@ public class HomeSlidingMenu extends SlidingMenu {
@Override
protected boolean fitSystemWindows(Rect insets) {
setPadding(insets.left, insets.top, insets.right, insets.bottom);
return super.fitSystemWindows(insets);
return false;
}
private ViewPager getViewPager() {

View File

@ -1,395 +0,0 @@
/*
* Copyright (C) 2011 The Android Open Source Project
* Copyright (C) 2011 Jake Wharton
* Copyright (C) 2012 Mariotaku Lee
*
* 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 org.mariotaku.twidere.view;
import android.content.Context;
import android.graphics.PorterDuff.Mode;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.InputDevice;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.view.iface.PagerIndicator;
/**
* This widget implements the dynamic action bar tab behavior that can change
* across different configurations or circumstances.
*/
public class TabPageIndicator2 extends HorizontalScrollView implements PagerIndicator {
private Runnable mTabSelector;
private int mCurrentItem;
private TabProvider mTabProvider;
private TabListener mTabListener;
private final LinearLayout mTabLayout;
private ViewPager mViewPager;
private ViewPager.OnPageChangeListener mPageListener;
private final LayoutInflater mInflater;
private final boolean mShouldApplyColorFilterToTabIcons;
private final int mTabIconColor;
int mMaxTabWidth;
private int mSelectedTabIndex;
private final int mTabHighlightColor;
private boolean mSwitchingEnabled = true;
private boolean mDisplayLabel, mDisplayIcon = true;
private final OnClickListener mTabClickListener = new OnClickListener() {
@Override
public void onClick(final View view) {
if (!mSwitchingEnabled) return;
final TabView tabView = (TabView) view;
if (mCurrentItem == tabView.getIndex() && mTabListener != null) {
mTabListener.onPageReselected(mCurrentItem);
}
mCurrentItem = tabView.getIndex();
setCurrentItem(mCurrentItem);
}
};
private final OnLongClickListener mTabLongClickListener = new OnLongClickListener() {
@Override
public boolean onLongClick(final View view) {
if (!mSwitchingEnabled) return false;
final TabView tabView = (TabView) view;
return mTabListener != null && mTabListener.onTabLongClick(tabView.getIndex());
}
};
public TabPageIndicator2(final Context context) {
this(context, null);
}
public TabPageIndicator2(final Context context, final AttributeSet attrs) {
super(context, attrs);
setHorizontalScrollBarEnabled(false);
mShouldApplyColorFilterToTabIcons = ThemeUtils.shouldApplyColorFilterToActionIcons(context);
mTabHighlightColor = isInEditMode() ? 0 : ThemeUtils.getUserThemeColor(context);
mTabIconColor = isInEditMode() ? 0 : ThemeUtils.getActionIconColor(context);
mInflater = LayoutInflater.from(context);
mTabLayout = new LinearLayout(context);
mTabLayout.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE);
addView(mTabLayout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.MATCH_PARENT));
}
public int getTabCount() {
return mTabLayout.getChildCount();
}
public View getTabItem(final int position) {
return mTabLayout.getChildAt(position);
}
public ViewGroup getTabLayout() {
return mTabLayout;
}
@Override
public void notifyDataSetChanged() {
if (mTabLayout == null || mViewPager == null) return;
mTabLayout.removeAllViews();
final PagerAdapter adapter = mViewPager.getAdapter();
mTabProvider = adapter instanceof TabProvider ? (TabProvider) adapter : null;
mTabListener = adapter instanceof TabListener ? (TabListener) adapter : null;
if (mTabProvider == null) return;
final int count = adapter.getCount();
for (int i = 0; i < count; i++) {
final CharSequence title = mTabProvider.getPageTitle(i);
final Drawable icon = mTabProvider.getPageIcon(i);
if (title != null && icon != null) {
addTab(title, icon, i);
} else if (title == null && icon != null) {
addTab(null, icon, i);
} else if (title != null && icon == null) {
addTab(title, null, i);
}
}
if (mSelectedTabIndex > count) {
mSelectedTabIndex = count - 1;
}
setCurrentItem(mSelectedTabIndex);
requestLayout();
}
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
if (mTabSelector != null) {
// Re-post the selector we saved
post(mTabSelector);
}
}
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (mTabSelector != null) {
removeCallbacks(mTabSelector);
}
}
@Override
public boolean onGenericMotionEvent(final MotionEvent event) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR1) return false;
if (mTabProvider == null) return false;
if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
switch (event.getAction()) {
case MotionEvent.ACTION_SCROLL: {
final float vscroll = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
if (vscroll < 0) {
if (mCurrentItem + 1 < mTabProvider.getCount()) {
setCurrentItem(mCurrentItem + 1);
}
} else if (vscroll > 0) {
if (mCurrentItem - 1 >= 0) {
setCurrentItem(mCurrentItem - 1);
}
}
}
}
}
return true;
}
@Override
public void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
final boolean lockedExpanded = widthMode == MeasureSpec.EXACTLY;
setFillViewport(lockedExpanded);
final int childCount = mTabLayout.getChildCount();
if (childCount > 1 && (widthMode == MeasureSpec.EXACTLY || widthMode == MeasureSpec.AT_MOST)) {
if (childCount > 2) {
mMaxTabWidth = (int) (MeasureSpec.getSize(widthMeasureSpec) * 0.4f);
} else {
mMaxTabWidth = MeasureSpec.getSize(widthMeasureSpec) / 2;
}
} else {
mMaxTabWidth = -1;
}
final int oldWidth = getMeasuredWidth();
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
final int newWidth = getMeasuredWidth();
if (lockedExpanded && oldWidth != newWidth) {
// Recenter the tab display if we're at a new (scrollable) size.
setCurrentItem(mSelectedTabIndex);
}
}
@Override
public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) {
if (mPageListener != null) {
mPageListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
}
@Override
public void onPageScrollStateChanged(final int state) {
if (mPageListener != null) {
mPageListener.onPageScrollStateChanged(state);
}
}
@Override
public void onPageSelected(final int position) {
setCurrentItem(position);
if (mTabListener != null) {
mTabListener.onPageSelected(position);
}
if (mPageListener != null) {
mPageListener.onPageSelected(position);
}
}
@Override
public void setCurrentItem(final int item) {
if (mViewPager == null) return;
// throw new IllegalStateException("ViewPager has not been bound.");
mCurrentItem = item;
mViewPager.setCurrentItem(item);
mSelectedTabIndex = item;
final int tabCount = mTabLayout.getChildCount();
for (int i = 0; i < tabCount; i++) {
final View child = mTabLayout.getChildAt(i);
final boolean isSelected = i == item;
child.setSelected(isSelected);
if (isSelected) {
animateToTab(item);
}
}
}
public void setDisplayIcon(final boolean display) {
mDisplayIcon = display;
notifyDataSetChanged();
}
public void setDisplayLabel(final boolean display) {
mDisplayLabel = display;
notifyDataSetChanged();
}
@Override
public void setEnabled(final boolean enabled) {
super.setEnabled(enabled);
setAlpha(enabled ? 1 : 0.5f);
}
@Override
public void setOnPageChangeListener(final ViewPager.OnPageChangeListener listener) {
mPageListener = listener;
}
public void setSwitchingEnabled(final boolean enabled) {
if (!(mViewPager instanceof ViewPager))
throw new IllegalStateException(
"This method should only called when your ViewPager instance is ExtendedViewPager");
mSwitchingEnabled = enabled;
}
@Override
public void setViewPager(final ViewPager pager) {
final PagerAdapter adapter = pager.getAdapter();
if (adapter == null) return;
// throw new IllegalStateException("ViewPager has not been bound.");
if (!(adapter instanceof TabProvider))
throw new IllegalStateException(
"ViewPager adapter must implement TitleProvider to be used with TitlePageIndicator.");
mViewPager = pager;
pager.setOnPageChangeListener(this);
notifyDataSetChanged();
}
@Override
public void setViewPager(final ViewPager pager, final int initialPosition) {
setViewPager(pager);
setCurrentItem(initialPosition);
}
private void addTab(final CharSequence label, final Drawable icon, final int index) {
// Workaround for not being able to pass a defStyle on pre-3.0
final TabView tabView = (TabView) mInflater.inflate(R.layout.tab_item_vpi, null);
tabView.init(this, mDisplayLabel ? label : null, mDisplayIcon ? icon : null, index);
tabView.setFocusable(true);
tabView.setOnClickListener(mTabClickListener);
tabView.setOnLongClickListener(mTabLongClickListener);
tabView.setContentDescription(label);
mTabLayout.addView(tabView, new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1));
if (ThemeUtils.shouldApplyColorFilter(getContext())) {
ThemeUtils.applyBackground(tabView, mTabHighlightColor);
}
}
private void animateToTab(final int position) {
final View tabView = mTabLayout.getChildAt(position);
if (mTabSelector != null) {
removeCallbacks(mTabSelector);
}
mTabSelector = new Runnable() {
@Override
public void run() {
final int scrollPos = tabView.getLeft() - (getWidth() - tabView.getWidth()) / 2;
smoothScrollTo(scrollPos, 0);
mTabSelector = null;
}
};
post(mTabSelector);
}
private int getTabIconColor() {
return mTabIconColor;
}
private boolean shouldApplyColorFilterToTabIcons() {
return mShouldApplyColorFilterToTabIcons;
}
public static class TabView extends FrameLayout {
private TabPageIndicator2 mParent;
private int mIndex;
public TabView(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
public int getIndex() {
return mIndex;
}
public void init(final TabPageIndicator2 parent, final CharSequence label, final Drawable icon, final int index) {
if (isInEditMode()) return;
mParent = parent;
mIndex = index;
final ImageView imageView = (ImageView) findViewById(R.id.tab_item_icon);
imageView.setVisibility(icon != null ? View.VISIBLE : View.GONE);
imageView.setImageDrawable(icon);
if (parent.shouldApplyColorFilterToTabIcons()) {
imageView.setColorFilter(parent.getTabIconColor(), Mode.SRC_ATOP);
}
final TextView textView = (TextView) findViewById(R.id.tab_item_title);
textView.setVisibility(TextUtils.isEmpty(label) ? View.GONE : View.VISIBLE);
textView.setText(label);
}
public void init(final TabPageIndicator2 parent, final CharSequence text, final int index) {
init(parent, text, null, index);
}
public void init(final TabPageIndicator2 parent, final Drawable icon, final int index) {
init(parent, null, icon, index);
}
@Override
public void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// Re-measure if we went beyond our maximum size.
if (!isInEditMode() && mParent.mMaxTabWidth > 0 && getMeasuredWidth() > mParent.mMaxTabWidth) {
super.onMeasure(MeasureSpec.makeMeasureSpec(mParent.mMaxTabWidth, MeasureSpec.EXACTLY),
heightMeasureSpec);
}
}
}
}

View File

@ -21,17 +21,20 @@ import org.mariotaku.twidere.view.iface.PagerIndicator;
*/
public class TabPagerIndicator extends RecyclerView implements PagerIndicator {
private final TabPagerIndicatorAdapter mAdapter;
private final int mStripHeight;
private PagerAdapter mTabProvider;
private ViewPager mViewPager;
private final TabPagerIndicatorAdapter mIndicatorAdapter;
private PagerAdapter mPagerProvider;
private OnPageChangeListener mPageChangeListener;
public TabPagerIndicator(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setLayoutManager(new TabLayoutManager(this));
mAdapter = new TabPagerIndicatorAdapter(this);
setAdapter(mAdapter);
mIndicatorAdapter = new TabPagerIndicatorAdapter(this);
setAdapter(mIndicatorAdapter);
mStripHeight = getResources().getDimensionPixelSize(R.dimen.element_spacing_small);
}
@ -45,7 +48,7 @@ public class TabPagerIndicator extends RecyclerView implements PagerIndicator {
@Override
public void notifyDataSetChanged() {
mAdapter.notifyDataSetChanged();
mIndicatorAdapter.notifyDataSetChanged();
}
@Override
@ -70,8 +73,9 @@ public class TabPagerIndicator extends RecyclerView implements PagerIndicator {
throw new IllegalArgumentException();
}
mViewPager = view;
mPagerProvider = adapter;
view.setOnPageChangeListener(this);
mAdapter.setTabProvider((TabProvider) adapter);
mIndicatorAdapter.setTabProvider((TabProvider) adapter);
}
@Override
@ -82,7 +86,7 @@ public class TabPagerIndicator extends RecyclerView implements PagerIndicator {
@Override
public void onPageSelected(int position) {
mAdapter.notifyDataSetChanged();
mIndicatorAdapter.notifyDataSetChanged();
if (mPageChangeListener == null) return;
mPageChangeListener.onPageSelected(position);
}
@ -94,7 +98,7 @@ public class TabPagerIndicator extends RecyclerView implements PagerIndicator {
}
public int getCount() {
return mAdapter.getItemCount();
return mIndicatorAdapter.getItemCount();
}
public void setBadge(int position, int count) {
@ -171,10 +175,21 @@ public class TabPagerIndicator extends RecyclerView implements PagerIndicator {
}
private void dispatchTabClick(int position) {
final int currentItem = getCurrentItem();
setCurrentItem(position);
if (mPagerProvider instanceof TabListener) {
if (currentItem != position) {
((TabListener) mPagerProvider).onPageSelected(position);
} else {
((TabListener) mPagerProvider).onPageReselected(position);
}
}
}
private boolean dispatchTabLongClick(int position) {
if (mPagerProvider instanceof TabListener) {
return ((TabListener) mPagerProvider).onTabLongClick(position);
}
return false;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -1,29 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tab_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="horizontal">
<view
android:id="@android:id/tabs"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="left"
class="org.mariotaku.twidere.view.TabPageIndicator2"/>
</LinearLayout>
<org.mariotaku.twidere.view.HomeActionsActionView
android:id="@+id/actions_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="0"/>
</LinearLayout>

View File

@ -1,40 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/* //device/apps/common/assets/res/layout/tab_content.xml
**
** Copyright 2011, The Android Open Source Project
**
** 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.
*/
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tab_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<org.mariotaku.twidere.view.TabPageIndicator2
android:id="@android:id/tabs"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"/>
<org.mariotaku.twidere.view.HomeActionsActionView
android:id="@+id/actions_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="0"/>
</LinearLayout>

View File

@ -1,31 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<view xmlns:android="http://schemas.android.com/apk/res/android"
style="?tabItemStyle"
android:layout_width="wrap_content"
android:layout_height="match_parent"
class="org.mariotaku.twidere.view.TabPageIndicator2$TabView">
<LinearLayout
android:id="@+id/tab_item_content"
style="?tabItemContentStyle"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center">
<ImageView
android:id="@+id/tab_item_icon"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:contentDescription="@string/icon"
android:scaleType="centerInside"/>
<TextView
android:id="@+id/tab_item_title"
style="?attr/tabItemTextStyle"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"/>
</LinearLayout>
</view>

View File

@ -26,7 +26,7 @@
<dimen name="accounts_drawer_default_indicator_size">12sp</dimen>
<dimen name="accounts_drawer_switch_label_size">16sp</dimen>
<dimen name="accounts_drawer_child_size">16sp</dimen>
<dimen name="home_actions_button_size">56dp</dimen>
<dimen name="home_actions_button_size">64dp</dimen>
<dimen name="action_button_size">56dp</dimen>
<dimen name="text_size_extra_small">12sp</dimen>

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="Theme" />
<style name="Theme"/>
<style name="Theme.Launcher" parent="android:Theme.NoDisplay" />
<style name="Theme.Launcher" parent="android:Theme.NoDisplay"/>
<style name="Theme.Blank" parent="android:Theme.DeviceDefault.NoActionBar">
@ -12,7 +12,7 @@
<item name="android:windowBackground">@android:color/black</item>
</style>
<style name="Theme.Blank.Dialog" parent="android:Theme.DeviceDefault.Dialog" />
<style name="Theme.Blank.Dialog" parent="android:Theme.DeviceDefault.Dialog"/>
<style name="Theme.Twidere.Dark" parent="android:Theme.DeviceDefault">
@ -23,6 +23,7 @@
<item name="android:windowAnimationStyle">@style/Animation.Twidere.Activity</item>
<item name="android:windowBackground">@color/bg_color_dark</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowActionModeOverlay">true</item>
<!-- ActionBar styles -->
<item name="android:actionBarStyle">@style/Widget.Twidere.ActionBar.Dark</item>
@ -63,6 +64,7 @@
<item name="android:windowAnimationStyle">@style/Animation.Twidere.Activity</item>
<item name="android:windowBackground">@color/bg_color_light</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowActionModeOverlay">true</item>
<!-- ActionBar styles -->
<item name="android:actionBarStyle">@style/Widget.Twidere.ActionBar.Light</item>
@ -103,6 +105,7 @@
<item name="android:windowAnimationStyle">@style/Animation.Twidere.Activity</item>
<item name="android:windowBackground">@color/bg_color_light</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowActionModeOverlay">true</item>
<!-- ActionBar styles -->
<item name="android:actionBarStyle">@style/Widget.Twidere.ActionBar.Light.DarkActionBar
@ -137,7 +140,7 @@
<item name="cardItemViewStyle">@style/Widget.CardItemView.Light</item>
</style>
<style name="Theme.Twidere.Light.DarkActionBar.DarkIcon" />
<style name="Theme.Twidere.Light.DarkActionBar.DarkIcon"/>
<style name="Theme.Twidere.Colored" parent="Theme.Twidere.Light">
@ -156,7 +159,7 @@
<!--<item name="android:actionBarItemBackground">@drawable/list_selector_white</item>-->
</style>
<style name="Theme.Twidere.Colored.DarkActionBar.DarkIcon" />
<style name="Theme.Twidere.Colored.DarkActionBar.DarkIcon"/>
<style name="Theme.Twidere.Colored.DarkActionBar.Transparent">
@ -169,7 +172,7 @@
<item name="android:windowShowWallpaper">true</item>
</style>
<style name="Theme.Twidere.Colored.DarkActionBar.Transparent.DarkIcon" />
<style name="Theme.Twidere.Colored.DarkActionBar.Transparent.DarkIcon"/>
<style name="Theme.Twidere.Colored.Transparent">
@ -212,7 +215,7 @@
<item name="android:windowShowWallpaper">true</item>
</style>
<style name="Theme.Twidere.Light.DarkActionBar.Transparent.DarkIcon" />
<style name="Theme.Twidere.Light.DarkActionBar.Transparent.DarkIcon"/>
<style name="Theme.Twidere.Colored.DarkActionBar.SolidBackground">
@ -220,7 +223,7 @@
<item name="android:windowBackground">@android:color/white</item>
</style>
<style name="Theme.Twidere.Colored.DarkActionBar.SolidBackground.DarkIcon" />
<style name="Theme.Twidere.Colored.DarkActionBar.SolidBackground.DarkIcon"/>
<style name="Theme.Twidere.Colored.SolidBackground">
@ -246,7 +249,7 @@
<item name="android:windowBackground">@android:color/white</item>
</style>
<style name="Theme.Twidere.Light.DarkActionBar.SolidBackground.DarkIcon" />
<style name="Theme.Twidere.Light.DarkActionBar.SolidBackground.DarkIcon"/>
<style name="Theme.Twidere.ActionBar.Colored.Light" parent="Theme.Twidere.Light">
<!--<item name="android:actionBarItemBackground">@drawable/list_selector_white_light</item>-->
@ -351,7 +354,7 @@
<item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
</style>
<style name="Theme.Twidere.Light.DarkActionBar.Compose.DarkIcon" />
<style name="Theme.Twidere.Light.DarkActionBar.Compose.DarkIcon"/>
<style name="Theme.Twidere.Colored.DarkActionBar.Compose">
<item name="android:windowNoTitle">true</item>
@ -366,7 +369,7 @@
<item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
</style>
<style name="Theme.Twidere.Colored.DarkActionBar.Compose.DarkIcon" />
<style name="Theme.Twidere.Colored.DarkActionBar.Compose.DarkIcon"/>
<style name="Theme.Twidere.Colored.Compose">
<item name="android:windowNoTitle">true</item>
@ -385,6 +388,7 @@
<!-- Window attributes -->
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowActionModeOverlay">true</item>
<item name="android:windowAnimationStyle">@style/Animation.Twidere.Activity</item>
<item name="android:windowBackground">@android:color/black</item>
@ -461,7 +465,7 @@
<item name="android:windowNoDisplay">true</item>
</style>
<style name="Theme.Test" parent="android:Theme.DeviceDefault" />
<style name="Theme.Test" parent="android:Theme.DeviceDefault"/>
<style name="Theme.Nyan" parent="android:Theme.DeviceDefault.NoActionBar">
<item name="android:windowBackground">@color/nyan_background</item>
@ -572,7 +576,7 @@
<item name="cardItemViewStyle">@style/Widget.CardItemView.Light</item>
</style>
<style name="Theme.Twidere.Settings.Light.DarkActionBar.DarkIcon" />
<style name="Theme.Twidere.Settings.Light.DarkActionBar.DarkIcon"/>
<style name="Theme.Twidere.Wizard" parent="Theme.Twidere.Settings.Light">
<item name="android:windowNoTitle">true</item>