theme fixes

crash fixes
This commit is contained in:
Mariotaku Lee 2016-03-18 15:41:17 +08:00
parent 13d87b8d87
commit c1ecd01cb0
35 changed files with 373 additions and 177 deletions

View File

@ -0,0 +1,23 @@
package android.support.v7.widget;
import android.content.Context;
import android.support.v7.widget.android.support.v7.view.menu.TwidereActionMenuItemView;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by mariotaku on 16/3/18.
*/
public class TwidereActionMenuView extends ActionMenuView {
public TwidereActionMenuView(Context context) {
super(context);
}
public TwidereActionMenuView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public View createActionMenuView(Context context, AttributeSet attrs) {
return new TwidereActionMenuItemView(context, attrs);
}
}

View File

@ -0,0 +1,107 @@
package android.support.v7.widget.android.support.v7.view.menu;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.annotation.Nullable;
import android.support.v7.view.menu.ActionMenuItemView;
import android.support.v7.view.menu.MenuItemImpl;
import android.util.AttributeSet;
import android.view.View;
import com.afollestad.appthemeengine.ATE;
import com.afollestad.appthemeengine.ATEActivity;
import com.afollestad.appthemeengine.inflation.ViewInterface;
import com.afollestad.appthemeengine.util.ATEUtil;
import com.afollestad.appthemeengine.util.TintHelper;
import com.afollestad.appthemeengine.viewprocessors.ViewProcessor;
import org.mariotaku.twidere.util.ThemeUtils;
/**
* Created by mariotaku on 16/3/18.
*/
public class TwidereActionMenuItemView extends ActionMenuItemView implements ViewInterface {
public TwidereActionMenuItemView(Context context) {
super(context);
init(context, null);
}
public TwidereActionMenuItemView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, null);
}
public TwidereActionMenuItemView(Context context, AttributeSet attrs, @Nullable ATEActivity keyContext) {
super(context, attrs);
init(context, keyContext);
}
private String mKey;
private int mTintColor;
private Drawable mIcon;
private boolean mCheckedActionView;
private void init(Context context, @Nullable ATEActivity keyContext) {
if (keyContext == null && context instanceof ATEActivity)
keyContext = (ATEActivity) context;
mKey = null;
if (keyContext != null)
mKey = keyContext.getATEKey();
if (mIcon != null)
setIcon(mIcon); // invalidates initial icon tint
else invalidateTintColor();
ATE.themeView(context, this, mKey);
setTextColor(mTintColor); // sets menu item text color
}
private void invalidateTintColor() {
final int colorBackground = ATEUtil.resolveColor(getContext(), android.R.attr.colorBackground);
mTintColor = ThemeUtils.getActionIconColor(getContext(), colorBackground);
}
@Override
public void setIcon(Drawable icon) {
invalidateTintColor();
mIcon = TintHelper.createTintedDrawable(icon, mTintColor);
super.setIcon(mIcon);
invalidateActionView();
}
@Override
public void setTitle(CharSequence title) {
super.setTitle(title);
invalidateActionView();
}
@SuppressWarnings("unchecked")
private void invalidateActionView() {
if (mCheckedActionView) return;
mCheckedActionView = true;
View actionView = getActionView();
if (actionView != null) {
ViewProcessor processor = ATE.getViewProcessor(actionView.getClass());
if (processor != null)
processor.process(getContext(), mKey, actionView, null);
}
}
@Nullable
private View getActionView() {
final MenuItemImpl menuImpl = getItemData();
if (menuImpl == null) return null;
return menuImpl.getActionView();
}
@Override
public boolean setsStatusBarColor() {
return false;
}
@Override
public boolean setsToolbarColor() {
return false;
}
}

View File

