fixed crashes under lollipop

fixed theme
This commit is contained in:
Mariotaku Lee 2015-01-20 01:46:14 +08:00
parent 450818eff2
commit 549f478806
36 changed files with 448 additions and 417 deletions

View File

@ -287,6 +287,8 @@ public interface SharedPreferenceConstants {
@Preference(type = STRING, hasDefault = true, defaultString = VALUE_MEDIA_PREVIEW_STYLE_CROP)
public static final String KEY_MEDIA_PREVIEW_STYLE = "media_preview_style";
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false)
public static final String KEY_MEDIA_PREVIEW = "media_preview";
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false)
public static final String KEY_SORT_TIMELINE_BY_ID = "sort_timeline_by_id";
@Preference(type = STRING, hasDefault = true)
public static final String KEY_PROFILE_IMAGE_STYLE = "profile_image_style";

View File

@ -33,8 +33,8 @@ import org.mariotaku.jsonserializer.JSONParcelable;
import org.mariotaku.jsonserializer.JSONSerializer;
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses;
import org.mariotaku.twidere.util.HtmlEscapeHelper;
import org.mariotaku.twidere.util.TwitterContentUtils;
import org.mariotaku.twidere.util.ParseUtils;
import org.mariotaku.twidere.util.TwitterContentUtils;
import org.mariotaku.twidere.util.content.ContentValuesUtils;
import java.util.Arrays;
@ -107,7 +107,7 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
public final String retweeted_by_name, retweeted_by_screen_name, retweeted_by_profile_image,
text_html, text_plain, user_name, user_screen_name, in_reply_to_name, in_reply_to_screen_name,
source, user_profile_image_url, text_unescaped, first_media;
source, user_profile_image_url, text_unescaped, first_media, card_name;
public final ParcelableLocation location;
@ -156,6 +156,7 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
mentions = ParcelableUserMention.fromJSONString(values.getAsString(Statuses.MENTIONS));
first_media = values.getAsString(Statuses.FIRST_MEDIA);
card = ParcelableCardEntity.fromJSONString(values.getAsString(Statuses.CARD));
card_name = card != null ? card.name : null;
}
public ParcelableStatus(final Cursor c, final CursorIndices idx) {
@ -200,6 +201,7 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
mentions = idx.mentions != -1 ? ParcelableUserMention.fromJSONString(c.getString(idx.mentions)) : null;
first_media = idx.first_media != -1 ? c.getString(idx.first_media) : null;
card = idx.card != -1 ? ParcelableCardEntity.fromJSONString(c.getString(idx.card)) : null;
card_name = card != null ? card.name : null;
}
public ParcelableStatus(final JSONParcel in) {
@ -241,6 +243,7 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
mentions = in.readParcelableArray("mentions", ParcelableUserMention.JSON_CREATOR);
first_media = media != null && media.length > 0 ? media[0].url : null;
card = in.readParcelable("card", ParcelableCardEntity.JSON_CREATOR);
card_name = card != null ? card.name : null;
}
public ParcelableStatus(final Parcel in) {
@ -282,6 +285,7 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
mentions = in.createTypedArray(ParcelableUserMention.CREATOR);
first_media = media != null && media.length > 0 ? media[0].url : null;
card = in.readParcelable(ParcelableCardEntity.class.getClassLoader());
card_name = card != null ? card.name : null;
}
public ParcelableStatus(final ParcelableStatus orig, final long override_my_retweet_id,
@ -324,6 +328,7 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
mentions = orig.mentions;
first_media = orig.first_media;
card = orig.card;
card_name = card != null ? card.name : null;
}
public ParcelableStatus(final Status orig, final long account_id, final boolean is_gap) {
@ -370,6 +375,7 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
mentions = ParcelableUserMention.fromUserMentionEntities(status.getUserMentionEntities());
first_media = media != null && media.length > 0 ? media[0].url : null;
card = ParcelableCardEntity.fromCardEntity(status.getCard(), account_id);
card_name = card != null ? card.name : null;
}
@Override
@ -541,7 +547,7 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
retweeted_by_user_screen_name, retweeted_by_user_profile_image, retweet_id, retweet_timestamp,
retweeted_by_user_id, user_id, source, retweet_count, favorite_count, reply_count,
descendent_reply_count, is_possibly_sensitive, is_following, media, first_media, mentions,
card;
card_name, card;
@Override
public String toString() {
@ -625,6 +631,7 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
media = cursor.getColumnIndex(Statuses.MEDIA);
first_media = cursor.getColumnIndex(Statuses.FIRST_MEDIA);
mentions = cursor.getColumnIndex(Statuses.MENTIONS);
card_name = cursor.getColumnIndex(Statuses.CARD_NAME);
card = cursor.getColumnIndex(Statuses.MENTIONS);
}

View File

@ -787,6 +787,8 @@ public interface TwidereDataStore {
public static final String CARD = "card";
public static final String CARD_NAME = "card_type";
public static final String SORT_ORDER_TIMESTAMP_DESC = STATUS_TIMESTAMP + " DESC";
public static final String SORT_ORDER_STATUS_ID_DESC = STATUS_ID + " DESC";
@ -800,7 +802,7 @@ public interface TwidereDataStore {
DESCENDENT_REPLY_COUNT, RETWEET_ID, RETWEET_TIMESTAMP, RETWEETED_BY_USER_ID,
RETWEETED_BY_USER_NAME, RETWEETED_BY_USER_SCREEN_NAME, RETWEETED_BY_USER_PROFILE_IMAGE,
MY_RETWEET_ID, IS_RETWEET, IS_FAVORITE, IS_PROTECTED, IS_VERIFIED, IS_FOLLOWING, IS_GAP,
IS_POSSIBLY_SENSITIVE, MEDIA, FIRST_MEDIA, MENTIONS, CARD};
IS_POSSIBLY_SENSITIVE, MEDIA, FIRST_MEDIA, MENTIONS, CARD_NAME, CARD};
public static final String[] TYPES = new String[]{TYPE_PRIMARY_KEY, TYPE_INT, TYPE_INT,
TYPE_INT, TYPE_INT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT,
@ -808,7 +810,7 @@ public interface TwidereDataStore {
TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_TEXT, TYPE_TEXT,
TYPE_TEXT, TYPE_INT, TYPE_BOOLEAN, TYPE_BOOLEAN, TYPE_BOOLEAN, TYPE_BOOLEAN,
TYPE_BOOLEAN, TYPE_BOOLEAN, TYPE_BOOLEAN, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT,
TYPE_TEXT};
TYPE_TEXT, TYPE_TEXT};
}

View File

@ -31,6 +31,7 @@ import org.mariotaku.twidere.model.ParcelableLocation;
import org.mariotaku.twidere.model.ParcelableMedia;
import org.mariotaku.twidere.model.ParcelableMediaUpdate;
import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.model.ParcelableStatus.ParcelableCardEntity;
import org.mariotaku.twidere.model.ParcelableStatusUpdate;
import org.mariotaku.twidere.model.ParcelableUser;
import org.mariotaku.twidere.model.ParcelableUserMention;
@ -363,6 +364,11 @@ public final class ContentValuesCreator implements TwidereConstants {
if (mentions != null) {
values.put(Statuses.MENTIONS, JSONSerializer.toJSONArrayString(mentions));
}
final ParcelableCardEntity card = ParcelableCardEntity.fromCardEntity(status.getCard(), accountId);
if (card != null) {
values.put(Statuses.CARD_NAME, card.name);
values.put(Statuses.CARD, JSONSerializer.toJSONObjectString(card));
}
return values;
}

View File

