improved theme

improving users list
This commit is contained in:
Mariotaku Lee 2015-04-17 04:29:36 +08:00
parent d7b304af98
commit d7421ff1f4
15 changed files with 379 additions and 277 deletions

View File

@ -17,6 +17,7 @@
#}
-keepclassmembers class android.support.v7.internal.app.WindowDecorActionBar {
private mContextView;
private mDecorToolbar;
}
-keepclassmembers class android.support.v7.internal.widget.ActionBarOverlayLayout {
private mWindowContentOverlay;

View File

@ -80,7 +80,7 @@ public class FiltersActivity extends BaseActionBarActivity {
supportRequestWindowFeature(WindowCompat.FEATURE_ACTION_MODE_OVERLAY);
super.onCreate(savedInstanceState);
ThemeUtils.applyActionBarBackground(getSupportActionBar(), this, getCurrentThemeResourceId(),
getCurrentThemeColor(), false);
getCurrentThemeColor(), getThemeBackgroundOption(), false);
setContentView(R.layout.activity_content_pages);
mMainContent.setOnFitSystemWindowsListener(this);
mAdapter = new SupportTabsAdapter(this, getSupportFragmentManager(), null, 1);

View File

@ -750,11 +750,13 @@ public class HomeActivity extends BaseActionBarActivity implements OnClickListen
private void setupBars() {
final int themeColor = getThemeColor();
final int themeResId = getCurrentThemeResourceId();
final boolean isTransparent = ThemeUtils.isTransparentBackground(getCurrentThemeBackgroundOption());
final String backgroundOption = getCurrentThemeBackgroundOption();
final boolean isTransparent = ThemeUtils.isTransparentBackground(backgroundOption);
final int actionBarAlpha = isTransparent ? ThemeUtils.getUserThemeBackgroundAlpha(this) : 0xFF;
final IHomeActionButton homeActionButton = (IHomeActionButton) mActionsButton;
mTabIndicator.setItemContext(ThemeUtils.getActionBarContext(this));
ViewUtils.setBackground(mActionBar, ThemeUtils.getActionBarBackground(this, themeResId, themeColor, true));
ViewUtils.setBackground(mActionBar, ThemeUtils.getActionBarBackground(this, themeResId, themeColor,
backgroundOption, true));
if (ThemeUtils.isDarkTheme(themeResId)) {
final int backgroundColor = ThemeUtils.getThemeBackgroundColor(mTabIndicator.getItemContext());
final int foregroundColor = ThemeUtils.getThemeForegroundColor(mTabIndicator.getItemContext());

View File

@ -47,7 +47,6 @@ import org.mariotaku.twidere.fragment.iface.IBaseFragment;
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback;
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback;
import org.mariotaku.twidere.fragment.support.SearchFragment;
import org.mariotaku.twidere.util.ColorUtils;
import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.ShortcutCallback;
import org.mariotaku.twidere.util.MultiSelectEventHandler;
@ -244,8 +243,10 @@ public class LinkHandlerActivity extends BaseActionBarActivity implements System
@SuppressLint("AppCompatMethod")
private void setActionBarTheme(ActionBar actionBar, int linkId, Uri data) {
final int currentThemeColor = getCurrentThemeColor();
int actionBarItemsColor = ColorUtils.getContrastYIQ(currentThemeColor, 192);
final int themeColor = getCurrentThemeColor();
final int themeId = getCurrentThemeResourceId();
final String option = getThemeBackgroundOption();
int actionBarItemsColor = ThemeUtils.getContrastActionBarItemColor(this, themeId, themeColor);
switch (linkId) {
case LINK_ID_USER: {
actionBarItemsColor = Color.WHITE;
@ -253,17 +254,13 @@ public class LinkHandlerActivity extends BaseActionBarActivity implements System
}
case LINK_ID_SEARCH:
case LINK_ID_USER_LISTS: {
ThemeUtils.applyActionBarBackground(actionBar, this, getCurrentThemeResourceId(),
currentThemeColor, false);
ThemeUtils.applyActionBarBackground(getActionBar(), this, getCurrentThemeResourceId(),
currentThemeColor, true);
ThemeUtils.applyActionBarBackground(actionBar, this, themeId, themeColor, option, false);
ThemeUtils.applyActionBarBackground(getActionBar(), this, themeId, themeColor, option, true);
break;
}
default: {
ThemeUtils.applyActionBarBackground(actionBar, this, getCurrentThemeResourceId(),
currentThemeColor, true);
ThemeUtils.applyActionBarBackground(getActionBar(), this, getCurrentThemeResourceId(),
currentThemeColor, true);
ThemeUtils.applyActionBarBackground(actionBar, this, themeId, themeColor, option, true);
ThemeUtils.applyActionBarBackground(getActionBar(), this, themeId, themeColor, option, true);
break;
}
}

View File

@ -23,15 +23,11 @@ import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.ActionBarActivity;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.ForegroundColorSpan;
import android.util.AttributeSet;
import android.view.View;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.activity.iface.IThemedActivity;
import org.mariotaku.twidere.util.ColorUtils;
import org.mariotaku.twidere.util.StrictModeUtils;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.Utils;
@ -91,7 +87,7 @@ public abstract class ThemedActionBarActivity extends ActionBarActivity implemen
public void onSupportActionModeStarted(android.support.v7.view.ActionMode mode) {
super.onSupportActionModeStarted(mode);
ThemeUtils.applySupportActionModeBackground(mode, this, getCurrentThemeResourceId(),
getCurrentThemeColor(), true);
getCurrentThemeColor(), getThemeBackgroundOption(), true);
}
@Override
@ -104,17 +100,6 @@ public abstract class ThemedActionBarActivity extends ActionBarActivity implemen
super.onCreate(savedInstanceState);
}
@Override
protected void onTitleChanged(CharSequence title, int color) {
final SpannableStringBuilder builder = new SpannableStringBuilder(title);
final int themeResId = getCurrentThemeResourceId();
final int themeColor = getThemeColor(), contrastColor = ColorUtils.getContrastYIQ(themeColor, 192);
if (!ThemeUtils.isDarkTheme(themeResId)) {
builder.setSpan(new ForegroundColorSpan(contrastColor), 0, builder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
super.onTitleChanged(title, color);
}
@Override
public View onCreateView(String name, @NonNull Context context, @NonNull AttributeSet attrs) {
final View view = ThemeUtils.createView(name, context, attrs, mCurrentThemeColor);

View File

@ -31,7 +31,6 @@ import android.view.View;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.activity.iface.IThemedActivity;
import org.mariotaku.twidere.util.ColorUtils;
import org.mariotaku.twidere.util.StrictModeUtils;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.Utils;
@ -122,7 +121,8 @@ public abstract class ThemedFragmentActivity extends FragmentActivity implements
protected void onTitleChanged(CharSequence title, int color) {
final SpannableStringBuilder builder = new SpannableStringBuilder(title);
final int themeResId = getCurrentThemeResourceId();
final int themeColor = getThemeColor(), contrastColor = ColorUtils.getContrastYIQ(themeColor, 192);
final int themeColor = getThemeColor();
final int contrastColor = ThemeUtils.getContrastActionBarTitleColor(this, themeResId, themeColor);
if (!ThemeUtils.isDarkTheme(themeResId)) {
builder.setSpan(new ForegroundColorSpan(contrastColor), 0, builder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}

View File

@ -192,19 +192,10 @@ public abstract class AbsStatusesAdapter<D> extends LoadMoreSupportAdapter<ViewH
@Override
public void onUserProfileClick(final StatusViewHolder holder, final int position) {
if (mStatusAdapterListener==null)return;
final ParcelableStatus status = getStatus(position);
if (status == null) return;
final Context context = getContext();
final View profileImageView = holder.getProfileImageView();
final View profileTypeView = holder.getProfileTypeView();
if (context instanceof FragmentActivity) {
final Bundle options = Utils.makeSceneTransitionOption((FragmentActivity) context,
new Pair<>(profileImageView, UserFragment.TRANSITION_NAME_PROFILE_IMAGE),
new Pair<>(profileTypeView, UserFragment.TRANSITION_NAME_PROFILE_TYPE));
Utils.openUserProfile(context, status.account_id, status.user_id, status.user_screen_name, options);
} else {
Utils.openUserProfile(context, status.account_id, status.user_id, status.user_screen_name, null);
}
mStatusAdapterListener.onUserProfileClick(holder, status, position);
}
public boolean isShowInReplyTo() {
@ -319,6 +310,8 @@ public abstract class AbsStatusesAdapter<D> extends LoadMoreSupportAdapter<ViewH
boolean onStatusLongClick(StatusViewHolder holder, int position);
void onStatusMenuClick(StatusViewHolder holder, View menuView, int position);
void onUserProfileClick(StatusViewHolder holder, ParcelableStatus status, int position);
}
}

View File

@ -159,12 +159,17 @@ public abstract class AbsUsersAdapter<D> extends LoadMoreSupportAdapter<ViewHold
@Override
public void onUserClick(UserViewHolder holder, int position) {
if (mUserAdapterListener == null) return;
mUserAdapterListener.onUserClick(holder, position);
}
@Override
public boolean onUserLongClick(UserViewHolder holder, int position) {
return false;
return mUserAdapterListener != null && mUserAdapterListener.onUserLongClick(holder, position);
}
public void setListener(UserAdapterListener userAdapterListener) {
mUserAdapterListener = userAdapterListener;
}
@Override
@ -179,4 +184,14 @@ public abstract class AbsUsersAdapter<D> extends LoadMoreSupportAdapter<ViewHold
protected abstract void bindStatus(UserViewHolder holder, int position);
private UserAdapterListener mUserAdapterListener;
public static interface UserAdapterListener {
void onUserClick(UserViewHolder holder, int position);
boolean onUserLongClick(UserViewHolder holder, int position);
}
}

View File

@ -9,6 +9,7 @@ import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.Loader;
import android.support.v4.util.Pair;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.PopupMenu;
import android.support.v7.widget.PopupMenu.OnMenuItemClickListener;
@ -83,12 +84,6 @@ public abstract class AbsStatusesFragment<Data> extends AbsContentListFragment<A
public abstract int getStatuses(long[] accountIds, long[] maxIds, long[] sinceIds);
@Override
public final boolean scrollToStart() {
saveReadPosition();
return super.scrollToStart();
}
@Override
public boolean handleKeyboardShortcutSingle(int keyCode, @NonNull KeyEvent event) {
if (!KeyboardShortcutsHandler.isValidForHotkey(keyCode, event)) return false;
@ -173,29 +168,6 @@ public abstract class AbsStatusesFragment<Data> extends AbsContentListFragment<A
return false;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mReadStateManager = getReadStateManager();
final FragmentActivity activity = getActivity();
final TwidereApplication application = TwidereApplication.getInstance(activity);
mKeyboardShortcutsHandler = application.getKeyboardShortcutsHandler();
getAdapter().setListener(this);
getScrollListener().setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
saveReadPosition();
}
}
});
final Bundle loaderArgs = new Bundle(getArguments());
loaderArgs.putBoolean(EXTRA_FROM_USER, true);
getLoaderManager().initLoader(0, loaderArgs, this);
setListShown(false);
}
@Override
public final Loader<Data> onCreateLoader(int id, Bundle args) {
final boolean fromUser = args.getBoolean(EXTRA_FROM_USER);
@ -258,9 +230,6 @@ public abstract class AbsStatusesFragment<Data> extends AbsContentListFragment<A
}
}
protected abstract Loader<Data> onCreateStatusesLoader(final Context context, final Bundle args,
final boolean fromUser);
@Override
public void onGapClick(GapViewHolder holder, int position) {
final AbsStatusesAdapter<Data> adapter = getAdapter();
@ -350,6 +319,17 @@ public abstract class AbsStatusesFragment<Data> extends AbsContentListFragment<A
mSelectedStatus = status;
}
@Override
public void onUserProfileClick(StatusViewHolder holder, ParcelableStatus status, int position) {
final FragmentActivity activity = getActivity();
final View profileImageView = holder.getProfileImageView();
final View profileTypeView = holder.getProfileTypeView();
final Bundle options = Utils.makeSceneTransitionOption(activity,
new Pair<>(profileImageView, UserFragment.TRANSITION_NAME_PROFILE_IMAGE),
new Pair<>(profileTypeView, UserFragment.TRANSITION_NAME_PROFILE_TYPE));
Utils.openUserProfile(activity, status.account_id, status.user_id, status.user_screen_name, options);
}
@Override
public void onStart() {
super.onStart();
@ -372,6 +352,35 @@ public abstract class AbsStatusesFragment<Data> extends AbsContentListFragment<A
super.onDestroyView();
}
@Override
public final boolean scrollToStart() {
saveReadPosition();
return super.scrollToStart();
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mReadStateManager = getReadStateManager();
final FragmentActivity activity = getActivity();
final TwidereApplication application = TwidereApplication.getInstance(activity);
mKeyboardShortcutsHandler = application.getKeyboardShortcutsHandler();
getAdapter().setListener(this);
getScrollListener().setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
saveReadPosition();
}
}
});
final Bundle loaderArgs = new Bundle(getArguments());
loaderArgs.putBoolean(EXTRA_FROM_USER, true);
getLoaderManager().initLoader(0, loaderArgs, this);
setListShown(false);
}
protected Object createMessageBusCallback() {
return new StatusesBusCallback();
}
@ -394,6 +403,9 @@ public abstract class AbsStatusesFragment<Data> extends AbsContentListFragment<A
protected abstract boolean hasMoreData(Data data);
protected abstract Loader<Data> onCreateStatusesLoader(final Context context, final Bundle args,
final boolean fromUser);
protected abstract void onLoadingFinished();
protected void saveReadPosition() {

View File

@ -22,14 +22,20 @@ package org.mariotaku.twidere.fragment.support;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.Loader;
import android.support.v4.util.Pair;
import android.view.View;
import org.mariotaku.twidere.adapter.AbsUsersAdapter;
import org.mariotaku.twidere.adapter.AbsUsersAdapter.UserAdapterListener;
import org.mariotaku.twidere.loader.iface.IExtendedLoader;
import org.mariotaku.twidere.model.ParcelableUser;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.holder.UserViewHolder;
abstract class AbsUsersFragment<Data> extends AbsContentListFragment<AbsUsersAdapter<Data>> implements LoaderCallbacks<Data> {
abstract class AbsUsersFragment<Data> extends AbsContentListFragment<AbsUsersAdapter<Data>> implements LoaderCallbacks<Data>, UserAdapterListener {
public final Data getData() {
return getAdapter().getData();
@ -38,6 +44,9 @@ abstract class AbsUsersFragment<Data> extends AbsContentListFragment<AbsUsersAda
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getAdapter().setListener(this);
final Bundle loaderArgs = new Bundle(getArguments());
loaderArgs.putBoolean(EXTRA_FROM_USER, true);
getLoaderManager().initLoader(0, loaderArgs, this);
@ -71,6 +80,25 @@ abstract class AbsUsersFragment<Data> extends AbsContentListFragment<AbsUsersAda
}
}
@Override
public void onUserClick(UserViewHolder holder, int position) {
final ParcelableUser user = getAdapter().getUser(position);
final FragmentActivity activity = getActivity();
final View profileImageView = holder.getProfileImageView();
final View profileTypeView = holder.getProfileTypeView();
final Bundle options = Utils.makeSceneTransitionOption(activity,
new Pair<>(profileImageView, UserFragment.TRANSITION_NAME_PROFILE_IMAGE),
new Pair<>(profileTypeView, UserFragment.TRANSITION_NAME_PROFILE_TYPE));
Utils.openUserProfile(activity, user.account_id, user.id, user.screen_name, options);
}
@Override
public boolean onUserLongClick(UserViewHolder holder, int position) {
return true;
}
protected ParcelableUser getSelectedUser() {
//TODO return selected
return null;

View File

@ -189,30 +189,6 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
}
};
private void restoreReadPosition(@Nullable Pair<Long, Integer> position) {
if (position == null) return;
final int adapterPosition = mStatusAdapter.findPositionById(position.first);
if (adapterPosition == RecyclerView.NO_POSITION) return;
mLayoutManager.scrollToPositionWithOffset(adapterPosition, position.second);
}
@Nullable
private Pair<Long, Integer> saveReadPosition() {
final int position = mLayoutManager.findFirstVisibleItemPosition();
if (position == RecyclerView.NO_POSITION) return null;
long itemId = mStatusAdapter.getItemId(position);
final View positionView;
if (itemId == StatusAdapter.VIEW_TYPE_CONVERSATION_LOAD_INDICATOR) {
// Should be next item
positionView = mLayoutManager.findViewByPosition(position + 1);
itemId = mStatusAdapter.getItemId(position + 1);
} else {
positionView = mLayoutManager.findViewByPosition(position);
}
return new Pair<>(itemId, positionView != null ? positionView.getTop() : -1);
}
private PopupMenu mPopupMenu;
private ParcelableStatus mSelectedStatus;
private OnMenuItemClickListener mOnStatusMenuItemClickListener = new OnMenuItemClickListener() {
@ -389,11 +365,14 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
}
@Override
public Loader<SingleResponse<ParcelableStatus>> onCreateLoader(final int id, final Bundle args) {
final Bundle fragmentArgs = getArguments();
final long accountId = fragmentArgs.getLong(EXTRA_ACCOUNT_ID, -1);
final long statusId = fragmentArgs.getLong(EXTRA_STATUS_ID, -1);
return new ParcelableStatusLoader(getActivity(), false, fragmentArgs, accountId, statusId);
public void onUserProfileClick(StatusViewHolder holder, ParcelableStatus status, int position) {
final FragmentActivity activity = getActivity();
final View profileImageView = holder.getProfileImageView();
final View profileTypeView = holder.getProfileTypeView();
final Bundle options = Utils.makeSceneTransitionOption(activity,
new Pair<>(profileImageView, UserFragment.TRANSITION_NAME_PROFILE_IMAGE),
new Pair<>(profileTypeView, UserFragment.TRANSITION_NAME_PROFILE_TYPE));
Utils.openUserProfile(activity, status.account_id, status.user_id, status.user_screen_name, options);
}
@Override
@ -415,6 +394,16 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
private void addConversation(ParcelableStatus status, int position) {
mStatusAdapter.addConversation(status, position);
} @Override
public Loader<SingleResponse<ParcelableStatus>> onCreateLoader(final int id, final Bundle args) {
final Bundle fragmentArgs = getArguments();
final long accountId = fragmentArgs.getLong(EXTRA_ACCOUNT_ID, -1);
final long statusId = fragmentArgs.getLong(EXTRA_STATUS_ID, -1);
return new ParcelableStatusLoader(getActivity(), false, fragmentArgs, accountId, statusId);
}
private StatusAdapter getAdapter() {
return mStatusAdapter;
}
private DividerItemDecoration getItemDecoration() {
@ -425,31 +414,6 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
return mStatusAdapter.getStatus();
}
@Override
public void onLoadFinished(final Loader<SingleResponse<ParcelableStatus>> loader,
final SingleResponse<ParcelableStatus> data) {
if (data.hasData()) {
final long itemId = mStatusAdapter.getItemId(mLayoutManager.findFirstVisibleItemPosition());
final View firstChild = mLayoutManager.getChildAt(0);
final int top = firstChild != null ? firstChild.getTop() : 0;
final ParcelableStatus status = data.getData();
if (mStatusAdapter.setStatus(status)) {
mLayoutManager.scrollToPositionWithOffset(1, 0);
mStatusAdapter.setConversation(null);
mStatusAdapter.setReplies(null);
loadReplies(status);
loadConversation(status);
} else {
final int position = mStatusAdapter.findPositionById(itemId);
mLayoutManager.scrollToPositionWithOffset(position, top);
}
setState(STATE_LOADED);
} else {
//TODO show errors
setState(STATE_ERROR);
}
}
private void loadConversation(ParcelableStatus status) {
if (AsyncTaskUtils.isTaskRunning(mLoadConversationTask)) {
mLoadConversationTask.cancel(true);
@ -509,6 +473,52 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
}
}
//end
} @Override
public void onLoadFinished(final Loader<SingleResponse<ParcelableStatus>> loader,
final SingleResponse<ParcelableStatus> data) {
if (data.hasData()) {
final long itemId = mStatusAdapter.getItemId(mLayoutManager.findFirstVisibleItemPosition());
final View firstChild = mLayoutManager.getChildAt(0);
final int top = firstChild != null ? firstChild.getTop() : 0;
final ParcelableStatus status = data.getData();
if (mStatusAdapter.setStatus(status)) {
mLayoutManager.scrollToPositionWithOffset(1, 0);
mStatusAdapter.setConversation(null);
mStatusAdapter.setReplies(null);
loadReplies(status);
loadConversation(status);
} else {
final int position = mStatusAdapter.findPositionById(itemId);
mLayoutManager.scrollToPositionWithOffset(position, top);
}
setState(STATE_LOADED);
} else {
//TODO show errors
setState(STATE_ERROR);
}
}
private void restoreReadPosition(@Nullable Pair<Long, Integer> position) {
if (position == null) return;
final int adapterPosition = mStatusAdapter.findPositionById(position.first);
if (adapterPosition == RecyclerView.NO_POSITION) return;
mLayoutManager.scrollToPositionWithOffset(adapterPosition, position.second);
}
@Nullable
private Pair<Long, Integer> saveReadPosition() {
final int position = mLayoutManager.findFirstVisibleItemPosition();
if (position == RecyclerView.NO_POSITION) return null;
long itemId = mStatusAdapter.getItemId(position);
final View positionView;
if (itemId == StatusAdapter.VIEW_TYPE_CONVERSATION_LOAD_INDICATOR) {
// Should be next item
positionView = mLayoutManager.findViewByPosition(position + 1);
itemId = mStatusAdapter.getItemId(position + 1);
} else {
positionView = mLayoutManager.findViewByPosition(position);
}
return new Pair<>(itemId, positionView != null ? positionView.getTop() : -1);
}
private void setConversation(List<ParcelableStatus> data) {
@ -911,41 +921,6 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
}
public static final class LoadSensitiveImageConfirmDialogFragment extends BaseSupportDialogFragment implements
DialogInterface.OnClickListener {
@Override
public void onClick(final DialogInterface dialog, final int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE: {
final Fragment f = getParentFragment();
if (f instanceof StatusFragment) {
final StatusAdapter adapter = ((StatusFragment) f).getAdapter();
adapter.setDetailMediaExpanded(true);
}
break;
}
}
}
@NonNull
@Override
public Dialog onCreateDialog(final Bundle savedInstanceState) {
final Context wrapped = ThemeUtils.getDialogThemedContext(getActivity());
final AlertDialog.Builder builder = new AlertDialog.Builder(wrapped);
builder.setTitle(android.R.string.dialog_alert_title);
builder.setMessage(R.string.sensitive_content_warning);
builder.setPositiveButton(android.R.string.ok, this);
builder.setNegativeButton(android.R.string.cancel, null);
return builder.create();
}
}
private StatusAdapter getAdapter() {
return mStatusAdapter;
}
static class LoadConversationTask extends AsyncTask<ParcelableStatus, ParcelableStatus,
ListResponse<ParcelableStatus>> {
@ -996,6 +971,37 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
}
public static final class LoadSensitiveImageConfirmDialogFragment extends BaseSupportDialogFragment implements
DialogInterface.OnClickListener {
@Override
public void onClick(final DialogInterface dialog, final int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE: {
final Fragment f = getParentFragment();
if (f instanceof StatusFragment) {
final StatusAdapter adapter = ((StatusFragment) f).getAdapter();
adapter.setDetailMediaExpanded(true);
}
break;
}
}
}
@NonNull
@Override
public Dialog onCreateDialog(final Bundle savedInstanceState) {
final Context wrapped = ThemeUtils.getDialogThemedContext(getActivity());
final AlertDialog.Builder builder = new AlertDialog.Builder(wrapped);
builder.setTitle(android.R.string.dialog_alert_title);
builder.setMessage(R.string.sensitive_content_warning);
builder.setPositiveButton(android.R.string.ok, this);
builder.setNegativeButton(android.R.string.cancel, null);
return builder.create();
}
}
private static class SpaceViewHolder extends ViewHolder {
public SpaceViewHolder(View itemView) {
@ -1003,11 +1009,6 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
}
}
@Override
public void onLoaderReset(final Loader<SingleResponse<ParcelableStatus>> loader) {
}
private static class StatusAdapter extends Adapter<ViewHolder> implements IStatusesAdapter<List<ParcelableStatus>> {
private static final int VIEW_TYPE_DETAIL_STATUS = 0;
@ -1091,31 +1092,17 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
return RecyclerView.NO_POSITION;
}
public StatusFragment getFragment() {
return mFragment;
}
public MediaLoaderWrapper getMediaLoader() {
return mImageLoader;
}
public Context getContext() {
return mContext;
}
@Override
public MediaLoadingHandler getMediaLoadingHandler() {
return mMediaLoadingHandler;
}
@Override
public int getProfileImageStyle() {
return mProfileImageStyle;
}
@Override
public int getMediaPreviewStyle() {
return mMediaPreviewStyle;
public float getTextSize() {
return mTextSize;
}
@NonNull
@ -1124,35 +1111,27 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
return mFragment.getTwitterWrapper();
}
public float getTextSize() {
return mTextSize;
@Override
public boolean isProfileImageEnabled() {
return mDisplayProfileImage;
}
public MediaLoaderWrapper getMediaLoader() {
return mImageLoader;
}
public StatusFragment getFragment() {
return mFragment;
}
@Override
public boolean isLoadMoreIndicatorVisible() {
return mLoadMoreIndicatorVisible;
public int getLinkHighlightingStyle() {
return mLinkHighligingStyle;
}
@Override
public boolean isLoadMoreSupported() {
return mLoadMoreSupported;
}
@Override
public void setLoadMoreSupported(boolean supported) {
mLoadMoreSupported = supported;
if (!supported) {
mLoadMoreIndicatorVisible = false;
}
notifyDataSetChanged();
}
@Override
public void setLoadMoreIndicatorVisible(boolean enabled) {
if (mLoadMoreIndicatorVisible == enabled) return;
mLoadMoreIndicatorVisible = enabled && mLoadMoreSupported;
updateItemDecoration();
notifyDataSetChanged();
public int getMediaPreviewStyle() {
return mMediaPreviewStyle;
}
@Override
@ -1169,30 +1148,30 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
}
}
@Override
public int getStatusesCount() {
return getConversationCount() + 1 + getRepliesCount() + 1;
}
@Override
public long getStatusId(int position) {
final ParcelableStatus status = getStatus(position);
return status != null ? status.hashCode() : position;
}
@Override
public int getStatusesCount() {
return getConversationCount() + 1 + getRepliesCount() + 1;
}
@Override
public TwidereLinkify getTwidereLinkify() {
return mTwidereLinkify;
}
@Override
public boolean isMediaPreviewEnabled() {
return mDisplayMediaPreview;
public boolean isCardActionsHidden() {
return mHideCardActions;
}
@Override
public int getLinkHighlightingStyle() {
return mLinkHighligingStyle;
public boolean isMediaPreviewEnabled() {
return mDisplayMediaPreview;
}
public boolean isNameFirst() {
@ -1204,11 +1183,6 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
return mSensitiveContentEnabled;
}
@Override
public boolean isCardActionsHidden() {
return mHideCardActions;
}
@Override
public void setData(List<ParcelableStatus> data) {
@ -1219,6 +1193,11 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
return false;
}
@Override
public MediaLoadingHandler getMediaLoadingHandler() {
return mMediaLoadingHandler;
}
public ParcelableStatus getStatus() {
return mStatus;
}
@ -1255,43 +1234,30 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
}
@Override
public boolean isProfileImageEnabled() {
return mDisplayProfileImage;
public boolean isLoadMoreIndicatorVisible() {
return mLoadMoreIndicatorVisible;
}
@Override
public final void onStatusClick(StatusViewHolder holder, int position) {
if (mStatusAdapterListener != null) {
mStatusAdapterListener.onStatusClick(holder, position);
}
}
@Override
public boolean onStatusLongClick(StatusViewHolder holder, int position) {
return false;
}
@Override
public void onMediaClick(StatusViewHolder holder, ParcelableMedia media, int position) {
if (mStatusAdapterListener != null) {
mStatusAdapterListener.onMediaClick(holder, media, position);
}
}
@Override
public void onUserProfileClick(StatusViewHolder holder, int position) {
final Context context = getContext();
final ParcelableStatus status = getStatus(position);
final View profileImageView = holder.getProfileImageView();
final View profileTypeView = holder.getProfileTypeView();
if (context instanceof FragmentActivity) {
final Bundle options = Utils.makeSceneTransitionOption((FragmentActivity) context,
new Pair<>(profileImageView, UserFragment.TRANSITION_NAME_PROFILE_IMAGE),
new Pair<>(profileTypeView, UserFragment.TRANSITION_NAME_PROFILE_TYPE));
Utils.openUserProfile(context, status.account_id, status.user_id, status.user_screen_name, options);
} else {
Utils.openUserProfile(context, status.account_id, status.user_id, status.user_screen_name, null);
public void setLoadMoreIndicatorVisible(boolean enabled) {
if (mLoadMoreIndicatorVisible == enabled) return;
mLoadMoreIndicatorVisible = enabled && mLoadMoreSupported;
updateItemDecoration();
notifyDataSetChanged();
}
@Override
public boolean isLoadMoreSupported() {
return mLoadMoreSupported;
}
@Override
public void setLoadMoreSupported(boolean supported) {
mLoadMoreSupported = supported;
if (!supported) {
mLoadMoreIndicatorVisible = false;
}
notifyDataSetChanged();
}
@Override
@ -1418,6 +1384,41 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
}
}
@Override
public void onMediaClick(StatusViewHolder holder, ParcelableMedia media, int position) {
if (mStatusAdapterListener != null) {
mStatusAdapterListener.onMediaClick(holder, media, position);
}
}
@Override
public final void onStatusClick(StatusViewHolder holder, int position) {
if (mStatusAdapterListener != null) {
mStatusAdapterListener.onStatusClick(holder, position);
}
}
@Override
public boolean onStatusLongClick(StatusViewHolder holder, int position) {
return false;
}
@Override
public void onUserProfileClick(StatusViewHolder holder, int position) {
final Context context = getContext();
final ParcelableStatus status = getStatus(position);
final View profileImageView = holder.getProfileImageView();
final View profileTypeView = holder.getProfileTypeView();
if (context instanceof FragmentActivity) {
final Bundle options = Utils.makeSceneTransitionOption((FragmentActivity) context,
new Pair<>(profileImageView, UserFragment.TRANSITION_NAME_PROFILE_IMAGE),
new Pair<>(profileTypeView, UserFragment.TRANSITION_NAME_PROFILE_TYPE));
Utils.openUserProfile(context, status.account_id, status.user_id, status.user_screen_name, options);
} else {
Utils.openUserProfile(context, status.account_id, status.user_id, status.user_screen_name, null);
}
}
public void setConversation(List<ParcelableStatus> conversation) {
mConversation = conversation;
notifyDataSetChanged();
@ -1515,5 +1516,14 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
}
@Override
public void onLoaderReset(final Loader<SingleResponse<ParcelableStatus>> loader) {
}
}

View File

@ -1422,7 +1422,8 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
final Drawable drawable = mPagerIndicator.getBackground();
final int stackedTabColor;
if (ThemeUtils.isDarkTheme(activity.getCurrentThemeResourceId())) {
final int themeId = activity.getCurrentThemeResourceId();
if (ThemeUtils.isDarkTheme(themeId)) {
stackedTabColor = getResources().getColor(R.color.background_color_action_bar_dark);
final int contrastColor = ColorUtils.getContrastYIQ(stackedTabColor, 192);
mPagerIndicator.setIconColor(contrastColor);
@ -1441,7 +1442,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
return;
}
final int barColor = (Integer) sArgbEvaluator.evaluate(factor, mActionBarShadowColor, stackedTabColor);
final int itemColor = ColorUtils.getContrastYIQ(barColor, 192);
final int itemColor = ThemeUtils.getContrastActionBarItemColor(activity, themeId, barColor);
if (mActionBarHomeAsUpIndicator != null) {
mActionBarHomeAsUpIndicator.setColorFilter(itemColor, Mode.SRC_ATOP);
}

View File

@ -40,7 +40,6 @@ import android.widget.TextView;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.util.ColorUtils;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.ViewUtils;
import org.mariotaku.twidere.view.iface.IExtendedView;
@ -109,15 +108,17 @@ public class ThemePreviewPreference extends Preference implements Constants, OnS
final int cardBackgroundColor = ThemeUtils.getCardBackgroundColor(context);
final int accentColor = ThemeUtils.getUserAccentColor(context);
ThemeUtils.applyWindowBackground(context, windowBackgroundView, ThemeUtils.getThemeResource(context),
ThemeUtils.getThemeBackgroundOption(context), ThemeUtils.getUserThemeBackgroundAlpha(context));
// ViewAccessor.setBackground(windowContentOverlayView, ThemeUtils.getWindowContentOverlay(context));
ViewUtils.setBackground(actionBarView, ThemeUtils.getActionBarBackground(context, themeRes, accentColor, true));
final int themeId = ThemeUtils.getThemeResource(context);
final String backgroundOption = ThemeUtils.getThemeBackgroundOption(context);
ThemeUtils.applyWindowBackground(context, windowBackgroundView, themeId, backgroundOption,
ThemeUtils.getUserThemeBackgroundAlpha(context));
ViewUtils.setBackground(actionBarView, ThemeUtils.getActionBarBackground(context, themeRes,
accentColor, backgroundOption, true));
ViewUtils.setBackground(actionBarOverlay, ThemeUtils.getWindowContentOverlay(context));
cardView.setCardBackgroundColor(cardBackgroundColor);
actionBarView.setTitle(R.string.app_name);
actionBarView.setTitleTextColor(ColorUtils.getContrastYIQ(accentColor, 192));
actionBarView.setTitleTextColor(ThemeUtils.getContrastActionBarTitleColor(context, themeId, accentColor));
menuBar.setEnabled(false);
final MenuInflater inflater = new SupportMenuInflater(context);
inflater.inflate(R.menu.menu_status, menuBar.getMenu());

View File

@ -42,6 +42,7 @@ import android.support.v7.internal.view.SupportActionModeWrapper;
import android.support.v7.internal.view.SupportActionModeWrapperTrojan;
import android.support.v7.internal.view.menu.ActionMenuItemView;
import android.support.v7.internal.widget.ActionBarOverlayLayout;
import android.support.v7.internal.widget.DecorToolbar;
import android.support.v7.widget.ActionMenuView;
import android.support.v7.widget.Toolbar;
import android.text.SpannableStringBuilder;
@ -93,18 +94,19 @@ public class ThemeUtils implements Constants {
public static void applyActionBarBackground(final ActionBar actionBar, final Context context,
final int themeRes, final int accentColor, boolean outlineEnabled) {
final int themeRes, final int accentColor,
final String backgroundOption, boolean outlineEnabled) {
if (actionBar == null || context == null) return;
actionBar.setBackgroundDrawable(getActionBarBackground(context, themeRes, accentColor, outlineEnabled));
actionBar.setBackgroundDrawable(getActionBarBackground(context, themeRes, accentColor, backgroundOption, outlineEnabled));
actionBar.setSplitBackgroundDrawable(getActionBarSplitBackground(context, themeRes));
actionBar.setStackedBackgroundDrawable(getActionBarBackground(context, themeRes, accentColor, outlineEnabled));
actionBar.setStackedBackgroundDrawable(getActionBarBackground(context, themeRes, accentColor, backgroundOption, outlineEnabled));
}
public static void applyActionBarBackground(final android.support.v7.app.ActionBar actionBar, final Context context,
final int themeRes, final int accentColor, boolean outlineEnabled) {
final int themeRes, final int accentColor, String backgroundOption, boolean outlineEnabled) {
if (actionBar == null || context == null) return;
actionBar.setBackgroundDrawable(getActionBarBackground(context, themeRes, accentColor, outlineEnabled));
actionBar.setBackgroundDrawable(getActionBarBackground(context, themeRes, accentColor, backgroundOption, outlineEnabled));
actionBar.setSplitBackgroundDrawable(getActionBarSplitBackground(context, themeRes));
actionBar.setStackedBackgroundDrawable(getActionBarStackedBackground(context, themeRes, accentColor, outlineEnabled));
}
@ -186,17 +188,19 @@ public class ThemeUtils implements Constants {
}
public static void applySupportActionModeBackground(ActionMode mode, FragmentActivity activity,
int themeRes, int accentColor, boolean outlineEnabled) {
int themeRes, int accentColor,
String backgroundOption, boolean outlineEnabled) {
// Very dirty implementation
if (!(mode instanceof SupportActionModeWrapper) || !(activity instanceof IThemedActivity))
return;
final android.support.v7.view.ActionMode modeCompat = SupportActionModeWrapperTrojan.getWrappedObject((SupportActionModeWrapper) mode);
applySupportActionModeBackground(modeCompat, activity, themeRes, accentColor, outlineEnabled);
applySupportActionModeBackground(modeCompat, activity, themeRes, accentColor, backgroundOption, outlineEnabled);
}
public static void applySupportActionModeBackground(android.support.v7.view.ActionMode modeCompat,
FragmentActivity activity, int themeRes,
int accentColor, boolean outlineEnabled) {
int accentColor, String backgroundOption, boolean outlineEnabled) {
// Very dirty implementation
if (!(modeCompat instanceof ActionModeImpl)) return;
try {
WindowDecorActionBar actionBar = null;
@ -209,16 +213,46 @@ public class ThemeUtils implements Constants {
}
}
if (actionBar == null) return;
final Context context = actionBar.getThemedContext();
final Field contextViewField = WindowDecorActionBar.class.getDeclaredField("mContextView");
final Field decorToolbarField = WindowDecorActionBar.class.getDeclaredField("mDecorToolbar");
contextViewField.setAccessible(true);
final View view = (View) contextViewField.get(actionBar);
if (view == null) return;
ViewUtils.setBackground(view, getActionBarBackground(activity, themeRes, accentColor, outlineEnabled));
decorToolbarField.setAccessible(true);
final View contextView = (View) contextViewField.get(actionBar);
final DecorToolbar decorToolbar = (DecorToolbar) decorToolbarField.get(actionBar);
if (contextView == null || decorToolbar == null) return;
final Toolbar toolbar = (Toolbar) decorToolbar.getViewGroup();
final int actionBarColor;
if (isDarkTheme(themeRes)) {
actionBarColor = context.getResources().getColor(R.color.background_color_action_bar_dark);
} else {
actionBarColor = accentColor;
}
toolbar.setTitleTextColor(getContrastActionBarTitleColor(context, themeRes, actionBarColor));
ViewUtils.setBackground(contextView, getActionBarBackground(activity, themeRes, accentColor, backgroundOption, outlineEnabled));
} catch (Exception e) {
e.printStackTrace();
}
}
public static int getContrastActionBarTitleColor(Context context, int theme, int color) {
if (isDarkTheme(theme) || ColorUtils.getYIQLuminance(color) < 192) {
//return light text color
return Color.WHITE;
}
//return dark text color
return Color.BLACK;
}
public static int getContrastActionBarItemColor(Context context, int theme, int color) {
if (isDarkTheme(theme) || ColorUtils.getYIQLuminance(color) < 192) {
//return light text color
return Color.WHITE;
}
//return dark text color
return Color.BLACK;
}
public static void applyWindowBackground(Context context, Window window, int theme, String option, int alpha) {
if (isWindowFloating(context, theme)) return;
if (VALUE_THEME_BACKGROUND_TRANSPARENT.equals(option)) {
@ -291,6 +325,7 @@ public class ThemeUtils implements Constants {
}
}
@Deprecated
@NonNull
public static Drawable getActionBarBackground(final Context context, final int themeRes,
final int accentColor, boolean outlineEnabled) {
@ -304,6 +339,20 @@ public class ThemeUtils implements Constants {
return applyActionBarDrawable(context, d, isTransparentBackground(context));
}
@NonNull
public static Drawable getActionBarBackground(final Context context, final int themeRes,
final int accentColor, final String backgroundOption,
final boolean outlineEnabled) {
final int actionBarColor;
if (isDarkTheme(themeRes)) {
actionBarColor = context.getResources().getColor(R.color.background_color_action_bar_dark);
} else {
actionBarColor = accentColor;
}
final ColorDrawable d = new ActionBarColorDrawable(actionBarColor, outlineEnabled);
return applyActionBarDrawable(context, d, isTransparentBackground(backgroundOption));
}
public static Context getActionBarContext(final Context context) {
@SuppressLint("InlinedApi")
final TypedArray a = context.obtainStyledAttributes(new int[]{R.attr.actionBarTheme,

View File

@ -106,6 +106,14 @@ public class UserViewHolder extends ViewHolder implements OnClickListener, OnLon
}
}
public ShapedImageView getProfileImageView() {
return profileImageView;
}
public ImageView getProfileTypeView() {
return profileTypeView;
}
@Override
public void onClick(View v) {
if (userClickListener == null) return;