1
0
mirror of https://github.com/TwidereProject/Twidere-Android synced 2025-02-16 19:50:53 +01:00

improved action bar quick return

This commit is contained in:
Mariotaku Lee 2014-10-24 17:32:02 +08:00
parent 84534f577c
commit 7baf4c95af
38 changed files with 891 additions and 426 deletions

View File

@ -40,7 +40,7 @@ public class BaseActivity extends BaseThemedActivity implements Constants {
}
@Override
public int getOverrideAccentColor() {
public int getThemeColor() {
return ThemeUtils.getUserThemeColor(this);
}

View File

@ -98,7 +98,7 @@ public abstract class BasePreferenceActivity extends PreferenceActivity implemen
}
@Override
public int getOverrideAccentColor() {
public int getThemeColor() {
return 0;
}

View File

@ -99,7 +99,7 @@ public abstract class BaseThemedActivity extends Activity implements IThemedActi
}
@Override
public abstract int getOverrideAccentColor();
public abstract int getThemeColor();
@Override
public String getThemeFontFamily() {
@ -140,7 +140,7 @@ public abstract class BaseThemedActivity extends Activity implements IThemedActi
}
protected final boolean isThemeChanged() {
return getThemeResourceId() != mCurrentThemeResource || getOverrideAccentColor() != mCurrentThemeColor
return getThemeResourceId() != mCurrentThemeResource || getThemeColor() != mCurrentThemeColor
|| !CompareUtils.objectEquals(getThemeFontFamily(), mCurrentThemeFontFamily)
|| getThemeBackgroundAlpha() != mCurrentThemeBackgroundAlpha;
}
@ -178,7 +178,7 @@ public abstract class BaseThemedActivity extends Activity implements IThemedActi
private final void setTheme() {
mCurrentThemeResource = getThemeResourceId();
mCurrentThemeColor = getOverrideAccentColor();
mCurrentThemeColor = getThemeColor();
mCurrentThemeFontFamily = getThemeFontFamily();
mCurrentThemeBackgroundAlpha = getThemeBackgroundAlpha();
ThemeUtils.notifyStatusBarColorChanged(this, mCurrentThemeResource, mCurrentThemeColor,

View File

@ -11,4 +11,16 @@ public interface IControlBarActivity {
public int getControlBarHeight();
public void moveControlBarBy(float delta);
public void notifyControlBarOffsetChanged();
public void registerControlBarOffsetListener(ControlBarOffsetListener listener);
public void unregisterControlBarOffsetListener(ControlBarOffsetListener listener);
public interface ControlBarOffsetListener {
public void onControlBarOffsetChanged(IControlBarActivity activity, float offset);
}
}

View File

@ -33,7 +33,7 @@ public interface IThemedActivity extends ITwidereContextWrapper {
public int getThemeBackgroundAlpha();
public int getOverrideAccentColor();
public int getThemeColor();
public TwidereMenuInflater getTwidereMenuInflater();

View File

@ -26,6 +26,7 @@ import android.os.Bundle;
import android.view.MenuItem;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.activity.iface.IControlBarActivity;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback;
import org.mariotaku.twidere.fragment.iface.IBasePullToRefreshFragment;
@ -34,20 +35,23 @@ import org.mariotaku.twidere.util.MessagesManager;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.view.MainFrameLayout.FitSystemWindowsCallback;
import java.util.ArrayList;
@SuppressLint("Registered")
public class BaseSupportActivity extends BaseSupportThemedActivity implements Constants,
FitSystemWindowsCallback, SystemWindowsInsetsCallback {
FitSystemWindowsCallback, SystemWindowsInsetsCallback, IControlBarActivity {
private boolean mInstanceStateSaved, mIsVisible, mIsOnTop;
private Rect mSystemWindowsInsets;
private ArrayList<ControlBarOffsetListener> mControlBarOffsetListeners = new ArrayList<>();
public MessagesManager getMessagesManager() {
return getTwidereApplication() != null ? getTwidereApplication().getMessagesManager() : null;
}
@Override
public int getOverrideAccentColor() {
public int getThemeColor() {
return ThemeUtils.getUserThemeColor(this, getThemeResourceId());
}
@ -157,4 +161,42 @@ public class BaseSupportActivity extends BaseSupportThemedActivity implements Co
public void fitSystemWindows(Rect insets) {
mSystemWindowsInsets = new Rect(insets);
}
@Override
public void setControlBarOffset(float offset) {
}
@Override
public float getControlBarOffset() {
return 0;
}
@Override
public int getControlBarHeight() {
return 0;
}
@Override
public void moveControlBarBy(float delta) {
}
@Override
public void notifyControlBarOffsetChanged() {
final float offset = getControlBarOffset();
for (final ControlBarOffsetListener l : mControlBarOffsetListeners) {
l.onControlBarOffsetChanged(this, offset);
}
}
@Override
public void registerControlBarOffsetListener(ControlBarOffsetListener listener) {
mControlBarOffsetListeners.add(listener);
}
@Override
public void unregisterControlBarOffsetListener(ControlBarOffsetListener listener) {
mControlBarOffsetListeners.remove(listener);
}
}

View File

@ -36,7 +36,7 @@ public class BaseSupportDialogActivity extends BaseSupportThemedActivity impleme
private boolean mInstanceStateSaved;
@Override
public int getOverrideAccentColor() {
public int getThemeColor() {
return ThemeUtils.getThemeColor(this, getThemeResourceId());
}

View File

@ -82,7 +82,7 @@ public abstract class BaseSupportThemedActivity extends FragmentActivity impleme
}
@Override
public abstract int getOverrideAccentColor();
public abstract int getThemeColor();
@Override
@ -138,11 +138,14 @@ public abstract class BaseSupportThemedActivity extends FragmentActivity impleme
setActionBarBackground();
}
@Override
protected void onStart() {
super.onStart();
}
@Override
protected void onResume() {
super.onResume();
ThemeUtils.notifyStatusBarColorChanged(this, mCurrentThemeResource, mCurrentThemeColor,
mCurrentThemeBackgroundAlpha);
}
protected boolean shouldSetWindowBackground() {
@ -155,7 +158,7 @@ public abstract class BaseSupportThemedActivity extends FragmentActivity impleme
private final void setTheme() {
mCurrentThemeResource = getThemeResourceId();
mCurrentThemeColor = getOverrideAccentColor();
mCurrentThemeColor = getThemeColor();
mCurrentThemeBackgroundAlpha = getThemeBackgroundAlpha();
ThemeUtils.notifyStatusBarColorChanged(this, mCurrentThemeResource, mCurrentThemeColor,
mCurrentThemeBackgroundAlpha);

View File

@ -217,7 +217,7 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa
}
@Override
public int getOverrideAccentColor() {
public int getThemeColor() {
return ThemeUtils.getUserThemeColor(this);
}

View File

@ -33,6 +33,7 @@ import android.content.pm.ActivityInfo;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.Uri;
@ -52,6 +53,8 @@ import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.MarginLayoutParams;
import android.view.Window;
import android.widget.FrameLayout;
import android.widget.FrameLayout.LayoutParams;
@ -64,7 +67,6 @@ import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu.CanvasTransformer;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.DataProfilingSettingsActivity;
import org.mariotaku.twidere.activity.SettingsWizardActivity;
import org.mariotaku.twidere.activity.iface.IControlBarActivity;
import org.mariotaku.twidere.adapter.support.SupportTabsAdapter;
import org.mariotaku.twidere.fragment.iface.IBaseFragment;
import org.mariotaku.twidere.fragment.iface.IBasePullToRefreshFragment;
@ -90,11 +92,11 @@ import org.mariotaku.twidere.util.UnreadCountUtils;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.util.accessor.ViewAccessor;
import org.mariotaku.twidere.view.ExtendedViewPager;
import org.mariotaku.twidere.view.HomeActionsActionView;
import org.mariotaku.twidere.view.HomeSlidingMenu;
import org.mariotaku.twidere.view.LeftDrawerFrameLayout;
import org.mariotaku.twidere.view.RightDrawerFrameLayout;
import org.mariotaku.twidere.view.TabPagerIndicator;
import org.mariotaku.twidere.view.iface.IHomeActionButton;
import java.util.ArrayList;
import java.util.List;
@ -116,7 +118,7 @@ import static org.mariotaku.twidere.util.Utils.showMenuItemToast;
public class HomeActivity extends BaseSupportActivity implements OnClickListener, OnPageChangeListener,
SupportFragmentCallback, SlidingMenu.OnOpenedListener, SlidingMenu.OnClosedListener,
OnLongClickListener, IControlBarActivity {
OnLongClickListener {
private final BroadcastReceiver mStateReceiver = new BroadcastReceiver() {
@ -159,7 +161,9 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
private HomeSlidingMenu mSlidingMenu;
private View mEmptyTabHint;
private ProgressBar mSmartBarProgress;
private HomeActionsActionView mActionsButton;
private View mActionsButton;
private View mTabsContainer;
private View mActionBarOverlay;
private LeftDrawerFrameLayout mLeftDrawerContainer;
private RightDrawerFrameLayout mRightDrawerContainer;
@ -189,8 +193,9 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
@Override
public void setControlBarOffset(float offset) {
mTabIndicator.setTranslationY(getControlBarHeight() * (offset - 1));
mTabsContainer.setTranslationY(getControlBarHeight() * (offset - 1));
mActionsButton.setTranslationY(mActionsButton.getHeight() * (1 - offset));
notifyControlBarOffsetChanged();
}
public void notifyAccountsChanged() {
@ -243,8 +248,10 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
mSlidingMenu = (HomeSlidingMenu) findViewById(R.id.home_menu);
mViewPager = (ExtendedViewPager) findViewById(R.id.main_pager);
mEmptyTabHint = findViewById(R.id.empty_tab_hint);
mActionsButton = (HomeActionsActionView) findViewById(R.id.actions_button_bottom);
mTabIndicator = (TabPagerIndicator) findViewById(android.R.id.tabs);
mActionsButton = findViewById(R.id.actions_button_bottom);
mTabsContainer = findViewById(R.id.tabs_container);
mTabIndicator = (TabPagerIndicator) findViewById(R.id.main_tabs);
mActionBarOverlay = findViewById(R.id.actionbar_overlay);
}
@Override
@ -438,7 +445,7 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
@Override
public float getControlBarOffset() {
final float totalHeight = getControlBarHeight();
return 1 + mTabIndicator.getTranslationY() / totalHeight;
return 1 + mTabsContainer.getTranslationY() / totalHeight;
}
@Override
@ -564,6 +571,21 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
}
}
mPagerPosition = Float.NaN;
final int themeColor = getThemeColor(), contrastColor = Utils.getContrastYIQ(themeColor, 192);
final int themeResId = getCurrentThemeResourceId();
if (ThemeUtils.isColoredActionBar(themeResId)) {
mTabIndicator.setBackgroundColor(themeColor);
mTabIndicator.setStripColor(contrastColor);
mTabIndicator.setIconColor(contrastColor);
} else {
ViewAccessor.setBackground(mTabIndicator, ThemeUtils.getActionBarBackground(this, themeResId));
mTabIndicator.setStripColor(themeColor);
mTabIndicator.setIconColor(ThemeUtils.isLightActionBar(themeResId) ? Color.BLACK : Color.WHITE);
}
if (mActionsButton instanceof IHomeActionButton) {
((IHomeActionButton) mActionsButton).setColor(themeColor);
}
ViewAccessor.setBackground(mActionBarOverlay, ThemeUtils.getWindowContentOverlay(this));
}
@Override
@ -825,10 +847,11 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
}
}
final boolean hasActivatedTask = hasActivatedTask();
if (mActionsButton != null) {
mActionsButton.setIcon(icon);
mActionsButton.setTitle(title);
mActionsButton.setShowProgress(hasActivatedTask);
if (mActionsButton instanceof IHomeActionButton) {
final IHomeActionButton hab = (IHomeActionButton) mActionsButton;
hab.setIcon(icon);
hab.setTitle(title);
hab.setShowProgress(hasActivatedTask);
}
if (mSmartBarProgress != null) {
mSmartBarProgress.setVisibility(hasActivatedTask ? View.VISIBLE : View.INVISIBLE);
@ -865,10 +888,19 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
}
}
public void moveControlBarBy(int delta) {
public void moveControlBarBy(float delta) {
final int min = -getControlBarHeight(), max = 0;
mTabIndicator.setTranslationY(MathUtils.clamp(mTabIndicator.getTranslationY() + delta, max, min));
mActionsButton.setTranslationY(MathUtils.clamp(mActionsButton.getTranslationY() - delta, mActionsButton.getHeight(), 0));
mTabsContainer.setTranslationY(MathUtils.clamp(mTabsContainer.getTranslationY() + delta, max, min));
final ViewGroup.LayoutParams ablp = mActionsButton.getLayoutParams();
final int totalHeight;
if (ablp instanceof MarginLayoutParams) {
final MarginLayoutParams mlp = (MarginLayoutParams) ablp;
totalHeight = mActionsButton.getHeight() + mlp.topMargin + mlp.bottomMargin;
} else {
totalHeight = mActionsButton.getHeight();
}
mActionsButton.setTranslationY(MathUtils.clamp(mActionsButton.getTranslationY() - delta, totalHeight, 0));
notifyControlBarOffsetChanged();
}
@ -919,9 +951,9 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
@Override
protected int[] doInBackground(final Void... params) {
final int tab_count = mIndicator.getCount();
final int[] result = new int[tab_count];
for (int i = 0, j = tab_count; i < j; i++) {
final int tabCount = mIndicator.getCount();
final int[] result = new int[tabCount];
for (int i = 0, j = tabCount; i < j; i++) {
result[i] = UnreadCountUtils.getUnreadCount(mContext, i);
}
return result;

View File

@ -45,7 +45,7 @@ public class ImagePickerActivity extends BaseSupportThemedActivity {
private Runnable mImageSelectedRunnable;
@Override
public int getOverrideAccentColor() {
public int getThemeColor() {
return 0;
}

View File

@ -19,13 +19,10 @@
package org.mariotaku.twidere.activity.support;
import static android.text.TextUtils.isEmpty;
import static org.mariotaku.twidere.util.Utils.createFragmentForIntent;
import static org.mariotaku.twidere.util.Utils.matchLinkId;
import android.app.ActionBar;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
@ -36,250 +33,266 @@ import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.Window;
import android.widget.TextView;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.iface.IControlBarActivity;
import org.mariotaku.twidere.fragment.iface.IBaseFragment;
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback;
import org.mariotaku.twidere.fragment.iface.IBasePullToRefreshFragment;
import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface;
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback;
import org.mariotaku.twidere.util.FlymeUtils;
import org.mariotaku.twidere.util.MultiSelectEventHandler;
public class LinkHandlerActivity extends BaseSupportActivity implements OnClickListener, OnLongClickListener {
import static org.mariotaku.twidere.util.Utils.createFragmentForIntent;
import static org.mariotaku.twidere.util.Utils.matchLinkId;
private MultiSelectEventHandler mMultiSelectHandler;
public class LinkHandlerActivity extends BaseSupportActivity implements OnClickListener,
OnLongClickListener, SystemWindowsInsetsCallback, IControlBarActivity {
private ActionBar mActionBar;
private MultiSelectEventHandler mMultiSelectHandler;
private boolean mFinishOnly;
private boolean mFinishOnly;
private View mGoTopView;
private TextView mTitleView, mSubtitleView;
@Override
public void onClick(final View v) {
switch (v.getId()) {
case R.id.go_top: {
final Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.content_fragment);
if (fragment instanceof RefreshScrollTopInterface) {
((RefreshScrollTopInterface) fragment).scrollToStart();
} else if (fragment instanceof ListFragment) {
((ListFragment) fragment).setSelection(0);
}
break;
}
}
}
@Override
public void onClick(final View v) {
switch (v.getId()) {
case R.id.go_top: {
final Fragment fragment = getSupportFragmentManager().findFragmentById(android.R.id.content);
if (fragment instanceof RefreshScrollTopInterface) {
((RefreshScrollTopInterface) fragment).scrollToStart();
} else if (fragment instanceof ListFragment) {
((ListFragment) fragment).setSelection(0);
}
break;
}
}
}
@Override
public boolean onLongClick(final View v) {
switch (v.getId()) {
case R.id.go_top: {
final Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.content_fragment);
if (fragment instanceof RefreshScrollTopInterface) {
((RefreshScrollTopInterface) fragment).triggerRefresh();
}
return true;
}
}
return false;
}
@Override
public boolean onLongClick(final View v) {
switch (v.getId()) {
case R.id.go_top: {
final Fragment fragment = getSupportFragmentManager().findFragmentById(android.R.id.content);
if (fragment instanceof RefreshScrollTopInterface) {
((RefreshScrollTopInterface) fragment).triggerRefresh();
}
return true;
}
}
return false;
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case MENU_HOME: {
if (mFinishOnly) {
finish();
} else {
navigateUpFromSameTask();
}
break;
}
}
return super.onOptionsItemSelected(item);
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case MENU_HOME: {
if (mFinishOnly) {
finish();
} else {
navigateUpFromSameTask();
}
break;
}
}
return super.onOptionsItemSelected(item);
}
@Override
protected IBasePullToRefreshFragment getCurrentPullToRefreshFragment() {
final Fragment fragment = getSupportFragmentManager().findFragmentById(android.R.id.content);
if (fragment instanceof IBasePullToRefreshFragment)
return (IBasePullToRefreshFragment) fragment;
else if (fragment instanceof SupportFragmentCallback) {
final Fragment curr = ((SupportFragmentCallback) fragment).getCurrentVisibleFragment();
if (curr instanceof IBasePullToRefreshFragment)
return (IBasePullToRefreshFragment) curr;
}
return null;
}
public void setSubtitle(final CharSequence subtitle) {
mSubtitleView.setVisibility(isEmpty(subtitle) ? View.GONE : View.VISIBLE);
mSubtitleView.setText(subtitle);
}
@Override
protected void onCreate(final Bundle savedInstanceState) {
mMultiSelectHandler = new MultiSelectEventHandler(this);
mMultiSelectHandler.dispatchOnCreate();
final Intent intent = getIntent();
final Uri data = intent.getData();
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setUiOptions(getWindow(), data);
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_link_handler);
setProgressBarIndeterminateVisibility(false);
if (data == null || !showFragment(data)) {
finish();
}
}
@Override
protected IBasePullToRefreshFragment getCurrentPullToRefreshFragment() {
final Fragment fragment = getSupportFragmentManager().findFragmentById(android.R.id.content);
if (fragment instanceof IBasePullToRefreshFragment)
return (IBasePullToRefreshFragment) fragment;
else if (fragment instanceof SupportFragmentCallback) {
final Fragment curr = ((SupportFragmentCallback) fragment).getCurrentVisibleFragment();
if (curr instanceof IBasePullToRefreshFragment) return (IBasePullToRefreshFragment) curr;
}
return null;
}
@Override
protected void onStart() {
super.onStart();
mMultiSelectHandler.dispatchOnStart();
}
@Override
protected void onCreate(final Bundle savedInstanceState) {
mMultiSelectHandler = new MultiSelectEventHandler(this);
mMultiSelectHandler.dispatchOnCreate();
final Intent intent = getIntent();
final Uri data = intent.getData();
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setUiOptions(getWindow(), data);
super.onCreate(savedInstanceState);
mActionBar = getActionBar();
mActionBar.setDisplayShowTitleEnabled(true);
mActionBar.setDisplayShowCustomEnabled(false);
mActionBar.setCustomView(R.layout.link_handler_actionbar);
final View view = mActionBar.getCustomView();
mGoTopView = view.findViewById(R.id.go_top);
mTitleView = (TextView) view.findViewById(R.id.actionbar_title);
mSubtitleView = (TextView) view.findViewById(R.id.actionbar_subtitle);
mGoTopView.setOnClickListener(this);
mGoTopView.setOnLongClickListener(this);
setProgressBarIndeterminateVisibility(false);
if (data == null || !showFragment(data)) {
finish();
}
}
@Override
protected void onStop() {
mMultiSelectHandler.dispatchOnStop();
super.onStop();
}
@Override
protected void onStart() {
super.onStart();
mMultiSelectHandler.dispatchOnStart();
}
@Override
public void fitSystemWindows(Rect insets) {
super.fitSystemWindows(insets);
final Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.content_fragment);
if (fragment instanceof IBaseFragment) {
((IBaseFragment) fragment).requestFitSystemWindows();
}
}
@Override
protected void onStop() {
mMultiSelectHandler.dispatchOnStop();
super.onStop();
}
@Override
protected void onTitleChanged(final CharSequence title, final int color) {
super.onTitleChanged(title, color);
}
@Override
protected void onTitleChanged(final CharSequence title, final int color) {
super.onTitleChanged(title, color);
mTitleView.setText(title);
}
private void setUiOptions(final Window window, final Uri data) {
if (FlymeUtils.hasSmartBar()) {
window.setUiOptions(ActivityInfo.UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW);
} else {
window.setUiOptions(0);
}
}
private void setUiOptions(final Window window, final Uri data) {
if (FlymeUtils.hasSmartBar()) {
window.setUiOptions(ActivityInfo.UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW);
} else {
window.setUiOptions(0);
}
}
private boolean showFragment(final Uri uri) {
final Intent intent = getIntent();
intent.setExtrasClassLoader(getClassLoader());
final Fragment fragment = createFragmentForIntent(this, intent);
if (uri == null || fragment == null) return false;
switch (matchLinkId(uri)) {
case LINK_ID_STATUS: {
setTitle(R.string.status);
break;
}
case LINK_ID_USER: {
setTitle(R.string.user);
break;
}
case LINK_ID_USER_TIMELINE: {
setTitle(R.string.statuses);
break;
}
case LINK_ID_USER_FAVORITES: {
setTitle(R.string.favorites);
break;
}
case LINK_ID_USER_FOLLOWERS: {
setTitle(R.string.followers);
break;
}
case LINK_ID_USER_FRIENDS: {
setTitle(R.string.action_following);
break;
}
case LINK_ID_USER_BLOCKS: {
setTitle(R.string.blocked_users);
break;
}
case LINK_ID_MUTES_USERS: {
setTitle(R.string.twitter_muted_users);
break;
}
case LINK_ID_DIRECT_MESSAGES_CONVERSATION: {
setTitle(R.string.direct_messages);
break;
}
case LINK_ID_USER_LIST: {
setTitle(R.string.user_list);
break;
}
case LINK_ID_USER_LISTS: {
setTitle(R.string.user_lists);
break;
}
case LINK_ID_USER_LIST_TIMELINE: {
setTitle(R.string.list_timeline);
break;
}
case LINK_ID_USER_LIST_MEMBERS: {
setTitle(R.string.list_members);
break;
}
case LINK_ID_USER_LIST_SUBSCRIBERS: {
setTitle(R.string.list_subscribers);
break;
}
case LINK_ID_USER_LIST_MEMBERSHIPS: {
setTitle(R.string.lists_following_user);
break;
}
case LINK_ID_SAVED_SEARCHES: {
setTitle(R.string.saved_searches);
break;
}
case LINK_ID_USER_MENTIONS: {
setTitle(R.string.user_mentions);
break;
}
case LINK_ID_INCOMING_FRIENDSHIPS: {
setTitle(R.string.incoming_friendships);
break;
}
case LINK_ID_USERS: {
setTitle(R.string.users);
break;
}
case LINK_ID_STATUSES: {
setTitle(R.string.statuses);
break;
}
case LINK_ID_STATUS_RETWEETERS: {
setTitle(R.string.users_retweeted_this);
break;
}
case LINK_ID_STATUS_FAVORITERS: {
setTitle(R.string.users_retweeted_this);
break;
}
case LINK_ID_STATUS_REPLIES: {
setTitle(R.string.view_replies);
break;
}
case LINK_ID_SEARCH: {
setTitle(android.R.string.search_go);
// setSubtitle(uri.getQueryParameter(QUERY_PARAM_QUERY));
break;
}
default: {
return false;
}
}
mFinishOnly = Boolean.parseBoolean(uri.getQueryParameter(QUERY_PARAM_FINISH_ONLY));
final FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_fragment, fragment);
ft.commit();
return true;
}
private boolean showFragment(final Uri uri) {
final Intent intent = getIntent();
intent.setExtrasClassLoader(getClassLoader());
final Fragment fragment = createFragmentForIntent(this, intent);
if (uri == null || fragment == null) return false;
switch (matchLinkId(uri)) {
case LINK_ID_STATUS: {
setTitle(R.string.status);
break;
}
case LINK_ID_USER: {
setTitle(R.string.user);
break;
}
case LINK_ID_USER_TIMELINE: {
setTitle(R.string.statuses);
break;
}
case LINK_ID_USER_FAVORITES: {
setTitle(R.string.favorites);
break;
}
case LINK_ID_USER_FOLLOWERS: {
setTitle(R.string.followers);
break;
}
case LINK_ID_USER_FRIENDS: {
setTitle(R.string.action_following);
break;
}
case LINK_ID_USER_BLOCKS: {
setTitle(R.string.blocked_users);
break;
}
case LINK_ID_MUTES_USERS: {
setTitle(R.string.twitter_muted_users);
break;
}
case LINK_ID_DIRECT_MESSAGES_CONVERSATION: {
setTitle(R.string.direct_messages);
break;
}
case LINK_ID_USER_LIST: {
setTitle(R.string.user_list);
break;
}
case LINK_ID_USER_LISTS: {
setTitle(R.string.user_lists);
break;
}
case LINK_ID_USER_LIST_TIMELINE: {
setTitle(R.string.list_timeline);
break;
}
case LINK_ID_USER_LIST_MEMBERS: {
setTitle(R.string.list_members);
break;
}
case LINK_ID_USER_LIST_SUBSCRIBERS: {
setTitle(R.string.list_subscribers);
break;
}
case LINK_ID_USER_LIST_MEMBERSHIPS: {
setTitle(R.string.lists_following_user);
break;
}
case LINK_ID_SAVED_SEARCHES: {
setTitle(R.string.saved_searches);
break;
}
case LINK_ID_USER_MENTIONS: {
setTitle(R.string.user_mentions);
break;
}
case LINK_ID_INCOMING_FRIENDSHIPS: {
setTitle(R.string.incoming_friendships);
break;
}
case LINK_ID_USERS: {
setTitle(R.string.users);
break;
}
case LINK_ID_STATUSES: {
setTitle(R.string.statuses);
break;
}
case LINK_ID_STATUS_RETWEETERS: {
setTitle(R.string.users_retweeted_this);
break;
}
case LINK_ID_STATUS_FAVORITERS: {
setTitle(R.string.users_retweeted_this);
break;
}
case LINK_ID_STATUS_REPLIES: {
setTitle(R.string.view_replies);
break;
}
case LINK_ID_SEARCH: {
setTitle(android.R.string.search_go);
setSubtitle(uri.getQueryParameter(QUERY_PARAM_QUERY));
break;
}
default: {
return false;
}
}
mFinishOnly = Boolean.parseBoolean(uri.getQueryParameter(QUERY_PARAM_FINISH_ONLY));
final FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(android.R.id.content, fragment);
ft.commit();
return true;
}
@Override
public void setControlBarOffset(float offset) {
}
@Override
public float getControlBarOffset() {
return 0;
}
@Override
public int getControlBarHeight() {
final ActionBar actionBar = getActionBar();
return actionBar != null ? actionBar.getHeight() : 0;
}
@Override
public void moveControlBarBy(float delta) {
}
}

View File

@ -7,7 +7,6 @@ import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View;
@ -32,7 +31,7 @@ public abstract class MenuDialogFragment extends BaseSupportDialogFragment imple
final int themeRes, accentColor;
if (activity instanceof IThemedActivity) {
themeRes = ((IThemedActivity) activity).getThemeResourceId();
accentColor = ((IThemedActivity) activity).getOverrideAccentColor();
accentColor = ((IThemedActivity) activity).getThemeColor();
} else {
themeRes = ThemeUtils.getSettingsThemeResource(activity);
accentColor = ThemeUtils.getUserThemeColor(activity);

View File

@ -95,7 +95,7 @@ public class UserHashtagAutoCompleteAdapter extends SimpleCursorAdapter implemen
final int themeRes, accentColor;
if (context instanceof IThemedActivity) {
themeRes = ((IThemedActivity) context).getThemeResourceId();
accentColor = ((IThemedActivity) context).getOverrideAccentColor();
accentColor = ((IThemedActivity) context).getThemeColor();
} else {
themeRes = ThemeUtils.getThemeResource(context);
accentColor = ThemeUtils.getUserThemeColor(context);

View File

@ -31,6 +31,7 @@ import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.database.Cursor;
import android.graphics.Color;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.FragmentActivity;
@ -141,6 +142,11 @@ public class AccountsDrawerFragment extends BaseSupportListFragment implements L
getLoaderManager().initLoader(0, null, this);
}
@Override
protected void fitSystemWindows(Rect insets) {
// No-op
}
@Override
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
switch (requestCode) {
@ -260,6 +266,7 @@ public class AccountsDrawerFragment extends BaseSupportListFragment implements L
if (!(item instanceof OptionItem)) return;
final OptionItem option = (OptionItem) item;
switch (option.id) {
case MENU_ACCOUNTS:
case MENU_ADD_ACCOUNT: {
final Intent intent = new Intent(INTENT_ACTION_TWITTER_LOGIN);
intent.setClass(getActivity(), SignInActivity.class);

View File

@ -19,9 +19,11 @@
package org.mariotaku.twidere.fragment.support;
import android.app.Activity;
import android.content.Context;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
@ -38,6 +40,8 @@ import org.mariotaku.refreshnow.widget.RefreshMode;
import org.mariotaku.refreshnow.widget.RefreshNowConfig;
import org.mariotaku.refreshnow.widget.RefreshNowListView;
import org.mariotaku.refreshnow.widget.RefreshNowProgressIndicator;
import org.mariotaku.twidere.activity.iface.IControlBarActivity;
import org.mariotaku.twidere.activity.iface.IControlBarActivity.ControlBarOffsetListener;
import org.mariotaku.twidere.fragment.iface.IBasePullToRefreshFragment;
import org.mariotaku.twidere.util.ThemeUtils;
@ -46,7 +50,7 @@ import static android.support.v4.app.ListFragmentTrojan.INTERNAL_LIST_CONTAINER_
import static android.support.v4.app.ListFragmentTrojan.INTERNAL_PROGRESS_CONTAINER_ID;
public abstract class BasePullToRefreshListFragment extends BaseSupportListFragment implements
IBasePullToRefreshFragment {
IBasePullToRefreshFragment, ControlBarOffsetListener {
@Override
public RefreshNowListView getListView() {
@ -65,6 +69,23 @@ public abstract class BasePullToRefreshListFragment extends BaseSupportListFragm
return getListView().isRefreshing();
}
@Override
public void onDetach() {
final FragmentActivity activity = getActivity();
if (activity instanceof IControlBarActivity) {
((IControlBarActivity) activity).unregisterControlBarOffsetListener(this);
}
super.onDetach();
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof IControlBarActivity) {
((IControlBarActivity) activity).registerControlBarOffsetListener(this);
}
}
/**
* Provide default implementation to return a simple list view. Subclasses
* can override to replace with their own layout. If doing so, the returned
@ -211,4 +232,10 @@ public abstract class BasePullToRefreshListFragment extends BaseSupportListFragm
}
@Override
public void onControlBarOffsetChanged(IControlBarActivity activity, float offset) {
final View indicator = getRefreshIndicatorView();
if (indicator == null) return;
indicator.setTranslationY(activity.getControlBarHeight() * (offset - 1));
}
}

View File

@ -48,6 +48,7 @@ import android.widget.ProgressBar;
import android.widget.TextView;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.activity.iface.IControlBarActivity;
import org.mariotaku.twidere.activity.iface.IThemedActivity;
import org.mariotaku.twidere.activity.support.HomeActivity;
import org.mariotaku.twidere.app.TwidereApplication;
@ -147,14 +148,16 @@ public class BaseSupportListFragment extends ListFragment implements IBaseFragme
@Override
public void requestFitSystemWindows() {
final Activity activity = getActivity();
if (!(activity instanceof SystemWindowsInsetsCallback)) return;
final SystemWindowsInsetsCallback callback = (SystemWindowsInsetsCallback) activity;
final Rect insets = new Rect();
if (activity instanceof SystemWindowsInsetsCallback
&& ((SystemWindowsInsetsCallback) activity).getSystemWindowsInsets(insets)) {
if (callback.getSystemWindowsInsets(insets)) {
fitSystemWindows(insets);
}
}
protected void fitSystemWindows(Rect insets) {
Utils.makeListFragmentFitsSystemWindows(this, insets);
}
public AsyncTwitterWrapper getTwitterWrapper() {
@ -215,13 +218,6 @@ public class BaseSupportListFragment extends ListFragment implements IBaseFragme
final ListView listView = getListView();
listView.setOnTouchListener(mInternalOnTouchListener);
requestFitSystemWindows();
if (isActionBarOverlay()) {
Utils.makeListFragmentFitsSystemWindows(this);
}
}
protected boolean isActionBarOverlay() {
return getTabPosition() >= 0;
}
/**
@ -378,8 +374,12 @@ public class BaseSupportListFragment extends ListFragment implements IBaseFragme
@Override
public boolean scrollToStart() {
if (!isAdded() || getActivity() == null) return false;
final Activity activity = getActivity();
if (!isAdded() || activity == null) return false;
Utils.scrollListToTop(getListView());
if (activity instanceof IControlBarActivity) {
((IControlBarActivity) activity).setControlBarOffset(1);
}
return true;
}
@ -433,9 +433,8 @@ 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 && getUserVisibleHint()) {
final HomeActivity home = (HomeActivity) a;
home.moveControlBarBy(delta);
if (a instanceof IControlBarActivity && getTabPosition() >= 0 && getUserVisibleHint()) {
((IControlBarActivity) a).moveControlBarBy(delta);
}
}
}

View File

@ -20,12 +20,14 @@
package org.mariotaku.twidere.util;
public class MathUtils {
public static float clamp(final float num, final float max, final float min) {
return Math.max(Math.min(num, max), min);
}
public static float clamp(final float num, final float bound1, final float bound2) {
final float max = Math.max(bound1, bound2), min = Math.min(bound1, bound2);
return Math.max(Math.min(num, max), min);
}
public static int clamp(final int num, final int max, final int min) {
return Math.max(Math.min(num, max), min);
}
public static int clamp(final int num, final int bound1, final int bound2) {
final int max = Math.max(bound1, bound2), min = Math.min(bound1, bound2);
return Math.max(Math.min(num, max), min);
}
}

View File

@ -493,7 +493,7 @@ public class ThemeUtils implements Constants {
final int themeRes, accentColor;
if (context instanceof IThemedActivity) {
themeRes = ((IThemedActivity) context).getThemeResourceId();
accentColor = ((IThemedActivity) context).getOverrideAccentColor();
accentColor = ((IThemedActivity) context).getThemeColor();
} else {
themeRes = getSettingsThemeResource(context);
accentColor = getUserThemeColor(context, themeRes);
@ -514,7 +514,7 @@ public class ThemeUtils implements Constants {
final int themeRes, accentColor;
if (context instanceof IThemedActivity) {
themeRes = ((IThemedActivity) context).getThemeResourceId();
accentColor = ((IThemedActivity) context).getOverrideAccentColor();
accentColor = ((IThemedActivity) context).getThemeColor();
} else {
themeRes = getSettingsThemeResource(context);
accentColor = getUserThemeColor(context);

View File

@ -3863,16 +3863,42 @@ public final class Utils implements Constants, TwitterConstants {
final SystemWindowsInsetsCallback callback = (SystemWindowsInsetsCallback) activity;
final Rect insets = new Rect();
if (callback.getSystemWindowsInsets(insets)) {
final ListView listView = fragment.getListView();
listView.setPadding(insets.left, insets.top, insets.right, insets.bottom);
listView.setClipToPadding(false);
if (listView instanceof RefreshNowListView) {
final View indicatorView = ((RefreshNowListView) listView).getRefreshIndicatorView();
final LayoutParams lp = indicatorView.getLayoutParams();
if (lp instanceof MarginLayoutParams) {
((MarginLayoutParams) lp).topMargin = insets.top;
indicatorView.setLayoutParams(lp);
}
makeListFragmentFitsSystemWindows(fragment, insets);
}
}
public static int getContrastYIQ(int color) {
return getContrastYIQ(color, 128);
}
public static int getContrastYIQ(int color, int threshold) {
return getContrastYIQ(color, threshold, Color.BLACK, Color.WHITE);
}
/**
* Get most contrasting color
*
* @param color
* @return {@link Color#WHITE} or {@link Color#BLACK}
* @see <a href='http://24ways.org/2010/calculating-color-contrast/'>Calculating Color Contrast</a>
*/
public static int getContrastYIQ(int color, int threshold, int colorDark, int colorLight) {
final int r = Color.red(color), g = Color.green(color), b = Color.blue(color);
int yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000;
return (yiq >= threshold) ? colorDark : colorLight;
}
public static void makeListFragmentFitsSystemWindows(ListFragment fragment, Rect insets) {
final ListView listView = fragment.getListView();
listView.setPadding(insets.left, insets.top, insets.right, insets.bottom);
listView.setClipToPadding(false);
if (listView instanceof RefreshNowListView) {
final View indicatorView = ((RefreshNowListView) listView).getRefreshIndicatorView();
final LayoutParams lp = indicatorView.getLayoutParams();
if (lp instanceof MarginLayoutParams) {
((MarginLayoutParams) lp).topMargin = insets.top;
indicatorView.setLayoutParams(lp);
}
}
}

View File

@ -0,0 +1,22 @@
package org.mariotaku.twidere.util;
import android.annotation.TargetApi;
import android.os.Build;
import android.view.Window;
/**
* Created by mariotaku on 14/10/23.
*/
public class WindowAccessor {
public static void setStatusBarColor(Window window, int color) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return;
WindowAccessorL.setStatusBarColor(window, color);
}
@TargetApi(Build.VERSION_CODES.L)
private static class WindowAccessorL {
public static void setStatusBarColor(Window window, int color) {
window.setStatusBarColor(color);
}
}
}

View File

@ -20,6 +20,7 @@
package org.mariotaku.twidere.util.accessor;
import android.annotation.TargetApi;
import android.content.res.ColorStateList;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.v4.view.ViewCompat;
@ -27,26 +28,39 @@ import android.view.View;
public final class ViewAccessor {
public static void enableHwAccelIfNecessary(final View view) {
if (ViewCompat.getLayerType(view) != ViewCompat.LAYER_TYPE_HARDWARE) {
ViewCompat.setLayerType(view, ViewCompat.LAYER_TYPE_HARDWARE, null);
}
}
public static void enableHwAccelIfNecessary(final View view) {
if (ViewCompat.getLayerType(view) != ViewCompat.LAYER_TYPE_HARDWARE) {
ViewCompat.setLayerType(view, ViewCompat.LAYER_TYPE_HARDWARE, null);
}
}
@SuppressWarnings("deprecation")
public static void setBackground(final View view, final Drawable background) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
view.setBackgroundDrawable(background);
} else {
ViewAccessorJB.setBackground(view, background);
}
}
public static void setBackgroundTintList(final View view, final ColorStateList list) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return;
ViewAccessorL.setBackgroundTintList(view, list);
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
static class ViewAccessorJB {
static void setBackground(final View view, final Drawable background) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) return;
view.setBackground(background);
}
}
@SuppressWarnings("deprecation")
public static void setBackground(final View view, final Drawable background) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
view.setBackgroundDrawable(background);
} else {
ViewAccessorJB.setBackground(view, background);
}
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
static class ViewAccessorJB {
static void setBackground(final View view, final Drawable background) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) return;
view.setBackground(background);
}
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
static class ViewAccessorL {
static void setBackgroundTintList(final View view, final ColorStateList list) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return;
view.setBackgroundTintList(list);
}
}
}