@ -28,7 +28,7 @@ package org.mariotaku.twidere;
public interface Constants extends TwidereConstants {
public static final String DATABASES_NAME = "twidere.sqlite";
public static final int DATABASES_VERSION = 82;
public static final int DATABASES_VERSION = 83;
public static final int MENU_GROUP_STATUS_EXTENSION = 10;
public static final int MENU_GROUP_COMPOSE_EXTENSION = 11;

View File

@ -1454,24 +1454,24 @@ public class ComposeActivity extends ThemedActionBarActivity implements TextWatc
private static class SpacingItemDecoration extends ItemDecoration {
private final int mSpacingSmall, mSpacingExtraSmall;
private final int mSpacingSmall, mSpacingNormal;
SpacingItemDecoration(Context context) {
final Resources resources = context.getResources();
mSpacingSmall = resources.getDimensionPixelSize(R.dimen.element_spacing_small);
mSpacingExtraSmall = resources.getDimensionPixelSize(R.dimen.element_spacing_xsmall);
mSpacingNormal = resources.getDimensionPixelSize(R.dimen.element_spacing_normal);
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) {
final int pos = parent.getChildPosition(view);
if (pos == 0) {
outRect.set(0, mSpacingSmall, 0, mSpacingExtraSmall);
outRect.set(0, mSpacingNormal, 0, 0);
} else if (pos == parent.getAdapter().getItemCount() - 1) {
outRect.set(0, mSpacingExtraSmall, 0, mSpacingSmall);
outRect.set(0, 0, 0, mSpacingNormal);
} else {
outRect.set(0, mSpacingExtraSmall, 0, mSpacingExtraSmall);
// outRect.set(0, mSpacingSmall, 0, mSpacingSmall);
outRect.set(0, 0, 0, 0);
}
}
}
@ -1515,8 +1515,12 @@ public class ComposeActivity extends ThemedActionBarActivity implements TextWatc
final ParcelableStatus status = args.getParcelable(EXTRA_STATUS);
final int profileImageStyle = Utils.getProfileImageStyle(preferences.getString(KEY_PROFILE_IMAGE_STYLE, null));
final int mediaPreviewStyle = Utils.getMediaPreviewStyle(preferences.getString(KEY_MEDIA_PREVIEW_STYLE, null));
mHolder.displayStatus(activity, loader, handler, twitter, profileImageStyle,
mediaPreviewStyle, true, status, null, true);
final boolean nameFirst = preferences.getBoolean(KEY_NAME_FIRST, true);
final boolean nicknameOnly = preferences.getBoolean(KEY_NICKNAME_ONLY, false);
final boolean displayMediaPreview = preferences.getBoolean(KEY_MEDIA_PREVIEW, false);
mHolder.displayStatus(activity, loader, handler, twitter, displayMediaPreview, true,
true, nameFirst, nicknameOnly, profileImageStyle, mediaPreviewStyle, status, null);
mStatusContainer.findViewById(R.id.item_menu).setVisibility(View.GONE);
mStatusContainer.findViewById(R.id.action_buttons).setVisibility(View.GONE);
mStatusContainer.findViewById(R.id.reply_retweet_status).setVisibility(View.GONE);

View File

@ -257,6 +257,15 @@ public class LinkHandlerActivity extends BaseSupportActivity implements OnClickL
}
}
@Override
public boolean getSystemWindowsInsets(Rect insets) {
final boolean result = super.getSystemWindowsInsets(insets);
if (result) {
insets.bottom = 0;
}
return result;
}
private boolean showFragment(final int linkId, final Uri uri) {
final Intent intent = getIntent();
intent.setExtrasClassLoader(getClassLoader());

View File

@ -71,6 +71,9 @@ public abstract class AbsActivitiesAdapter<Data> extends Adapter<ViewHolder> imp
private final int mTextSize;
private final int mProfileImageStyle, mMediaPreviewStyle;
private final boolean mCompactCards;
private final boolean mDisplayMediaPreview;
private final boolean mNameFirst;
private final boolean mNicknameOnly;
private boolean mLoadMoreIndicatorEnabled;
private ActivityAdapterListener mActivityAdapterListener;
@ -88,6 +91,9 @@ public abstract class AbsActivitiesAdapter<Data> extends Adapter<ViewHolder> imp
mCompactCards = compact;
mProfileImageStyle = Utils.getProfileImageStyle(preferences.getString(KEY_PROFILE_IMAGE_STYLE, null));
mMediaPreviewStyle = Utils.getMediaPreviewStyle(preferences.getString(KEY_MEDIA_PREVIEW_STYLE, null));
mDisplayMediaPreview = preferences.getBoolean(KEY_MEDIA_PREVIEW, false);
mNameFirst = preferences.getBoolean(KEY_NAME_FIRST, true);
mNicknameOnly = preferences.getBoolean(KEY_NICKNAME_ONLY, false);
}
public abstract ParcelableActivity getActivity(int position);
@ -137,6 +143,14 @@ public abstract class AbsActivitiesAdapter<Data> extends Adapter<ViewHolder> imp
return mLoadMoreIndicatorEnabled;
}
public boolean isNameFirst() {
return mNameFirst;
}
public boolean isNicknameOnly() {
return mNicknameOnly;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
@ -197,8 +211,8 @@ public abstract class AbsActivitiesAdapter<Data> extends Adapter<ViewHolder> imp
}
final StatusViewHolder statusViewHolder = (StatusViewHolder) holder;
statusViewHolder.displayStatus(getContext(), getImageLoader(), getImageLoadingHandler(),
getTwitterWrapper(), getProfileImageStyle(), getMediaPreviewStyle(), false,
status, null, false);
getTwitterWrapper(), isMediaPreviewDisplayed(), false, false, isNameFirst(),
isNicknameOnly(), getProfileImageStyle(), getMediaPreviewStyle(), status, null);
break;
}
case ITEM_VIEW_TYPE_TITLE_SUMMARY: {
@ -305,6 +319,10 @@ public abstract class AbsActivitiesAdapter<Data> extends Adapter<ViewHolder> imp
protected abstract int getActivityAction(int position);
private boolean isMediaPreviewDisplayed() {
return mDisplayMediaPreview;
}
public static interface ActivityAdapterListener {
void onGapClick(GapViewHolder holder, int position);

View File

@ -46,6 +46,9 @@ public abstract class AbsStatusesAdapter<D> extends Adapter<ViewHolder> implemen
private final int mTextSize;
private final int mProfileImageStyle, mMediaPreviewStyle;
private final boolean mCompactCards;
private final boolean mNameFirst;
private final boolean mNicknameOnly;
private final boolean mDisplayMediaPreview;
private boolean mLoadMoreIndicatorEnabled;
private StatusAdapterListener mStatusAdapterListener;
private boolean mShowInReplyTo;
@ -65,6 +68,9 @@ public abstract class AbsStatusesAdapter<D> extends Adapter<ViewHolder> implemen
mCompactCards = compact;
mProfileImageStyle = Utils.getProfileImageStyle(preferences.getString(KEY_PROFILE_IMAGE_STYLE, null));
mMediaPreviewStyle = Utils.getMediaPreviewStyle(preferences.getString(KEY_MEDIA_PREVIEW_STYLE, null));
mNameFirst = preferences.getBoolean(KEY_NAME_FIRST, true);
mNicknameOnly = preferences.getBoolean(KEY_NICKNAME_ONLY, false);
mDisplayMediaPreview = preferences.getBoolean(KEY_MEDIA_PREVIEW, false);
setShowInReplyTo(true);
}
@ -72,6 +78,11 @@ public abstract class AbsStatusesAdapter<D> extends Adapter<ViewHolder> implemen
public abstract void setData(D data);
@Override
public boolean shouldShowAccountsColor() {
return mShowAccountsColor;
}
@Override
public ImageLoaderWrapper getImageLoader() {
return mImageLoader;
@ -111,6 +122,21 @@ public abstract class AbsStatusesAdapter<D> extends Adapter<ViewHolder> implemen
return mLoadMoreIndicatorEnabled;
}
@Override
public boolean isMediaPreviewEnabled() {
return mDisplayMediaPreview;
}
@Override
public boolean isNameFirst() {
return mNameFirst;
}
@Override
public boolean isNicknameOnly() {
return mNicknameOnly;
}
public boolean isShowInReplyTo() {
return mShowInReplyTo;
}
@ -166,17 +192,6 @@ public abstract class AbsStatusesAdapter<D> extends Adapter<ViewHolder> implemen
}
}
@Override
public boolean shouldShowAccountsColor() {
return mShowAccountsColor;
}
public void setShowAccountsColor(boolean showAccountsColor) {
if (mShowAccountsColor == showAccountsColor) return;
mShowAccountsColor = showAccountsColor;
notifyDataSetChanged();
}
@Override
public int getItemViewType(int position) {
if (position == getStatusCount()) {
@ -246,6 +261,12 @@ public abstract class AbsStatusesAdapter<D> extends Adapter<ViewHolder> implemen
notifyDataSetChanged();
}
public void setShowAccountsColor(boolean showAccountsColor) {
if (mShowAccountsColor == showAccountsColor) return;
mShowAccountsColor = showAccountsColor;
notifyDataSetChanged();
}
protected abstract void bindStatus(StatusViewHolder holder, int position);
public static interface StatusAdapterListener {

View File

@ -14,6 +14,12 @@ public interface IStatusesAdapter<Data> extends IContentCardAdapter, StatusClick
long getStatusId(int position);
boolean isMediaPreviewEnabled();
boolean isNameFirst();
boolean isNicknameOnly();
void setData(Data data);
boolean shouldShowAccountsColor();

View File

@ -19,7 +19,6 @@
package org.mariotaku.twidere.app;
import android.app.Application;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@ -30,6 +29,7 @@ import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.AsyncTask;
import android.os.Handler;
import android.support.multidex.MultiDexApplication;
import com.nostra13.universalimageloader.cache.disc.DiskCache;
import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiscCache;
@ -69,10 +69,10 @@ import static org.mariotaku.twidere.util.Utils.initAccountColor;
import static org.mariotaku.twidere.util.Utils.startProfilingServiceIfNeeded;
import static org.mariotaku.twidere.util.Utils.startRefreshServiceIfNeeded;
public class TwidereApplication extends Application implements Constants, OnSharedPreferenceChangeListener {
public class TwidereApplication extends MultiDexApplication implements Constants,
OnSharedPreferenceChangeListener {
private Handler mHandler;
private ImageLoaderWrapper mImageLoaderWrapper;
private ImageLoader mImageLoader;
private AsyncTaskManager mAsyncTaskManager;
@ -141,6 +141,16 @@ public class TwidereApplication extends Application implements Constants, OnShar
return mImageLoaderWrapper = new ImageLoaderWrapper(getImageLoader());
}
public static TwidereApplication getInstance(final Context context) {
if (context == null) return null;
final Context app = context.getApplicationContext();
return app instanceof TwidereApplication ? (TwidereApplication) app : null;
}
public Bus getMessageBus() {
return mMessageBus;
}
public MessagesManager getMessagesManager() {
if (mCroutonsManager != null) return mCroutonsManager;
return mCroutonsManager = new MessagesManager(this);
@ -253,14 +263,4 @@ public class TwidereApplication extends Application implements Constants, OnShar
}
}
public Bus getMessageBus() {
return mMessageBus;
}
public static TwidereApplication getInstance(final Context context) {
if (context == null) return null;
final Context app = context.getApplicationContext();
return app instanceof TwidereApplication ? (TwidereApplication) app : null;
}
}

View File

@ -19,7 +19,6 @@
package org.mariotaku.twidere.fragment.support;
import android.app.ActionBar;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
@ -34,6 +33,8 @@ import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.util.Pair;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.PopupMenu;
import android.text.Editable;
import android.text.TextUtils;
@ -65,6 +66,7 @@ import org.mariotaku.querybuilder.Expression;
import org.mariotaku.querybuilder.OrderBy;
import org.mariotaku.querybuilder.RawItemArray;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.support.BaseSupportActivity;
import org.mariotaku.twidere.activity.support.ImagePickerActivity;
import org.mariotaku.twidere.adapter.AccountsSpinnerAdapter;
import org.mariotaku.twidere.adapter.DirectMessagesConversationAdapter;
@ -190,8 +192,8 @@ public class DirectMessagesConversationFragment extends BaseSupportFragment impl
public void onActivityCreated(final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
final FragmentActivity activity = getActivity();
final ActionBar actionBar = activity.getActionBar();
final BaseSupportActivity activity = (BaseSupportActivity) getActivity();
final ActionBar actionBar = activity.getSupportActionBar();
if (actionBar == null) throw new NullPointerException();
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM,
ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_CUSTOM);
@ -350,7 +352,7 @@ public class DirectMessagesConversationFragment extends BaseSupportFragment impl
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_direct_messages_conversation, menu);
final View profileImageItemView = menu.findItem(R.id.item_profile_image).getActionView();
final View profileImageItemView = MenuItemCompat.getActionView(menu.findItem(R.id.item_profile_image));
profileImageItemView.setOnClickListener(this);
mProfileImageContainer = (IColorLabelView) profileImageItemView;
mRecipientProfileImageView = (ImageView) profileImageItemView.findViewById(R.id.recipient_profile_image);
@ -633,8 +635,8 @@ public class DirectMessagesConversationFragment extends BaseSupportFragment impl
}
private void updateActionBar() {
final FragmentActivity activity = getActivity();
final ActionBar actionBar = activity.getActionBar();
final BaseSupportActivity activity = (BaseSupportActivity) getActivity();
final ActionBar actionBar = activity.getSupportActionBar();
if (actionBar == null) return;
actionBar.setDisplayOptions(mRecipient != null ? ActionBar.DISPLAY_SHOW_TITLE : ActionBar.DISPLAY_SHOW_CUSTOM,
ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_CUSTOM);

View File

@ -91,6 +91,9 @@ public class RetweetQuoteDialogFragment extends BaseSupportDialogFragment implem
final StatusViewHolder holder = new StatusViewHolder(view.findViewById(R.id.item_content));
final int profileImageStyle = Utils.getProfileImageStyle(preferences.getString(KEY_PROFILE_IMAGE_STYLE, null));
final int mediaPreviewStyle = Utils.getMediaPreviewStyle(preferences.getString(KEY_MEDIA_PREVIEW_STYLE, null));
final boolean nameFirst = preferences.getBoolean(KEY_NAME_FIRST, true);
final boolean nicknameOnly = preferences.getBoolean(KEY_NICKNAME_ONLY, false);
final boolean displayMediaPreview = preferences.getBoolean(KEY_MEDIA_PREVIEW, false);
final ParcelableStatus status = getStatus();
builder.setView(view);
@ -99,9 +102,9 @@ public class RetweetQuoteDialogFragment extends BaseSupportDialogFragment implem
builder.setNeutralButton(R.string.quote, this);
builder.setNegativeButton(android.R.string.cancel, null);
holder.displayStatus(context, loader, handler, twitter, displayMediaPreview, true,
true, nameFirst, nicknameOnly, profileImageStyle, mediaPreviewStyle, status, null);
holder.displayStatus(context, loader, handler, twitter, profileImageStyle, mediaPreviewStyle,
true, getStatus(), null, true);
view.findViewById(R.id.item_menu).setVisibility(View.GONE);
view.findViewById(R.id.action_buttons).setVisibility(View.GONE);
view.findViewById(R.id.reply_retweet_status).setVisibility(View.GONE);

View File

@ -90,6 +90,7 @@ import org.mariotaku.twidere.util.StatisticUtils;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.TwidereLinkify;
import org.mariotaku.twidere.util.TwitterCardUtils;
import org.mariotaku.twidere.util.UserColorNameUtils;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.util.Utils.OnMediaClickListener;
import org.mariotaku.twidere.view.ShapedImageView;
@ -299,8 +300,10 @@ public class StatusFragment extends BaseSupportFragment
@Override
protected void fitSystemWindows(Rect insets) {
super.fitSystemWindows(insets);
// mRecyclerView.setPadding(insets.left, insets.top, insets.right, insets.bottom);
getView().setPadding(insets.left, insets.top, insets.right, insets.bottom);
final View view = getView();
if (view != null) {
view.setPadding(insets.left, insets.top, insets.right, insets.bottom);
}
}
@Override
@ -405,6 +408,7 @@ public class StatusFragment extends BaseSupportFragment
private final int mCardBackgroundColor;
private final boolean mIsCompact;
private final int mProfileImageStyle;
private final boolean mDisplayMediaPreview;
private ParcelableStatus mStatus;
private ParcelableCredentials mStatusAccount;
@ -429,6 +433,7 @@ public class StatusFragment extends BaseSupportFragment
mTextSize = preferences.getInt(KEY_TEXT_SIZE, res.getInteger(R.integer.default_text_size));
mProfileImageStyle = Utils.getProfileImageStyle(preferences.getString(KEY_PROFILE_IMAGE_STYLE, null));
mIsCompact = compact;
mDisplayMediaPreview = preferences.getBoolean(KEY_MEDIA_PREVIEW, false);
if (compact) {
mCardLayoutResource = R.layout.card_item_status_compact;
} else {
@ -485,6 +490,11 @@ public class StatusFragment extends BaseSupportFragment
return status != null ? status.hashCode() : position;
}
@Override
public boolean isMediaPreviewEnabled() {
return mDisplayMediaPreview;
}
@Override
public int getProfileImageStyle() {
return mProfileImageStyle;
@ -827,11 +837,12 @@ public class StatusFragment extends BaseSupportFragment
private final ShapedImageView profileImageView;
private final ImageView profileTypeView;
private final TextView timeSourceView;
private final TextView replyRetweetStatusView;
private final TextView retweetedByView;
private final View repliesContainer, retweetsContainer, favoritesContainer;
private final TextView repliesCountView, retweetsCountView, favoritesCountView;
private final View profileContainer;
private final View retweetedByContainer;
private final View mediaPreviewContainer;
private final View mediaPreviewLoad;
private final LinearLayout mediaPreviewGrid;
@ -850,7 +861,8 @@ public class StatusFragment extends BaseSupportFragment
profileImageView = (ShapedImageView) itemView.findViewById(R.id.profile_image);
profileTypeView = (ImageView) itemView.findViewById(R.id.profile_type);
timeSourceView = (TextView) itemView.findViewById(R.id.time_source);
replyRetweetStatusView = (TextView) itemView.findViewById(R.id.reply_retweet_status);
retweetedByView = (TextView) itemView.findViewById(R.id.retweeted_by);
retweetedByContainer = itemView.findViewById(R.id.retweeted_by_container);
repliesContainer = itemView.findViewById(R.id.replies_container);
retweetsContainer = itemView.findViewById(R.id.retweets_container);
favoritesContainer = itemView.findViewById(R.id.favorites_container);
@ -893,6 +905,14 @@ public class StatusFragment extends BaseSupportFragment
Utils.openStatusRetweeters(activity, status.account_id, status.id);
break;
}
case R.id.retweeted_by_container: {
final ParcelableStatus status = adapter.getStatus(getPosition());
if (status.retweet_id > 0) {
Utils.openUserProfile(adapter.getContext(), status.account_id, status.user_id,
status.user_screen_name, null);
}
break;
}
}
}
@ -1024,6 +1044,17 @@ public class StatusFragment extends BaseSupportFragment
final ImageLoaderWrapper loader = adapter.getImageLoader();
final boolean nameFirst = adapter.isNameFirst();
final boolean nicknameOnly = adapter.isNicknameOnly();
if (status.retweet_id > 0) {
final String retweetedBy = UserColorNameUtils.getDisplayName(context, status.retweeted_by_id,
status.retweeted_by_name, status.retweeted_by_screen_name, nameFirst, nicknameOnly);
retweetedByView.setText(context.getString(R.string.name_retweeted, retweetedBy));
retweetedByContainer.setVisibility(View.VISIBLE);
} else {
retweetedByView.setText(null);
retweetedByContainer.setVisibility(View.GONE);
}
final String nickname = getUserNickname(context, status.user_id, true);
if (TextUtils.isEmpty(nickname)) {
nameView.setText(status.user_name);
@ -1124,8 +1155,8 @@ public class StatusFragment extends BaseSupportFragment
ThemeUtils.wrapMenuIcon(menuBar, MENU_GROUP_STATUS_SHARE);
mediaPreviewLoad.setOnClickListener(this);
profileContainer.setOnClickListener(this);
retweetsContainer.setOnClickListener(this);
retweetedByContainer.setOnClickListener(this);
final float defaultTextSize = adapter.getTextSize();
nameView.setTextSize(defaultTextSize * 1.25f);

View File

@ -135,8 +135,13 @@ public class StatusTranslateDialogFragment extends BaseSupportDialogFragment imp
SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
final int profileImageStyle = Utils.getProfileImageStyle(preferences.getString(KEY_PROFILE_IMAGE_STYLE, null));
final int mediaPreviewStyle = Utils.getMediaPreviewStyle(preferences.getString(KEY_MEDIA_PREVIEW_STYLE, null));
mHolder.displayStatus(activity, loader, handler, twitter, profileImageStyle,
mediaPreviewStyle, true, status, null, true);
final boolean nameFirst = preferences.getBoolean(KEY_NAME_FIRST, true);
final boolean nicknameOnly = preferences.getBoolean(KEY_NICKNAME_ONLY, false);
final boolean displayMediaPreview = preferences.getBoolean(KEY_MEDIA_PREVIEW, false);
mHolder.displayStatus(activity, loader, handler, twitter, displayMediaPreview, true,
true, nameFirst, nicknameOnly, profileImageStyle, mediaPreviewStyle, status, null);
mStatusContainer.findViewById(R.id.item_menu).setVisibility(View.GONE);
mStatusContainer.findViewById(R.id.action_buttons).setVisibility(View.GONE);
mStatusContainer.findViewById(R.id.reply_retweet_status).setVisibility(View.GONE);

View File

@ -32,16 +32,20 @@ public class TwitterCardUtils {
private static final TwitterCardFragmentFactory sFactory = TwitterCardFragmentFactory.getInstance();
public static final String CARD_NAME_PLAYER = "player";
public static final String CARD_NAME_AUDIO = "audio";
public static final String CARD_NAME_ANIMATED_GIF = "animated_gif";
public static Fragment createCardFragment(ParcelableCardEntity card) {
if ("player".equals(card.name)) {
if (CARD_NAME_PLAYER.equals(card.name)) {
final Fragment playerFragment = sFactory.createPlayerFragment(card);
if (playerFragment != null) return playerFragment;
return TwitterCardFragmentFactory.createGenericPlayerFragment(card);
} else if ("audio".equals(card.name)) {
} else if (CARD_NAME_AUDIO.equals(card.name)) {
final Fragment playerFragment = sFactory.createAudioFragment(card);
if (playerFragment != null) return playerFragment;
return TwitterCardFragmentFactory.createGenericPlayerFragment(card);
} else if ("animated_gif".equals(card.name)) {
} else if (CARD_NAME_ANIMATED_GIF.equals(card.name)) {
final Fragment playerFragment = sFactory.createAnimatedGifFragment(card);
if (playerFragment != null) return playerFragment;
return TwitterCardFragmentFactory.createGenericPlayerFragment(card);
@ -65,7 +69,7 @@ public class TwitterCardUtils {
public static boolean isCardSupported(ParcelableCardEntity card) {
if (card == null) return false;
return "player".equals(card.name) || "audio".equals(card.name) || "animated_gif".equals(card.name);
return CARD_NAME_PLAYER.equals(card.name) || CARD_NAME_AUDIO.equals(card.name) || CARD_NAME_ANIMATED_GIF.equals(card.name);
}
}

View File

@ -36,6 +36,7 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
@ -3928,7 +3929,9 @@ public final class Utils implements Constants, TwitterConstants {
public static int getActionBarHeight(Context context) {
final TypedValue tv = new TypedValue();
if (context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
final Theme theme = context.getTheme();
final int attr = context instanceof ActionBarActivity ? R.attr.actionBarSize : android.R.attr.actionBarSize;
if (theme.resolveAttribute(attr, tv, true)) {
return TypedValue.complexToDimensionPixelSize(tv.data, context.getResources().getDisplayMetrics());
}
return 0;

View File

@ -1,220 +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.Canvas;
import android.graphics.Rect;
import android.support.annotation.NonNull;
import android.support.v4.view.ViewCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.Adapter;
import android.support.v7.widget.RecyclerView.ItemDecoration;
import android.support.v7.widget.RecyclerView.Recycler;
import android.support.v7.widget.RecyclerView.State;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.model.ParcelableAccount;
import org.mariotaku.twidere.util.ImageLoaderWrapper;
import org.mariotaku.twidere.view.iface.IColorLabelView.Helper;
/**
* Created by mariotaku on 14/12/8.
*/
public class ComposeSelectAccountButton extends ViewGroup {
private final AccountIconsAdapter mAccountIconsAdapter;
private final Helper mColorLabelHelper;
private final InternalRecyclerView recyclerView;
public ComposeSelectAccountButton(Context context) {
this(context, null);
}
public ComposeSelectAccountButton(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ComposeSelectAccountButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mColorLabelHelper = new Helper(this, context, attrs, defStyle);
mColorLabelHelper.setIgnorePaddings(true);
mAccountIconsAdapter = new AccountIconsAdapter(context);
recyclerView = new InternalRecyclerView(context);
final LinearLayoutManager linearLayoutManager = new MyLinearLayoutManager(context);
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setAdapter(mAccountIconsAdapter);
recyclerView.addItemDecoration(new ItemDecoration() {
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) {
final int pos = parent.getChildPosition(view);
if (pos == 0) {
outRect.left = 0;
} else {
final int count = state.getItemCount();
outRect.left = -(parent.getHeight() - (parent.getWidth() - parent.getHeight()) / (count - 1));
}
}
});
ViewCompat.setOverScrollMode(recyclerView, ViewCompat.OVER_SCROLL_NEVER);
addView(recyclerView);
mAccountIconsAdapter.setSelectedAccounts(ParcelableAccount.getAccounts(context, false, false));
}
public void setSelectedAccounts(long[] accountIds) {
final ParcelableAccount[] accounts = ParcelableAccount.getAccounts(getContext(), accountIds);
// if (accounts != null) {
// final int[] colors = new int[accounts.length];
// for (int i = 0, j = colors.length; i < j; i++) {
// colors[i] = accounts[i].color;
// }
// mColorLabelHelper.drawEnd(colors);
// } else {
// mColorLabelHelper.drawEnd(null);
// }
mAccountIconsAdapter.setSelectedAccounts(accounts);
}
@Override
protected void dispatchDraw(@NonNull final Canvas canvas) {
mColorLabelHelper.dispatchDrawBackground(canvas);
super.dispatchDraw(canvas);
mColorLabelHelper.dispatchDrawLabels(canvas);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
measureChildren(widthMeasureSpec, heightMeasureSpec);
int maxWidth = 0;
for (int i = 0, j = getChildCount(); i < j; i++) {
final View child = getChildAt(i);
maxWidth = Math.max(maxWidth, child.getMeasuredWidth());
}
if (maxWidth == 0) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
} else {
setMeasuredDimension(maxWidth, heightMeasureSpec);
}
}
static class AccountIconViewHolder extends ViewHolder {
private final ImageView iconView;
public AccountIconViewHolder(View itemView) {
super(itemView);
iconView = (ImageView) itemView.findViewById(android.R.id.icon);
}
public void showAccount(AccountIconsAdapter adapter, ParcelableAccount account) {
final ImageLoaderWrapper loader = adapter.getImageLoader();
loader.displayProfileImage(iconView, account.profile_image_url);
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
for (int i = 0, j = getChildCount(); i < j; i++) {
final View child = getChildAt(i);
child.layout(getPaddingLeft(), getPaddingTop(), r - l - getPaddingRight(),
b - t - getPaddingBottom());
}
}
private static class AccountIconsAdapter extends Adapter<AccountIconViewHolder> {
private final Context mContext;
private final LayoutInflater mInflater;
private final ImageLoaderWrapper mImageLoader;
private ParcelableAccount[] mAccounts;
public AccountIconsAdapter(Context context) {
mContext = context;
mInflater = LayoutInflater.from(context);
mImageLoader = TwidereApplication.getInstance(context).getImageLoaderWrapper();
}
public ImageLoaderWrapper getImageLoader() {
return mImageLoader;
}
@Override
public AccountIconViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final View view = mInflater.inflate(R.layout.adapter_item_compose_account2, parent, false);
return new AccountIconViewHolder(view);
}
@Override
public void onBindViewHolder(AccountIconViewHolder holder, int position) {
holder.showAccount(this, mAccounts[position]);
}
@Override
public int getItemCount() {
return mAccounts != null ? mAccounts.length : 0;
}
public void setSelectedAccounts(ParcelableAccount[] accounts) {
mAccounts = accounts;
notifyDataSetChanged();
}
}
private static class InternalRecyclerView extends RecyclerView {
public InternalRecyclerView(Context context) {
super(context);
setChildrenDrawingOrderEnabled(true);
}
@Override
public boolean dispatchTouchEvent(@NonNull MotionEvent ev) {
return false;
}
@Override
protected int getChildDrawingOrder(int childCount, int i) {
return childCount - i - 1;
}
}
private static class MyLinearLayoutManager extends LinearLayoutManager {
public MyLinearLayoutManager(Context context) {
super(context);
}
@Override
public void onMeasure(Recycler recycler, State state, int widthSpec, int heightSpec) {
final int height = MeasureSpec.getSize(heightSpec), width = Math.round(height * 1.25f);
setMeasuredDimension(width, height);
}
}
}

View File

@ -1,7 +1,6 @@
package org.mariotaku.twidere.view.holder;
import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.PorterDuff.Mode;
import android.support.annotation.NonNull;
@ -22,6 +21,7 @@ import org.mariotaku.twidere.model.ParcelableStatus.CursorIndices;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.ImageLoaderWrapper;
import org.mariotaku.twidere.util.ImageLoadingHandler;
import org.mariotaku.twidere.util.TwitterCardUtils;
import org.mariotaku.twidere.util.UserColorNameUtils;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.CardMediaContainer;
@ -45,6 +45,7 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
private final ImageView replyRetweetIcon;
private final ShapedImageView profileImageView;
private final ImageView profileTypeView;
private final ImageView extraTypeView;
private final TextView textView;
private final TextView nameView, screenNameView;
private final TextView replyRetweetView;
@ -66,6 +67,7 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
itemContent = (IColorLabelView) itemView.findViewById(R.id.item_content);
profileImageView = (ShapedImageView) itemView.findViewById(R.id.profile_image);
profileTypeView = (ImageView) itemView.findViewById(R.id.profile_type);
extraTypeView = (ImageView) itemView.findViewById(R.id.extra_type);
textView = (TextView) itemView.findViewById(R.id.text);
nameView = (TextView) itemView.findViewById(R.id.name);
screenNameView = (TextView) itemView.findViewById(R.id.screen_name);
@ -124,27 +126,35 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
public void displayStatus(final ParcelableStatus status, final boolean displayInReplyTo) {
displayStatus(adapter.getContext(), adapter.getImageLoader(),
adapter.getImageLoadingHandler(), adapter.getTwitterWrapper(),
adapter.isMediaPreviewEnabled(), adapter.shouldShowAccountsColor(),
displayInReplyTo, adapter.isNameFirst(), adapter.isNicknameOnly(),
adapter.getProfileImageStyle(), adapter.getMediaPreviewStyle(),
adapter.shouldShowAccountsColor(), status, null, displayInReplyTo);
status, null);
}
public void displayStatus(final Context context, final ImageLoaderWrapper loader,
final ImageLoadingHandler handler, final AsyncTwitterWrapper twitter,
public void displayStatus(@NonNull final Context context,
@NonNull final ImageLoaderWrapper loader,
@NonNull final ImageLoadingHandler handler,
@NonNull final AsyncTwitterWrapper twitter,
final boolean displayMediaPreview, final boolean displayAccountsColor,
final boolean displayInReplyTo, boolean nameFirst, boolean nicknameOnly,
final int profileImageStyle, final int mediaPreviewStyle,
final boolean displayAccountsColor,
@NonNull final ParcelableStatus status,
@Nullable final TranslationResult translation,
final boolean displayInReplyTo) {
@Nullable final TranslationResult translation) {
final ParcelableMedia[] media = status.media;
replyRetweetIcon.setColorFilter(replyRetweetView.getCurrentTextColor(), Mode.SRC_ATOP);
if (status.retweet_id > 0) {
replyRetweetView.setText(context.getString(R.string.name_retweeted, status.retweeted_by_name));
final String retweetedBy = UserColorNameUtils.getDisplayName(context, status.retweeted_by_id,
status.retweeted_by_name, status.retweeted_by_screen_name, nameFirst, nicknameOnly);
replyRetweetView.setText(context.getString(R.string.name_retweeted, retweetedBy));
replyRetweetIcon.setImageResource(R.drawable.ic_activity_action_retweet);
replyRetweetView.setVisibility(View.VISIBLE);
replyRetweetIcon.setVisibility(View.VISIBLE);
} else if (status.in_reply_to_status_id > 0 && status.in_reply_to_user_id > 0 && displayInReplyTo) {
replyRetweetView.setText(context.getString(R.string.in_reply_to_name, status.in_reply_to_name));
final String inReplyTo = UserColorNameUtils.getDisplayName(context, status.in_reply_to_user_id,
status.in_reply_to_name, status.in_reply_to_screen_name, nameFirst, nicknameOnly);
replyRetweetView.setText(context.getString(R.string.in_reply_to_name, inReplyTo));
replyRetweetIcon.setImageResource(R.drawable.ic_activity_action_reply);
replyRetweetView.setVisibility(View.VISIBLE);
replyRetweetIcon.setVisibility(View.VISIBLE);
@ -157,11 +167,9 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
final int typeIconRes = getUserTypeIconRes(status.user_is_verified, status.user_is_protected);
if (typeIconRes != 0) {
profileTypeView.setImageResource(typeIconRes);
// profileTypeView.setBackgroundResource(typeIconRes);
profileTypeView.setVisibility(View.VISIBLE);
} else {
profileTypeView.setImageDrawable(null);
// profileTypeView.setBackgroundResource(0);
profileTypeView.setVisibility(View.GONE);
}
@ -181,9 +189,13 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
loader.displayProfileImage(profileImageView, status.user_profile_image_url);
mediaPreviewContainer.setStyle(mediaPreviewStyle);
mediaPreviewContainer.setVisibility(media != null && media.length > 0 ? View.VISIBLE : View.GONE);
mediaPreviewContainer.displayMedia(media, loader, status.account_id, null, handler);
if (displayMediaPreview) {
mediaPreviewContainer.setStyle(mediaPreviewStyle);
mediaPreviewContainer.setVisibility(media != null && media.length > 0 ? View.VISIBLE : View.GONE);
mediaPreviewContainer.displayMedia(media, loader, status.account_id, null, handler);
} else {
mediaPreviewContainer.setVisibility(View.GONE);
}
if (translation != null) {
textView.setText(translation.getText());
} else {
@ -226,6 +238,25 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
} else {
favoriteCountView.setText(null);
}
displayExtraTypeIcon(status.card_name, status.media != null ? status.media.length : 0);
}
private void displayExtraTypeIcon(String cardName, int mediaLength) {
if (TwitterCardUtils.CARD_NAME_AUDIO.equals(cardName)) {
extraTypeView.setImageResource(R.drawable.ic_action_play_circle);
extraTypeView.setVisibility(View.VISIBLE);
} else if (TwitterCardUtils.CARD_NAME_ANIMATED_GIF.equals(cardName)) {
extraTypeView.setImageResource(R.drawable.ic_action_play_circle);
extraTypeView.setVisibility(View.VISIBLE);
} else if (TwitterCardUtils.CARD_NAME_PLAYER.equals(cardName)) {
extraTypeView.setImageResource(R.drawable.ic_action_play_circle);
extraTypeView.setVisibility(View.VISIBLE);
} else if (mediaLength > 0) {
extraTypeView.setImageResource(R.drawable.ic_action_gallery);
extraTypeView.setVisibility(View.VISIBLE);
} else {
extraTypeView.setVisibility(View.GONE);
}
}
@ -234,7 +265,8 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
final ImageLoaderWrapper loader = adapter.getImageLoader();
final AsyncTwitterWrapper twitter = adapter.getTwitterWrapper();
final Context context = adapter.getContext();
final Resources resources = context.getResources();
final boolean nameFirst = adapter.isNameFirst();
final boolean nicknameOnly = adapter.isNicknameOnly();
final long reply_count = cursor.getLong(indices.reply_count);
final long retweet_count;
@ -256,18 +288,25 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
final String user_screen_name = cursor.getString(indices.user_screen_name);
final String user_profile_image_url = cursor.getString(indices.user_profile_image_url);
final String retweeted_by_name = cursor.getString(indices.retweeted_by_user_name);
final String retweeted_by_screen_name = cursor.getString(indices.retweeted_by_user_screen_name);
final String in_reply_to_name = cursor.getString(indices.in_reply_to_user_name);
final String in_reply_to_screen_name = cursor.getString(indices.in_reply_to_user_screen_name);
final String card_name = cursor.getString(indices.card_name);
final ParcelableMedia[] media = ParcelableMedia.fromJSONString(cursor.getString(indices.media));
replyRetweetIcon.setColorFilter(replyRetweetView.getCurrentTextColor(), Mode.SRC_ATOP);
if (retweet_id > 0) {
replyRetweetView.setText(context.getString(R.string.name_retweeted, retweeted_by_name));
final String retweetedBy = UserColorNameUtils.getDisplayName(context, retweeted_by_id,
retweeted_by_name, retweeted_by_screen_name, nameFirst, nicknameOnly);
replyRetweetView.setText(context.getString(R.string.name_retweeted, retweetedBy));
replyRetweetIcon.setImageResource(R.drawable.ic_activity_action_retweet);
replyRetweetView.setVisibility(View.VISIBLE);
replyRetweetIcon.setVisibility(View.VISIBLE);
} else if (in_reply_to_status_id > 0 && in_reply_to_user_id > 0 && displayInReplyTo) {
replyRetweetView.setText(context.getString(R.string.in_reply_to_name, in_reply_to_name));
final String inReplyTo = UserColorNameUtils.getDisplayName(context, in_reply_to_user_id,
in_reply_to_name, in_reply_to_screen_name, nameFirst, nicknameOnly);
replyRetweetView.setText(context.getString(R.string.in_reply_to_name, inReplyTo));
replyRetweetIcon.setImageResource(R.drawable.ic_activity_action_reply);
replyRetweetView.setVisibility(View.VISIBLE);
replyRetweetIcon.setVisibility(View.VISIBLE);
@ -305,10 +344,14 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
loader.displayProfileImage(profileImageView, user_profile_image_url);
final String text_unescaped = cursor.getString(indices.text_unescaped);
mediaPreviewContainer.setStyle(adapter.getMediaPreviewStyle());
mediaPreviewContainer.setVisibility(media != null && media.length > 0 ? View.VISIBLE : View.GONE);
mediaPreviewContainer.displayMedia(media, loader, account_id, null,
adapter.getImageLoadingHandler());
if (adapter.isMediaPreviewEnabled()) {
mediaPreviewContainer.setStyle(adapter.getMediaPreviewStyle());
mediaPreviewContainer.setVisibility(media != null && media.length > 0 ? View.VISIBLE : View.GONE);
mediaPreviewContainer.displayMedia(media, loader, account_id, null,
adapter.getImageLoadingHandler());
} else {
mediaPreviewContainer.setVisibility(View.GONE);
}
textView.setText(text_unescaped);
if (reply_count > 0) {
@ -347,6 +390,7 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
} else {
favoriteCountView.setText(null);
}
displayExtraTypeIcon(card_name, media != null ? media.length : 0);
}
public CardView getCardView() {
@ -365,7 +409,7 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
nameView.setText("User");
screenNameView.setText("@user");
timeView.setTime(System.currentTimeMillis());
textView.setText("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam faucibus quis purus ac malesuada. Duis id vulputate magna, a eleifend amet.");
textView.setText(R.string.sample_status_text);
mediaPreviewContainer.displayMedia(R.drawable.profile_image_nyan_sakamoto,
R.drawable.profile_image_nyan_sakamoto_santa);
}

View File

@ -23,6 +23,7 @@ import android.content.Context;
import android.content.res.ColorStateList;
import android.os.Build;
import android.support.v4.graphics.drawable.DrawableCompat;
import android.support.v7.widget.SwitchCompat;
import android.util.AttributeSet;
import android.widget.Switch;

View File

@ -0,0 +1,50 @@
/*
* 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.content.res.ColorStateList;
import android.os.Build;
import android.support.v4.graphics.drawable.DrawableCompat;
import android.support.v7.widget.SwitchCompat;
import android.util.AttributeSet;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.view.iface.IThemedView;
public class ThemedSwitchCompat extends SwitchCompat implements IThemedView {
public ThemedSwitchCompat(final Context context) {
this(context, null);
}
public ThemedSwitchCompat(final Context context, final AttributeSet attrs) {
super(context, attrs);
ThemeUtils.initTextView(this);
}
@Override
public void setThemeTintColor(ColorStateList color) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
DrawableCompat.setTintList(getThumbDrawable(), color);
DrawableCompat.setTintList(getTrackDrawable(), color);
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 667 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 958 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -18,7 +18,7 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<org.mariotaku.twidere.view.SquareFrameLayout
<RelativeLayout
style="?android:actionButtonStyle"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
@ -26,29 +26,33 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:clickable="true"
android:paddingBottom="@dimen/element_spacing_normal"
android:paddingLeft="@dimen/element_spacing_mlarge"
android:paddingBottom="@dimen/element_spacing_msmall"
android:paddingLeft="@dimen/element_spacing_small"
android:paddingRight="@dimen/element_spacing_small"
android:paddingTop="@dimen/element_spacing_normal"
android:paddingTop="@dimen/element_spacing_msmall"
tools:layout_height="?actionBarSize"
tools:showIn="@layout/menu_compose">
<org.mariotaku.twidere.view.ShapedImageView
<org.mariotaku.twidere.view.SquareShapedImageView
android:id="@+id/account_profile_image"
style="?profileImageStyle"
android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
app:sivBackgroundColor="?android:colorBackground"
app:sivBorder="true"
app:sivBorderWidth="1.5dp"
app:sivBorderWidth="@dimen/line_width_compose_account_profile_image"
tools:src="@drawable/ic_profile_image_default"/>
<org.mariotaku.twidere.view.BadgeView
android:id="@+id/accounts_count"
android:layout_alignTop="@id/account_profile_image"
android:layout_alignBottom="@id/account_profile_image"
android:layout_alignRight="@id/account_profile_image"
android:layout_alignLeft="@id/account_profile_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:textColor="?android:colorForeground"/>
</org.mariotaku.twidere.view.SquareFrameLayout>
</RelativeLayout>

View File

@ -110,10 +110,10 @@
android:layout_width="?actionBarSize"
android:layout_height="match_parent"
android:layout_gravity="left"
android:layout_marginLeft="@dimen/element_spacing_small"
android:layout_marginLeft="@dimen/element_spacing_xsmall"
android:overScrollMode="never"
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_normal"/>
android:paddingLeft="@dimen/element_spacing_msmall"
android:paddingRight="@dimen/element_spacing_msmall"/>
</FrameLayout>
</RelativeLayout>

View File

@ -18,13 +18,15 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<org.mariotaku.twidere.view.SquareShapedImageView
android:id="@android:id/icon"
style="?profileImageStyle"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@android:id/icon"
style="?profileImageStyle"
tools:layout_width="48dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/element_spacing_small"
android:layout_marginBottom="@dimen/element_spacing_small"
app:sivBorder="true"
app:sivBorderWidth="1.5dp"/>
app:sivBorderWidth="@dimen/line_width_compose_account_profile_image"
tools:layout_width="48dp"/>

View File

@ -1,30 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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/>.
-->
<org.mariotaku.twidere.view.SquareShapedImageView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@android:id/icon"
style="?profileImageStyle"
tools:layout_height="48dp"
android:layout_width="wrap_content"
android:layout_height="match_parent"
app:sivBorder="true"
app:sivBorderWidth="1.5dp"/>

View File

@ -34,9 +34,9 @@
<Space
android:id="@+id/reply_retweet_space"
android:layout_width="@dimen/icon_size_status_profile_image"
android:layout_marginRight="@dimen/element_spacing_small"
android:layout_height="@dimen/element_size_small"
android:layout_marginLeft="@dimen/element_spacing_normal"/>
android:layout_marginLeft="@dimen/element_spacing_normal"
android:layout_marginRight="@dimen/element_spacing_small"/>
<ImageView
android:id="@+id/reply_retweet_icon"
@ -108,8 +108,8 @@
android:layout_toRightOf="@id/profile_image"
android:orientation="vertical">
<LinearLayout
android:id="@+id/name_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/element_spacing_xsmall"
@ -139,15 +139,19 @@
tools:text="\@user"/>
</LinearLayout>
<org.mariotaku.twidere.view.ShortTimeView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical"
android:paddingBottom="@dimen/element_spacing_small"
android:paddingTop="@dimen/element_spacing_xsmall"
android:singleLine="true"
android:textAppearance="?android:textAppearanceSmall"
android:textSize="10sp"/>
tools:text="10 mins ago"
tools:textSize="10sp"/>
</LinearLayout>
@ -190,61 +194,85 @@
android:textColor="?android:attr/textColorPrimary"
tools:text="@string/sample_status_text"/>
<HorizontalScrollView
android:id="@+id/action_buttons"
android:layout_width="wrap_content"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/profile_container"
android:layout_below="@+id/text"
android:overScrollMode="never"
android:scrollbars="none">
android:gravity="center_vertical"
android:orientation="horizontal">
<LinearLayout
<HorizontalScrollView
android:id="@+id/action_buttons"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
android:layout_weight="0"
android:overScrollMode="never"
android:scrollbars="none">
<org.mariotaku.twidere.view.ActionIconThemedTextView
android:id="@+id/reply_count"
style="?cardActionButtonStyle"
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="@dimen/button_size_content_card"
android:layout_weight="0"
android:drawableLeft="@drawable/ic_action_reply"
android:gravity="center"
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_normal"
android:textAppearance="?android:textAppearanceSmall"
app:iabActivatedColor="@color/highlight_reply"/>
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<org.mariotaku.twidere.view.ActionIconThemedTextView
android:id="@+id/retweet_count"
style="?cardActionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="@dimen/button_size_content_card"
android:layout_weight="0"
android:drawableLeft="@drawable/ic_action_retweet"
android:gravity="center"
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_normal"
android:textAppearance="?android:textAppearanceSmall"
app:iabActivatedColor="@color/highlight_retweet"/>
<org.mariotaku.twidere.view.ActionIconThemedTextView
android:id="@+id/reply_count"
style="?cardActionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="@dimen/button_size_content_card"
android:layout_weight="0"
android:drawableLeft="@drawable/ic_action_reply"
android:gravity="center"
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_normal"
android:textAppearance="?android:textAppearanceSmall"
app:iabActivatedColor="@color/highlight_reply"/>
<org.mariotaku.twidere.view.ActionIconThemedTextView
android:id="@+id/favorite_count"
style="?cardActionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="@dimen/button_size_content_card"
android:layout_weight="0"
android:drawableLeft="@drawable/ic_action_star"
android:gravity="center"
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_normal"
android:textAppearance="?android:textAppearanceSmall"
app:iabActivatedColor="@color/highlight_favorite"/>
<org.mariotaku.twidere.view.ActionIconThemedTextView
android:id="@+id/retweet_count"
style="?cardActionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="@dimen/button_size_content_card"
android:layout_weight="0"
android:drawableLeft="@drawable/ic_action_retweet"
android:gravity="center"
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_normal"
android:textAppearance="?android:textAppearanceSmall"
app:iabActivatedColor="@color/highlight_retweet"/>
</LinearLayout>
</HorizontalScrollView>
<org.mariotaku.twidere.view.ActionIconThemedTextView
android:id="@+id/favorite_count"
style="?cardActionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="@dimen/button_size_content_card"
android:layout_weight="0"
android:drawableLeft="@drawable/ic_action_star"
android:gravity="center"
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_normal"
android:textAppearance="?android:textAppearanceSmall"
app:iabActivatedColor="@color/highlight_favorite"/>
</LinearLayout>
</HorizontalScrollView>
<Space
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<org.mariotaku.twidere.view.ActionIconView
android:id="@+id/extra_type"
android:layout_width="@dimen/element_size_small"
android:layout_height="@dimen/element_size_small"
android:layout_gravity="center|right"
android:layout_marginLeft="@dimen/element_spacing_normal"
android:layout_marginRight="@dimen/element_spacing_normal"
android:layout_weight="0"
android:color="?android:textColorSecondary"
tools:src="@drawable/ic_action_gallery"/>
</LinearLayout>
</org.mariotaku.twidere.view.ColorLabelRelativeLayout>
</merge>

View File

@ -125,7 +125,7 @@
android:singleLine="true"
android:textAppearance="?android:textAppearanceSmall"
android:textColor="?android:textColorSecondary"
android:textSize="10sp"/>
tools:textSize="10sp"/>
</LinearLayout>
<org.mariotaku.twidere.view.ShortTimeView
@ -134,7 +134,16 @@
android:layout_height="wrap_content"
android:layout_weight="0"
android:textAppearance="?android:textAppearanceSmall"
android:textSize="10sp"/>
tools:textSize="10sp"/>
<org.mariotaku.twidere.view.ActionIconView
android:id="@+id/extra_type"
android:layout_width="@dimen/element_size_small"
android:layout_height="@dimen/element_size_small"
android:layout_weight="0"
android:color="?android:textColorSecondary"
tools:src="@drawable/ic_action_gallery"/>
</LinearLayout>
<org.mariotaku.twidere.view.CardMediaContainer

View File

@ -26,20 +26,32 @@
android:layout_height="wrap_content"
android:orientation="vertical">
<org.mariotaku.twidere.view.themed.ThemedTextView
android:id="@+id/reply_retweet_status"
<LinearLayout
android:id="@+id/retweeted_by_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:selectableItemBackground"
android:clickable="true"
android:drawablePadding="4dp"
android:gravity="center_vertical"
android:minHeight="@dimen/element_size_small"
android:padding="@dimen/element_spacing_normal"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:visibility="gone"/>
android:paddingLeft="@dimen/element_spacing_small"
android:paddingRight="@dimen/element_spacing_small"
tools:visiblity="visible">
<Space
android:layout_width="@dimen/element_size_mlarge"
android:layout_height="wrap_content"
android:layout_margin="@dimen/padding_profile_image_detail_page"/>
<org.mariotaku.twidere.view.themed.ThemedTextView
android:id="@+id/retweeted_by"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:minHeight="@dimen/element_size_small"
android:padding="@dimen/element_spacing_normal"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"
tools:text="Retweeted by Mariotaku"/>
</LinearLayout>
<org.mariotaku.twidere.view.ColorLabelRelativeLayout
android:id="@+id/profile_container"
@ -115,8 +127,8 @@
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/element_spacing_small"
android:gravity="center_vertical"
tools:text="Jan 1 2015 0:00, via Twidere"
android:textAppearance="?android:attr/textAppearanceSmall"/>
android:textAppearance="?android:attr/textAppearanceSmall"
tools:text="Jan 1 2015 0:00, via Twidere"/>
</LinearLayout>
@ -163,9 +175,9 @@
<org.mariotaku.twidere.view.TwitterCardContainer
android:id="@+id/twitter_card"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
android:layout_height="wrap_content"
android:visibility="gone"/>
<RelativeLayout
android:id="@+id/location_container"

View File

@ -18,10 +18,11 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/item_profile_image"
android:actionLayout="@layout/action_item_messages_conversation_profile_image"
android:showAsAction="always"
android:title="@string/user"/>
android:title="@string/user"
app:actionLayout="@layout/action_item_messages_conversation_profile_image"
app:showAsAction="always"/>
</menu>

View File

@ -98,4 +98,6 @@
<dimen name="elevation_settings_item">0dp</dimen>
<dimen name="popup_width_account_selector">160dp</dimen>
<dimen name="line_width_compose_account_profile_image">2dp</dimen>
</resources>

View File

@ -716,5 +716,6 @@
<string name="belongs_to">Belongs to</string>
<string name="blocked_by_user_summary">You were blocked by <xliff:g id="name">%s</xliff:g></string>
<string name="select_accounts">Select accounts</string>
<string name="media_preview">Media preview</string>
</resources>

View File

@ -21,7 +21,11 @@
android:order="23"
android:summary="@string/nickname_only_summary"
android:title="@string/nickname_only"/>
<org.mariotaku.twidere.preference.AutoFixCheckBoxPreference
android:defaultValue="false"
android:key="media_preview"
android:order="24"
android:title="@string/media_preview"/>
<org.mariotaku.twidere.preference.LinkHighlightPreference
android:defaultValue="none"