@ -0,0 +1,63 @@
package com.afollestad.appthemeengine.inflation;
import android.content.Context;
import android.support.annotation.Nullable;
import android.support.v7.widget.AppCompatMultiAutoCompleteTextView;
import android.util.AttributeSet;
import com.afollestad.appthemeengine.ATE;
import com.afollestad.appthemeengine.ATEActivity;
import com.afollestad.appthemeengine.tagprocessors.ATEDefaultTags;
/**
* @author Aidan Follestad (afollestad)
*/
public class ATEMultiAutoCompleteTextView2 extends AppCompatMultiAutoCompleteTextView implements ViewInterface, PostInflationApplier {
public ATEMultiAutoCompleteTextView2(Context context) {
super(context);
init(context, null);
}
public ATEMultiAutoCompleteTextView2(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, null);
}
public ATEMultiAutoCompleteTextView2(Context context, AttributeSet attrs, @Nullable ATEActivity keyContext, boolean waitForInflate) {
super(context, attrs);
mWaitForInflate = waitForInflate;
init(context, keyContext);
}
private boolean mWaitForInflate;
private ATEActivity mKeyContext;
private void init(Context context, @Nullable ATEActivity keyContext) {
ATEDefaultTags.process(this);
if (mWaitForInflate) {
mKeyContext = keyContext;
ATE.addPostInflationView(this);
return;
}
ATEViewUtil.init(keyContext, this, context);
}
@Override
public boolean setsStatusBarColor() {
return false;
}
@Override
public boolean setsToolbarColor() {
return false;
}
@Override
public void postApply() {
if(!mWaitForInflate) return;
mWaitForInflate = false;
ATEViewUtil.init(mKeyContext, this, getContext());
mKeyContext = null;
}
}

View File

@ -29,17 +29,18 @@ import android.view.MotionEvent;
import com.squareup.otto.Bus;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.activity.ThemedAppCompatActivity;
import org.mariotaku.twidere.activity.iface.IControlBarActivity;
import org.mariotaku.twidere.activity.iface.IExtendedActivity;
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback;
import org.mariotaku.twidere.util.MediaLoaderWrapper;
import org.mariotaku.twidere.util.NotificationManagerWrapper;
import org.mariotaku.twidere.util.ReadStateManager;
import org.mariotaku.twidere.util.SharedPreferencesWrapper;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.UserColorNameManager;
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper;
import org.mariotaku.twidere.view.iface.IExtendedView.OnFitSystemWindowsListener;
@ -65,6 +66,10 @@ public class BaseAppCompatActivity extends ThemedAppCompatActivity implements Co
protected SharedPreferencesWrapper mPreferences;
@Inject
protected NotificationManagerWrapper mNotificationManager;
@Inject
protected MediaLoaderWrapper mMediaLoader;
@Inject
protected UserColorNameManager mUserColorNameManager;
private ActionHelper mActionHelper = new ActionHelper(this);

View File