View File

@ -0,0 +1,115 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.view;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Bitmap;
import android.graphics.Outline;
import android.graphics.PorterDuff.Mode;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewOutlineProvider;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ProgressBar;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.iface.IHomeActionButton;
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class HomeActionButton extends FrameLayout implements IHomeActionButton {
private final ImageView mIconView;
private final ProgressBar mProgressBar;
public HomeActionButton(final Context context) {
this(context, null);
}
public HomeActionButton(final Context context, final AttributeSet attrs) {
this(context, attrs, 0);
}
public HomeActionButton(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
inflate(context, R.layout.action_item_home_actions, this);
mIconView = (ImageView) findViewById(android.R.id.icon);
mProgressBar = (ProgressBar) findViewById(android.R.id.progress);
setOutlineProvider(new HomeActionButtonOutlineProvider());
setClipToOutline(true);
}
@Override
public void setColor(int color) {
final Drawable drawable = getBackground();
if (drawable != null) {
drawable.setColorFilter(color, Mode.MULTIPLY);
}
final int contrastColor = Utils.getContrastYIQ(color, 192);
mIconView.setColorFilter(contrastColor, Mode.SRC_ATOP);
mProgressBar.setIndeterminateTintList(ColorStateList.valueOf(contrastColor));
}
@Override
public void setIcon(final Bitmap bm) {
mIconView.setImageBitmap(bm);
}
@Override
public void setIcon(final Drawable drawable) {
mIconView.setImageDrawable(drawable);
}
@Override
public void setIcon(final int resId) {
mIconView.setImageResource(resId);
}
@Override
public void setShowProgress(final boolean showProgress) {
mProgressBar.setVisibility(showProgress ? View.VISIBLE : View.GONE);
mIconView.setVisibility(showProgress ? View.GONE : View.VISIBLE);
}
@Override
public void setTitle(final CharSequence title) {
setContentDescription(title);
}
@Override
public void setTitle(final int title) {
setTitle(getResources().getText(title));
}
private static class HomeActionButtonOutlineProvider extends ViewOutlineProvider {
@Override
public void getOutline(View view, Outline outline) {
final int width = view.getWidth(), height = view.getHeight();
final int size = Math.min(width, height);
final int left = (width - size) / 2, top = (height - size) / 2;
outline.setOval(left, top, left + size, top + size);
}
}
}

View File

@ -0,0 +1,94 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.view;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.PorterDuff.Mode;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ProgressBar;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.iface.IHomeActionButton;
public class HomeActionButtonCompat extends FrameLayout implements IHomeActionButton {
private final ImageView mIconView;
private final ProgressBar mProgressBar;
public HomeActionButtonCompat(final Context context) {
this(context, null);
}
public HomeActionButtonCompat(final Context context, final AttributeSet attrs) {
this(context, attrs, 0);
}
public HomeActionButtonCompat(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
inflate(context, R.layout.action_item_home_actions, this);
mIconView = (ImageView) findViewById(android.R.id.icon);
mProgressBar = (ProgressBar) findViewById(android.R.id.progress);
}
@Override
public void setColor(int color) {
final Drawable drawable = getBackground();
if (drawable instanceof LayerDrawable) {
final Drawable layer = ((LayerDrawable) drawable).findDrawableByLayerId(R.id.color_layer);
if (layer != null) {
layer.setColorFilter(color, Mode.SRC_ATOP);
}
}
mIconView.setColorFilter(Utils.getContrastYIQ(color), Mode.SRC_ATOP);
}
public void setIcon(final Bitmap bm) {
mIconView.setImageBitmap(bm);
}
public void setIcon(final Drawable drawable) {
mIconView.setImageDrawable(drawable);
}
public void setIcon(final int resId) {
mIconView.setImageResource(resId);
}
public void setShowProgress(final boolean showProgress) {
mProgressBar.setVisibility(showProgress ? View.VISIBLE : View.GONE);
mIconView.setVisibility(showProgress ? View.GONE : View.VISIBLE);
}
public void setTitle(final CharSequence title) {
setContentDescription(title);
}
public void setTitle(final int title) {
setTitle(getResources().getText(title));
}
}