@ -46,6 +46,7 @@ import android.os.Bundle;
import android.os.Parcelable;
import android.provider.BaseColumns;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
@ -61,6 +62,7 @@ import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.ItemDecoration;
import android.support.v7.widget.RecyclerView.State;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.support.v7.widget.Toolbar;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.text.Editable;
import android.text.Spannable;
@ -88,6 +90,9 @@ import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.afollestad.appthemeengine.Config;
import com.afollestad.appthemeengine.customizers.ATEToolbarCustomizer;
import com.afollestad.appthemeengine.util.ATEUtil;
import com.github.johnpersano.supertoasts.SuperToast;
import com.github.johnpersano.supertoasts.SuperToast.Duration;
import com.github.johnpersano.supertoasts.SuperToast.OnDismissListener;
@ -166,8 +171,8 @@ import java.util.TreeSet;
import javax.inject.Inject;
public class ComposeActivity extends ThemedFragmentActivity implements OnMenuItemClickListener,
OnClickListener, OnLongClickListener, Callback {
public class ComposeActivity extends BaseAppCompatActivity implements OnMenuItemClickListener,
OnClickListener, OnLongClickListener, Callback, ATEToolbarCustomizer {
// Constants
private static final String FAKE_IMAGE_LINK = "https://www.example.com/fake_image.jpg";
@ -597,11 +602,11 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
if (accounts.length == 1) {
mCountView.setText(null);
final ParcelableAccount account = accounts[0];
mImageLoader.displayProfileImage(mProfileImageView, account);
mMediaLoader.displayProfileImage(mProfileImageView, account);
mProfileImageView.setBorderColor(account.color);
} else {
mCountView.setText(String.valueOf(accounts.length));
mImageLoader.cancelDisplayTask(mProfileImageView);
mMediaLoader.cancelDisplayTask(mProfileImageView);
mProfileImageView.setImageDrawable(null);
mProfileImageView.setBorderColors(Utils.getAccountColors(accounts));
}
@ -1387,6 +1392,16 @@ public class ComposeActivity extends ThemedFragmentActivity implements OnMenuIte
mSendTextCountView.setTextCount(validatedCount);
}
@Override
public int getLightToolbarMode(@Nullable Toolbar toolbar) {
return Config.LIGHT_TOOLBAR_AUTO;
}
@Override
public int getToolbarColor(@Nullable Toolbar toolbar) {
return ATEUtil.resolveColor(this, android.R.attr.panelColorBackground);
}
static class ComposeLocationListener implements LocationListener {
final WeakReference<ComposeActivity> mActivityRef;

View File

@ -134,7 +134,7 @@ public class SettingsActivity extends BaseAppCompatActivity implements OnItemCli
R.xml.preferences_refresh);
mEntriesAdapter.addPreference(R.drawable.ic_action_notification, getString(R.string.notifications),
R.xml.preferences_notifications);
mEntriesAdapter.addPreference(R.drawable.ic_action_server, getString(R.string.network),
mEntriesAdapter.addPreference(R.drawable.ic_action_web, getString(R.string.network),
R.xml.preferences_network);
mEntriesAdapter.addPreference(R.drawable.ic_action_status_compose, getString(R.string.compose),
R.xml.preferences_compose);

View File

@ -26,7 +26,8 @@ import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatDelegate;
import android.support.v7.widget.Toolbar;
import android.support.v7.view.menu.ActionMenuItemView;
import android.support.v7.widget.TwidereActionMenuView;
import android.util.AttributeSet;
import android.view.View;
import android.view.Window;
@ -39,8 +40,6 @@ import org.mariotaku.twidere.activity.iface.IAppCompatActivity;
import org.mariotaku.twidere.activity.iface.IThemedActivity;
import org.mariotaku.twidere.util.StrictModeUtils;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.ShapedImageView.ShapeStyle;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
@ -140,21 +139,44 @@ public abstract class ThemedAppCompatActivity extends ATEActivity implements Con
view = newInstance(name, context, attrs);
}
if (view == null) {
for (String prefix : sClassPrefixList) {
view = newInstance(prefix + name, context, attrs);
if (view != null) break;
}
view = newInstance(name, context, attrs);
}
if (view != null) {
return view;
}
}
if (parent instanceof TwidereActionMenuView) {
final Class<?> cls = findClass(name);
if (cls != null && ActionMenuItemView.class.isAssignableFrom(cls)) {
return ((TwidereActionMenuView) parent).createActionMenuView(context, attrs);
}
}
return super.onCreateView(parent, name, context, attrs);
}
private Class<?> findClass(String name) {
Class<?> cls = null;
try {
cls = Class.forName(name);
} catch (ClassNotFoundException e) {
// Ignore
}
if (cls != null) return cls;
for (String prefix : sClassPrefixList) {
try {
cls = Class.forName(prefix + name);
} catch (ClassNotFoundException e) {
// Ignore
}
if (cls != null) return cls;
}
return null;
}
private View newInstance(String name, Context context, AttributeSet attrs) {
try {
final Class<?> cls = Class.forName(name);
final Class<?> cls = findClass(name);
if (cls == null) throw new ClassNotFoundException(name);
final Constructor<?> constructor = cls.getConstructor(Context.class, AttributeSet.class);
return (View) constructor.newInstance(context, attrs);
} catch (InstantiationException e) {

View File

@ -68,8 +68,10 @@ import org.mariotaku.twidere.util.theme.ActionBarContextViewViewProcessor;
import org.mariotaku.twidere.util.theme.ExtendedSwipeRefreshLayoutViewProcessor;
import org.mariotaku.twidere.util.theme.FloatingActionButtonViewProcessor;
import org.mariotaku.twidere.util.theme.TabPagerIndicatorViewProcessor;
import org.mariotaku.twidere.util.theme.TimelineContentTextViewViewProcessor;
import org.mariotaku.twidere.view.TabPagerIndicator;
import org.mariotaku.twidere.view.themed.ExtendedSwipeRefreshLayout;
import org.mariotaku.twidere.view.ExtendedSwipeRefreshLayout;
import org.mariotaku.twidere.view.TimelineContentTextView;
public class TwidereApplication extends Application implements Constants,
OnSharedPreferenceChangeListener {
@ -131,6 +133,7 @@ public class TwidereApplication extends Application implements Constants,
ATE.registerViewProcessor(FloatingActionButton.class, new FloatingActionButtonViewProcessor());
ATE.registerViewProcessor(ActionBarContextView.class, new ActionBarContextViewViewProcessor());
ATE.registerViewProcessor(ExtendedSwipeRefreshLayout.class, new ExtendedSwipeRefreshLayoutViewProcessor());
ATE.registerViewProcessor(TimelineContentTextView.class, new TimelineContentTextViewViewProcessor());
final SharedPreferences preferences = getSharedPreferences();
if (!ATE.config(this, null).isConfigured()) {
final int themeColor = preferences.getInt(KEY_THEME_COLOR, ContextCompat.getColor(this,

View File

@ -49,7 +49,7 @@ import org.mariotaku.twidere.util.TwidereColorUtils;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.HeaderDrawerLayout;
import org.mariotaku.twidere.view.iface.IExtendedView;
import org.mariotaku.twidere.view.themed.ExtendedSwipeRefreshLayout;
import org.mariotaku.twidere.view.ExtendedSwipeRefreshLayout;
/**
* Created by mariotaku on 15/10/26.

View File

@ -163,7 +163,6 @@ import org.mariotaku.twidere.view.CardMediaContainer.OnMediaClickListener;
import org.mariotaku.twidere.view.ColorLabelRelativeLayout;
import org.mariotaku.twidere.view.ExtendedRecyclerView;
import org.mariotaku.twidere.view.ForegroundColorView;
import org.mariotaku.twidere.view.StatusTextView;
import org.mariotaku.twidere.view.TwitterCardContainer;
import org.mariotaku.twidere.view.holder.GapViewHolder;
import org.mariotaku.twidere.view.holder.LoadIndicatorViewHolder;
@ -915,7 +914,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
private final ActionMenuView menuBar;
private final TextView nameView, screenNameView;
private final StatusTextView textView;
private final TextView textView;
private final TextView quotedTextView;
private final TextView quotedNameView, quotedScreenNameView;
private final ImageView profileImageView;
@ -951,7 +950,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
menuBar = (ActionMenuView) itemView.findViewById(R.id.menu_bar);
nameView = (TextView) itemView.findViewById(R.id.name);
screenNameView = (TextView) itemView.findViewById(R.id.screen_name);
textView = (StatusTextView) itemView.findViewById(R.id.text);
textView = (TextView) itemView.findViewById(R.id.text);
profileImageView = (ImageView) itemView.findViewById(R.id.profile_image);
profileTypeView = (ImageView) itemView.findViewById(R.id.profile_type);
timeSourceView = (TextView) itemView.findViewById(R.id.time_source);

View File

@ -183,7 +183,7 @@ public abstract class TwitterAPIStatusesLoader extends ParcelableStatusesLoader
final boolean filtered = shouldFilterStatus(db, status);
if (filtered) {
if (!status.is_gap && i != size - 1) {
data.remove(i);
data.remove(status);
} else {
status.is_filtered = true;
}

View File

@ -657,6 +657,7 @@ public class ThemeUtils implements Constants {
wrapMenuIcon(view, colorDark, colorLight, excludeGroups);
}
public static int getActionIconColor(Context context) {
final int colorDark = ContextCompat.getColor(context, R.color.action_icon_dark);
final int colorLight = ContextCompat.getColor(context, R.color.action_icon_light);
@ -664,6 +665,12 @@ public class ThemeUtils implements Constants {
return TwidereColorUtils.getContrastYIQ(itemBackgroundColor, colorDark, colorLight);
}
public static int getActionIconColor(Context context, int backgroundColor) {
final int colorDark = ContextCompat.getColor(context, R.color.action_icon_dark);
final int colorLight = ContextCompat.getColor(context, R.color.action_icon_light);
return ATEUtil.isColorLight(backgroundColor) ? colorDark : colorLight;
}
public static void wrapMenuIcon(ActionMenuView view, int colorDark, int colorLight, int... excludeGroups) {
final Context context = view.getContext();
final int itemBackgroundColor = ThemeUtils.getThemeBackgroundColor(context);

View File

@ -6,7 +6,7 @@ import android.support.annotation.NonNull;
import com.afollestad.appthemeengine.Config;
import com.afollestad.appthemeengine.viewprocessors.ViewProcessor;
import org.mariotaku.twidere.view.themed.ExtendedSwipeRefreshLayout;
import org.mariotaku.twidere.view.ExtendedSwipeRefreshLayout;
/**
* Created by mariotaku on 16/3/18.

View File

@ -0,0 +1,23 @@
package org.mariotaku.twidere.util.theme;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.afollestad.appthemeengine.Config;
import com.afollestad.appthemeengine.viewprocessors.ViewProcessor;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.view.TimelineContentTextView;
/**
* Created by mariotaku on 16/3/18.
*/
public class TimelineContentTextViewViewProcessor implements ViewProcessor<TimelineContentTextView, Object> {
@Override
public void process(@NonNull Context context, @Nullable String key, @Nullable TimelineContentTextView target, @Nullable Object extra) {
if (target == null) return;
final int accentColor = Config.accentColor(context, key);
target.setLinkTextColor(ThemeUtils.getOptimalAccentColor(accentColor, target.getCurrentTextColor()));
}
}

View File

@ -22,7 +22,6 @@ package org.mariotaku.twidere.view;
import android.content.Context;
import android.content.res.ColorStateList;
import android.support.annotation.NonNull;
import android.support.v7.widget.AppCompatMultiAutoCompleteTextView;
import android.text.InputType;
import android.text.Selection;
import android.text.method.ArrowKeyMovementMethod;
@ -31,6 +30,9 @@ import android.util.AttributeSet;
import android.view.View;
import android.widget.AdapterView;
import com.afollestad.appthemeengine.inflation.ATEMultiAutoCompleteTextView;
import com.afollestad.appthemeengine.inflation.ATEMultiAutoCompleteTextView2;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.ComposeAutoCompleteAdapter;
import org.mariotaku.twidere.model.UserKey;
@ -38,7 +40,7 @@ import org.mariotaku.twidere.util.EmojiSupportUtils;
import org.mariotaku.twidere.util.widget.StatusTextTokenizer;
import org.mariotaku.twidere.view.iface.IThemeBackgroundTintView;
public class ComposeEditText extends AppCompatMultiAutoCompleteTextView implements IThemeBackgroundTintView {
public class ComposeEditText extends ATEMultiAutoCompleteTextView2 implements IThemeBackgroundTintView {
private ComposeAutoCompleteAdapter mAdapter;
private UserKey mAccountKey;
@ -48,11 +50,7 @@ public class ComposeEditText extends AppCompatMultiAutoCompleteTextView implemen
}
public ComposeEditText(final Context context, final AttributeSet attrs) {
this(context, attrs, R.attr.autoCompleteTextViewStyle);
}
public ComposeEditText(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
super(context, attrs);
EmojiSupportUtils.initForTextView(this);
setTokenizer(new StatusTextTokenizer());
setOnItemClickListener(new AdapterView.OnItemClickListener() {

View File

@ -17,7 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.view.themed;
package org.mariotaku.twidere.view;
import android.content.Context;
import android.graphics.Rect;

View File

@ -24,6 +24,7 @@ import android.content.res.Resources;
import android.content.res.TypedArray;
import android.support.annotation.Nullable;
import android.support.v4.text.BidiFormatter;
import android.support.v7.widget.AppCompatTextView;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
@ -34,12 +35,11 @@ import android.util.AttributeSet;
import android.util.TypedValue;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.view.themed.ThemedTextView;
/**
* Created by mariotaku on 15/5/28.
*/
public class NameView extends ThemedTextView {
public class NameView extends AppCompatTextView {
private boolean mNameFirst;
private boolean mTwoLine;

View File

@ -22,19 +22,19 @@ package org.mariotaku.twidere.view;
import android.content.Context;
import android.os.Handler;
import android.os.SystemClock;
import android.support.v7.widget.AppCompatTextView;
import android.text.format.DateUtils;
import android.util.AttributeSet;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.view.themed.ThemedTextView;
import java.lang.ref.WeakReference;
import static android.text.format.DateUtils.getRelativeTimeSpanString;
import static org.mariotaku.twidere.util.Utils.formatSameDayTime;
public class ShortTimeView extends ThemedTextView implements Constants {
public class ShortTimeView extends AppCompatTextView implements Constants {
private static final long TICKER_DURATION = 5000L;

View File

@ -1,48 +0,0 @@
package org.mariotaku.twidere.view;
import android.content.Context;
import android.text.method.LinkMovementMethod;
import android.text.method.MovementMethod;
import android.util.AttributeSet;
import android.view.MotionEvent;
import org.mariotaku.twidere.util.EmojiSupportUtils;
import org.mariotaku.twidere.view.themed.ThemedTextView;
public class StatusTextView extends ThemedTextView {
public StatusTextView(final Context context) {
super(context);
EmojiSupportUtils.initForTextView(this);
}
public StatusTextView(final Context context, final AttributeSet attrs) {
super(context, attrs);
EmojiSupportUtils.initForTextView(this);
}
public StatusTextView(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
EmojiSupportUtils.initForTextView(this);
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
// FIXME simple workaround to https://code.google.com/p/android/issues/detail?id=191430
// Android clears TextView when setText(), so setText before touch
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
if (getSelectionEnd() != getSelectionStart()) {
final CharSequence text = getText();
setText(null);
setText(text);
}
}
return super.dispatchTouchEvent(event);
}
@Override
protected MovementMethod getDefaultMovementMethod() {
return LinkMovementMethod.getInstance();
}
}

View File

@ -20,6 +20,7 @@
package org.mariotaku.twidere.view;
import android.content.Context;
import android.support.v7.widget.AppCompatTextView;
import android.text.Layout;
import android.text.Spannable;
import android.text.method.LinkMovementMethod;
@ -29,13 +30,12 @@ import android.util.AttributeSet;
import android.view.MotionEvent;
import org.mariotaku.twidere.util.EmojiSupportUtils;
import org.mariotaku.twidere.view.themed.ThemedTextView;
/**
* Returns true when not clicking links
* Created by mariotaku on 15/11/20.
*/
public class TimelineContentTextView extends ThemedTextView {
public class TimelineContentTextView extends AppCompatTextView {
private boolean mFirstNotLink;
public TimelineContentTextView(Context context) {
@ -54,8 +54,17 @@ public class TimelineContentTextView extends ThemedTextView {
}
@Override
protected MovementMethod getDefaultMovementMethod() {
return LinkMovementMethod.getInstance();
public boolean dispatchTouchEvent(MotionEvent event) {
// FIXME simple workaround to https://code.google.com/p/android/issues/detail?id=191430
// Android clears TextView when setText(), so setText before touch
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
if (getSelectionEnd() != getSelectionStart()) {
final CharSequence text = getText();
setText(null);
setText(text);
}
}
return super.dispatchTouchEvent(event);
}
@Override
@ -90,11 +99,8 @@ public class TimelineContentTextView extends ThemedTextView {
}
@Override
public int getBaseline() {
try {
return super.getBaseline();
} catch (IndexOutOfBoundsException e) {
return -1;
}
protected MovementMethod getDefaultMovementMethod() {
return LinkMovementMethod.getInstance();
}
}

View File

@ -1,42 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 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.themed;
import android.content.Context;
import android.support.v7.widget.AppCompatTextView;
import android.util.AttributeSet;
/**
* Created by mariotaku on 15/6/30.
*/
public class ThemedTextView extends AppCompatTextView {
public ThemedTextView(Context context) {
super(context);
}
public ThemedTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ThemedTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
}

View File

@ -99,7 +99,7 @@
android:color="?android:textColorSecondary"
android:src="@drawable/ic_action_location"/>
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:id="@+id/location_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -201,12 +201,13 @@
android:layout_toStartOf="@+id/send"
android:scrollbars="none">
<android.support.v7.widget.ActionMenuView
<android.support.v7.widget.TwidereActionMenuView
android:id="@+id/menu_bar"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="@null"/>
android:background="@null"
android:tag="ate_ignore"/>
</FrameLayout>
<LinearLayout

View File

@ -14,7 +14,7 @@
android:orientation="vertical"
android:padding="@dimen/element_spacing_normal">
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:id="@+id/count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -26,7 +26,7 @@
android:textStyle="bold"
tools:text="255"/>
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:id="@+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@ -108,7 +108,7 @@
</LinearLayout>
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -134,7 +134,7 @@
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"/>
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:id="@+id/summary"
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@ -18,7 +18,7 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:id="@+id/gap_indicator"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"

View File

@ -74,7 +74,7 @@
android:textStyle="italic"
tools:text="External group at gnu.io"/>
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:id="@+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -95,7 +95,7 @@
android:orientation="horizontal"
android:paddingTop="@dimen/element_spacing_small">
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:id="@+id/members_count"
android:layout_width="0dp"
android:layout_height="wrap_content"
@ -107,7 +107,7 @@
android:textAppearance="?android:attr/textAppearanceSmall"
tools:text="255"/>
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:id="@+id/admins_count"
android:layout_width="0dp"
android:layout_height="wrap_content"

View File

@ -47,7 +47,7 @@
android:textColor="?android:attr/textColorSecondary"
tools:text="@string/sample_status_text"/>
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@ -74,7 +74,7 @@
android:layout_toRightOf="@+id/status_info_icon"
tools:visibility="visible"/>
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:id="@+id/status_info_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@ -78,7 +78,7 @@
tools:text="Created by user"/>
</LinearLayout>
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:id="@+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -98,7 +98,7 @@
android:orientation="horizontal"
android:paddingTop="@dimen/element_spacing_small">
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:id="@+id/members_count"
android:layout_width="0dp"
android:layout_height="wrap_content"
@ -109,7 +109,7 @@
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"/>
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:id="@+id/subscribers_count"
android:layout_width="0dp"
android:layout_height="wrap_content"

View File

@ -26,7 +26,7 @@
<include layout="@layout/layout_content_fragment_common"/>
<org.mariotaku.twidere.view.themed.ExtendedSwipeRefreshLayout
<org.mariotaku.twidere.view.ExtendedSwipeRefreshLayout
android:id="@+id/swipe_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -42,5 +42,5 @@
android:focusable="true"
android:listSelector="?selectableItemBackground"/>
</org.mariotaku.twidere.view.themed.ExtendedSwipeRefreshLayout>
</org.mariotaku.twidere.view.ExtendedSwipeRefreshLayout>
</FrameLayout>

View File

@ -25,7 +25,7 @@
<include layout="@layout/layout_content_fragment_common"/>
<org.mariotaku.twidere.view.themed.ExtendedSwipeRefreshLayout
<org.mariotaku.twidere.view.ExtendedSwipeRefreshLayout
android:id="@+id/swipe_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -39,5 +39,5 @@
android:focusable="true"
android:scrollbars="vertical"/>
</org.mariotaku.twidere.view.themed.ExtendedSwipeRefreshLayout>
</org.mariotaku.twidere.view.ExtendedSwipeRefreshLayout>
</FrameLayout>

View File

@ -29,7 +29,7 @@
android:orientation="vertical"
android:splitMotionEvents="false">
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:id="@+id/retweeted_by"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -104,7 +104,7 @@
android:layout_height="wrap_content"
android:orientation="horizontal">
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -113,7 +113,7 @@
android:textColor="?android:textColorPrimary"
tools:text="Name"/>
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:id="@+id/screen_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -125,7 +125,7 @@
tools:text="\@username"/>
</LinearLayout>
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:id="@+id/time_source"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -164,7 +164,7 @@
</org.mariotaku.twidere.view.ColorLabelRelativeLayout>
<org.mariotaku.twidere.view.StatusTextView
<org.mariotaku.twidere.view.TimelineContentTextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -242,7 +242,7 @@
android:visibility="gone"
tools:visibility="visible">
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:id="@+id/quoted_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -251,7 +251,7 @@
android:textColor="?android:textColorPrimary"
tools:text="Name"/>
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:id="@+id/quoted_screen_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -263,7 +263,7 @@
tools:text="\@username"/>
</LinearLayout>
<org.mariotaku.twidere.view.StatusTextView
<org.mariotaku.twidere.view.TimelineContentTextView
android:id="@+id/quoted_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -396,11 +396,12 @@
android:splitMotionEvents="false"
tools:visibility="invisible"/>
<android.support.v7.widget.ActionMenuView
<android.support.v7.widget.TwidereActionMenuView
android:id="@+id/menu_bar"
android:layout_width="match_parent"
android:layout_height="?android:actionBarSize"
android:layout_below="@+id/counts_users_height_holder"
android:clipChildren="false"/>
android:clipChildren="false"
android:tag="ate_ignore"/>
</RelativeLayout>

View File

@ -91,7 +91,7 @@
android:minHeight="@dimen/element_size_normal"
android:orientation="vertical">
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -100,7 +100,7 @@
android:textColor="?android:textColorPrimary"
tools:text="Name"/>
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:id="@+id/screen_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -110,7 +110,7 @@
android:textColor="?android:textColorPrimary"
tools:text="\@screenname"/>
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:id="@+id/following_you_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -156,7 +156,7 @@
android:orientation="vertical"
android:padding="@dimen/element_spacing_small">
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/element_spacing_small"
@ -195,7 +195,7 @@
android:color="?android:textColorPrimary"
android:src="@drawable/ic_action_location"/>
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:id="@+id/location"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -252,7 +252,7 @@
android:color="?android:textColorPrimary"
android:src="@drawable/ic_action_time"/>
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:id="@+id/created_at"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -289,7 +289,7 @@
android:orientation="vertical"
android:padding="@dimen/element_spacing_small">
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:id="@+id/followers_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -298,7 +298,7 @@
android:textColor="?android:textColorPrimary"
tools:text="255"/>
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
@ -318,7 +318,7 @@
android:orientation="vertical"
android:padding="@dimen/element_spacing_small">
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:id="@+id/friends_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -327,7 +327,7 @@
android:textColor="?android:textColorPrimary"
tools:text="255"/>
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
@ -347,7 +347,7 @@
android:orientation="vertical"
android:padding="@dimen/element_spacing_small">
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:id="@+id/listed_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -356,7 +356,7 @@
android:textColor="?android:textColorPrimary"
tools:text="255"/>
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
@ -376,7 +376,7 @@
android:orientation="vertical"
android:padding="@dimen/element_spacing_small">
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:id="@+id/groups_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -385,7 +385,7 @@
android:textColor="?android:textColorPrimary"
tools:text="255"/>
<org.mariotaku.twidere.view.themed.ThemedTextView
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"

View File

@ -22,6 +22,7 @@
<!-- ATE attributes -->
<item name="ateThemeKey">light</item>
<item name="actionBarTheme">@null</item>
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
</style>
@ -50,6 +51,8 @@
<!-- ATE attributes -->
<item name="ateThemeKey">light</item>
<item name="actionBarTheme">@null</item>
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
</style>
@ -75,11 +78,14 @@
<!-- ATE attributes -->
<item name="ateThemeKey">light</item>
<item name="actionBarTheme">@null</item>
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
</style>
<style name="Theme.Twidere.Compose" parent="Theme.Twidere.Dialog">
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="windowActionModeOverlay">false</item>

View File

@ -23,6 +23,7 @@
<!-- ATE attributes -->
<item name="ateThemeKey">dark</item>
<item name="actionBarTheme">@null</item>
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
</style>
@ -58,6 +59,8 @@
<!-- ATE attributes -->
<item name="ateThemeKey">dark</item>
<item name="actionBarTheme">@null</item>
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
</style>
<style name="Theme.Twidere.Dialog" parent="Theme.AppCompat.Dialog">
@ -82,6 +85,8 @@
<!-- ATE attributes -->
<item name="ateThemeKey">dark</item>
<item name="actionBarTheme">@null</item>
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
</style>
@ -164,6 +169,8 @@
<!-- ATE attributes -->
<item name="ateThemeKey">dark</item>
<item name="actionBarTheme">@null</item>
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
</style>
<style name="Theme.Nyan" parent="Theme.AppCompat.NoActionBar">