View File

@ -1,78 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.view;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ProgressBar;
import org.mariotaku.twidere.R;
public class HomeActionsActionView extends FrameLayout {
private final ImageView mIconView;
private final ProgressBar mProgressBar;
public HomeActionsActionView(final Context context) {
this(context, null);
}
public HomeActionsActionView(final Context context, final AttributeSet attrs) {
this(context, attrs, android.R.attr.actionButtonStyle);
}
public HomeActionsActionView(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
inflate(context, R.layout.action_item_home_actions, this);
mIconView = (ImageView) findViewById(android.R.id.icon);
mProgressBar = (ProgressBar) findViewById(android.R.id.progress);
}
public void setIcon(final Bitmap bm) {
mIconView.setImageBitmap(bm);
}
public void setIcon(final Drawable drawable) {
mIconView.setImageDrawable(drawable);
}
public void setIcon(final int resId) {
mIconView.setImageResource(resId);
}
public void setShowProgress(final boolean showProgress) {
mProgressBar.setVisibility(showProgress ? View.VISIBLE : View.GONE);
mIconView.setVisibility(showProgress ? View.GONE : View.VISIBLE);
}
public void setTitle(final CharSequence title) {
setContentDescription(title);
}
public void setTitle(final int title) {
setTitle(getResources().getText(title));
}
}

View File

@ -38,6 +38,10 @@ public class TabPagerIndicator extends RecyclerView implements PagerIndicator {
mStripHeight = getResources().getDimensionPixelSize(R.dimen.element_spacing_small);
}
public void setStripColor(int color) {
mIndicatorAdapter.setStripColor(color);
}
public TabPagerIndicator(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
@ -117,12 +121,17 @@ public class TabPagerIndicator extends RecyclerView implements PagerIndicator {
return mStripHeight;
}
public void setIconColor(int color) {
mIndicatorAdapter.setIconColor(color);
}
private static class TabPagerIndicatorAdapter extends Adapter<TabItemHolder> implements OnClickListener, OnLongClickListener {
private final TabPagerIndicator mIndicator;
private final LayoutInflater mInflater;
private TabProvider mTabProvider;
private int mStripColor, mIconColor;
public TabPagerIndicatorAdapter(TabPagerIndicator indicator) {
mIndicator = indicator;
@ -146,6 +155,8 @@ public class TabPagerIndicator extends RecyclerView implements PagerIndicator {
final Drawable icon = mTabProvider.getPageIcon(position);
final CharSequence title = mTabProvider.getPageTitle(position);
holder.setTabData(position, icon, title, mIndicator.getCurrentItem() == position);
holder.setStripColor(mStripColor);
holder.setIconColor(mIconColor);
}
@Override
@ -172,6 +183,16 @@ public class TabPagerIndicator extends RecyclerView implements PagerIndicator {
if (!(tag instanceof Integer)) return false;
return mIndicator.dispatchTabLongClick((Integer) tag);
}
public void setStripColor(int color) {
mStripColor = color;
notifyDataSetChanged();
}
public void setIconColor(int color) {
mIconColor = color;
notifyDataSetChanged();
}
}
private void dispatchTabClick(int position) {
@ -216,7 +237,15 @@ public class TabPagerIndicator extends RecyclerView implements PagerIndicator {
itemView.setContentDescription(title);
iconView.setImageDrawable(icon);
iconView.setContentDescription(title);
selectedIndicator.setActivated(activated);
selectedIndicator.setVisibility(activated ? VISIBLE : INVISIBLE);
}
public void setStripColor(int color) {
selectedIndicator.setBackgroundColor(color);
}
public void setIconColor(int color) {
iconView.setColorFilter(color);
}
}

View File

@ -0,0 +1,23 @@
package org.mariotaku.twidere.view.iface;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
/**
* Created by mariotaku on 14/10/23.
*/
public interface IHomeActionButton {
void setColor(int color);
void setIcon(Bitmap bm);
void setIcon(Drawable drawable);
void setIcon(int resId);
void setShowProgress(boolean showProgress);
void setTitle(CharSequence title);
void setTitle(int title);
}

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#40ffffff">
<item>
<color android:color="#ffffff"/>
</item>
</ripple>

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="oval">
<gradient
android:endColor="#00000000"
android:gradientRadius="50%p"
android:startColor="#A0000000"
android:type="radial"/>
<size
android:width="64dp"
android:height="64dp"/>
</shape>
</item>
<item
android:id="@+id/color_layer"
android:bottom="@dimen/element_spacing_small"
android:left="@dimen/element_spacing_small"
android:right="@dimen/element_spacing_small"
android:top="@dimen/element_spacing_small">
<shape android:shape="oval">
<solid android:color="#ffffff"/>
</shape>
</item>
<item
android:bottom="@dimen/element_spacing_small"
android:left="@dimen/element_spacing_small"
android:right="@dimen/element_spacing_small"
android:top="@dimen/element_spacing_small">
<selector>
<item android:state_pressed="true">
<shape android:shape="oval">
<solid android:color="#20FFFFFF"/>
</shape>
</item>
</selector>
</item>
</layer-list>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<org.mariotaku.twidere.view.HomeActionButton
android:id="@+id/actions_button_bottom"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="@dimen/float_action_button_size"
android:layout_height="@dimen/float_action_button_size"
android:layout_gravity="bottom|right"
android:layout_margin="@dimen/element_spacing_large"
android:background="@drawable/btn_home_actions"
android:elevation="@dimen/element_spacing_small"
android:visibility="visible"/>

View File

@ -3,18 +3,20 @@
<ProgressBar
android:id="@android:id/progress"
style="?android:attr/progressBarStyle"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_gravity="center"
style="?android:attr/progressBarStyleLarge"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_margin="@dimen/element_spacing_small"
android:visibility="gone"/>
<ImageView
android:id="@android:id/icon"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_gravity="center"
android:layout_margin="@dimen/element_spacing_normal"
android:contentDescription="@string/compose"
android:scaleType="center"/>
android:scaleType="centerInside"/>
</merge>

View File

@ -11,12 +11,27 @@
<include layout="@layout/empty_tab_hint"/>
<include layout="@layout/home_actions_button_layout"/>
<include layout="@layout/layout_home_actions_button"/>
<org.mariotaku.twidere.view.TabPagerIndicator
android:id="@android:id/tabs"
style="?android:actionBarStyle"
<LinearLayout
android:id="@+id/tabs_container"
android:layout_width="match_parent"
android:layout_height="?android:actionBarSize"/>
android:layout_height="match_parent"
android:orientation="vertical">
<org.mariotaku.twidere.view.TabPagerIndicator
android:id="@+id/main_tabs"
style="?android:actionBarStyle"
android:layout_width="match_parent"
android:layout_height="?android:actionBarSize"
android:layout_weight="0"
android:theme="?android:actionBarWidgetTheme"/>
<View
android:id="@+id/actionbar_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"/>
</LinearLayout>
</FrameLayout>

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<org.mariotaku.twidere.view.HomeActionsActionView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/actions_button_bottom"
style="?android:imageButtonStyle"
android:layout_width="@dimen/home_actions_button_size"
android:layout_height="@dimen/home_actions_button_size"
android:layout_gravity="bottom|right"
android:visibility="visible"/>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<org.mariotaku.twidere.view.HomeActionButtonCompat
android:id="@+id/actions_button_bottom"
style="?android:buttonStyle"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="@dimen/float_action_button_size"
android:layout_height="@dimen/float_action_button_size"
android:layout_gravity="bottom|right"
android:layout_margin="@dimen/element_spacing_large"
android:background="@drawable/btn_home_actions_compat"
android:visibility="visible"/>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<org.mariotaku.twidere.view.MainFrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:id="@+id/content_fragment"
android:layout_height="match_parent"/>

View File

@ -16,7 +16,6 @@
<dimen name="text_size_wizard_nav_item">36sp</dimen>
<dimen name="line_indicator_line_width_wizard">32dp</dimen>
<dimen name="line_indicator_stroke_width_wizard">4dp</dimen>
<dimen name="home_actions_button_size">64dp</dimen>
<!-- Dimensions for Tab indicator -->
<dimen name="tab_item_minwidth_vpi">72dp</dimen>

View File

@ -26,7 +26,8 @@
<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">64dp</dimen>
<dimen name="float_action_button_size">56dp</dimen>
<dimen name="float_action_button_icon_size">24dp</dimen>
<dimen name="action_button_size">56dp</dimen>
<dimen name="text_size_extra_small">12sp</dimen>

View File

@ -26,8 +26,8 @@
<item name="android:windowActionModeOverlay">true</item>
<!-- ActionBar styles -->
<item name="android:actionBarStyle">@style/Widget.Twidere.ActionBar.Dark</item>
<item name="android:actionBarWidgetTheme">@style/Theme.Twidere.Dark</item>
<!--<item name="android:actionBarStyle">@style/Widget.Twidere.ActionBar.Dark</item>-->
<!--<item name="android:actionBarWidgetTheme">@style/Theme.Twidere.Dark</item>-->
<!-- Custom view styles -->
<item name="tabItemStyle">@style/Widget.TabPageIndicator.TabItem</item>
@ -67,8 +67,8 @@
<item name="android:windowActionModeOverlay">true</item>
<!-- ActionBar styles -->
<item name="android:actionBarStyle">@style/Widget.Twidere.ActionBar.Light</item>
<item name="android:actionBarWidgetTheme">@style/Theme.Twidere.Light</item>
<!--<item name="android:actionBarStyle">@style/Widget.Twidere.ActionBar.Light</item>-->
<!--<item name="android:actionBarWidgetTheme">@style/Theme.Twidere.Light</item>-->
<!-- Custom view styles -->
<item name="tabItemStyle">@style/Widget.TabPageIndicator.TabItem</item>
@ -108,9 +108,8 @@
<item name="android:windowActionModeOverlay">true</item>
<!-- ActionBar styles -->
<item name="android:actionBarStyle">@style/Widget.Twidere.ActionBar.Light.DarkActionBar
</item>
<item name="android:actionBarWidgetTheme">@style/Theme.Twidere.Dark</item>
<!--<item name="android:actionBarStyle">@style/Widget.Twidere.ActionBar.Light.DarkActionBar</item>-->
<!--<item name="android:actionBarWidgetTheme">@style/Theme.Twidere.Dark</item>-->
<!-- Custom view styles -->
<item name="tabItemStyle">@style/Widget.TabPageIndicator.TabItem</item>
@ -145,17 +144,16 @@
<style name="Theme.Twidere.Colored" parent="Theme.Twidere.Light">
<!-- ActionBar styles -->
<item name="android:actionBarStyle">@style/Widget.Twidere.ActionBar.Colored</item>
<item name="android:actionBarWidgetTheme">@style/Theme.Twidere.ActionBar.Colored.Light
</item>
<!--<item name="android:actionBarStyle">@style/Widget.Twidere.ActionBar.Colored</item>-->
<!--<item name="android:actionBarWidgetTheme">@style/Theme.Twidere.ActionBar.Colored.Light</item>-->
<!--<item name="android:actionBarItemBackground">@drawable/list_selector_white_light</item>-->
</style>
<style name="Theme.Twidere.Colored.DarkActionBar" parent="Theme.Twidere.Light.DarkActionBar">
<!-- ActionBar styles -->
<item name="android:actionBarStyle">@style/Widget.Twidere.ActionBar.Colored.Inverse</item>
<item name="android:actionBarWidgetTheme">@style/Theme.Twidere.ActionBar.Colored.Dark</item>
<!--<item name="android:actionBarStyle">@style/Widget.Twidere.ActionBar.Colored.Inverse</item>-->
<!--<item name="android:actionBarWidgetTheme">@style/Theme.Twidere.ActionBar.Colored.Dark</item>-->
<!--<item name="android:actionBarItemBackground">@drawable/list_selector_white</item>-->
</style>
@ -581,6 +579,7 @@
<style name="Theme.Twidere.Wizard" parent="Theme.Twidere.Settings.Light">
<item name="android:windowNoTitle">true</item>
<item name="android:windowActionBar">false</item>
<item name="android:colorActivatedHighlight">@android:color/holo_blue_light</item>
</style>
</resources>