new user profile screen

started to make l transition animation
bug fixes
This commit is contained in:
Mariotaku Lee 2014-12-01 15:00:37 +08:00
parent 8feedc3469
commit b47b7c7d3b
63 changed files with 2989 additions and 2247 deletions

@ -1 +1 @@
Subproject commit 96cb3e6d3df6f68657520e721b4223ee2d2a95bf
Subproject commit f282a42abb5c763d74de01864633eda1f8874c7d

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 37 KiB

View File

@ -2,7 +2,7 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion 21
buildToolsVersion '21.1'
buildToolsVersion '21.1.1'
defaultConfig {
applicationId "org.mariotaku.twidere"
@ -94,6 +94,7 @@ dependencies {
compile 'com.google.android.apps.dashclock:dashclock-api:2.0.0'
compile 'me.grantland:autofittextview:0.2.0'
compile 'com.github.johnpersano:supertoasts:1.3.4.1@aar'
compile 'com.astuetz:pagerslidingtabstrip:1.0.1'
googleCompile 'com.google.android.gms:play-services:6.1.71'
fdroidCompile 'org.osmdroid:osmdroid-android:4.2'
fdroidCompile 'org.slf4j:slf4j-simple:1.6.1'

View File

@ -56,7 +56,7 @@
android:hardwareAccelerated="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/Theme.Blank">
android:theme="@style/Theme.Twidere.Dark">
<uses-library
android:name="com.sec.android.app.multiwindow"
android:required="false"/>

View File

@ -19,9 +19,7 @@
package org.mariotaku.twidere.activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.PorterDuff.Mode;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.support.v4.app.NavUtils;
@ -43,12 +41,6 @@ public abstract class BasePreferenceActivity extends PreferenceActivity implemen
return super.onMenuOpened(featureId, menu);
}
@Override
public void finish() {
super.finish();
overrideCloseAnimationIfNeeded();
}
@Override
public int getCurrentThemeResourceId() {
return mCurrentThemeResource;
@ -83,16 +75,6 @@ public abstract class BasePreferenceActivity extends PreferenceActivity implemen
@Override
public void navigateUpFromSameTask() {
NavUtils.navigateUpFromSameTask(this);
overrideCloseAnimationIfNeeded();
}
@Override
public void overrideCloseAnimationIfNeeded() {
if (shouldOverrideActivityAnimation()) {
ThemeUtils.overrideActivityCloseAnimation(this);
} else {
ThemeUtils.overrideNormalActivityCloseAnimation(this);
}
}
@Override
@ -100,20 +82,12 @@ public abstract class BasePreferenceActivity extends PreferenceActivity implemen
restartActivity(this);
}
@Override
public boolean shouldOverrideActivityAnimation() {
return true;
}
protected final boolean isThemeChanged() {
return getThemeResourceId() != mCurrentThemeResource;
}
@Override
protected void onCreate(final Bundle savedInstanceState) {
if (shouldOverrideActivityAnimation()) {
ThemeUtils.overrideActivityOpenAnimation(this);
}
ThemeUtils.notifyStatusBarColorChanged(this, mCurrentThemeResource, 0, 0xFF);
setTheme(mCurrentThemeResource = getThemeResourceId());
super.onCreate(savedInstanceState);

View File

@ -39,12 +39,6 @@ public abstract class BaseThemedActivity extends Activity implements IThemedActi
private String mCurrentThemeFontFamily;
private Theme mTheme;
@Override
public void finish() {
super.finish();
overrideCloseAnimationIfNeeded();
}
@Override
public Resources getDefaultResources() {
return super.getResources();
@ -87,16 +81,6 @@ public abstract class BaseThemedActivity extends Activity implements IThemedActi
@Override
public void navigateUpFromSameTask() {
NavUtils.navigateUpFromSameTask(this);
overrideCloseAnimationIfNeeded();
}
@Override
public void overrideCloseAnimationIfNeeded() {
if (shouldOverrideActivityAnimation()) {
ThemeUtils.overrideActivityCloseAnimation(this);
} else {
ThemeUtils.overrideNormalActivityCloseAnimation(this);
}
}
@Override
@ -104,11 +88,6 @@ public abstract class BaseThemedActivity extends Activity implements IThemedActi
restartActivity(this);
}
@Override
public boolean shouldOverrideActivityAnimation() {
return true;
}
protected final boolean isThemeChanged() {
return getThemeResourceId() != mCurrentThemeResource || getThemeColor() != mCurrentThemeColor
|| !CompareUtils.objectEquals(getThemeFontFamily(), mCurrentThemeFontFamily)
@ -122,12 +101,8 @@ public abstract class BaseThemedActivity extends Activity implements IThemedActi
StrictModeUtils.detectAllThreadPolicy();
}
if (shouldOverrideActivityAnimation()) {
ThemeUtils.overrideActivityOpenAnimation(this);
}
setTheme();
super.onCreate(savedInstanceState);
// AccentThemeFixer.fixActionBar(getActionBar(), this);
setActionBarBackground();
}

View File

@ -37,9 +37,6 @@ public interface IThemedActivity {
public void navigateUpFromSameTask();
public void overrideCloseAnimationIfNeeded();
public void restart();
public boolean shouldOverrideActivityAnimation();
}

View File

@ -46,12 +46,6 @@ public class BaseSupportDialogActivity extends BaseSupportThemedActivity impleme
return (TwidereApplication) getApplication();
}
@Override
public final boolean shouldOverrideActivityAnimation() {
// Dialog theme should never use custom animations
return false;
}
protected boolean isStateSaved() {
return mInstanceStateSaved;
}

View File

@ -39,12 +39,6 @@ public abstract class BaseSupportThemedActivity extends FragmentActivity impleme
private int mCurrentThemeResource, mCurrentThemeColor, mCurrentThemeBackgroundAlpha;
@Override
public void finish() {
super.finish();
overrideCloseAnimationIfNeeded();
}
@Override
public Resources getDefaultResources() {
return super.getResources();
@ -68,38 +62,19 @@ public abstract class BaseSupportThemedActivity extends FragmentActivity impleme
@Override
public void navigateUpFromSameTask() {
NavUtils.navigateUpFromSameTask(this);
overrideCloseAnimationIfNeeded();
}
@Override
public void overrideCloseAnimationIfNeeded() {
if (shouldOverrideActivityAnimation()) {
ThemeUtils.overrideActivityCloseAnimation(this);
} else {
ThemeUtils.overrideNormalActivityCloseAnimation(this);
}
}
@Override
public final void restart() {
restartActivity(this);
}
@Override
public boolean shouldOverrideActivityAnimation() {
return true;
}
@Override
protected void onCreate(final Bundle savedInstanceState) {
if (Utils.isDebugBuild()) {
StrictModeUtils.detectAllVmPolicy();
StrictModeUtils.detectAllThreadPolicy();
}
if (shouldOverrideActivityAnimation()) {
ThemeUtils.overrideActivityOpenAnimation(this);
}
setTheme();
super.onCreate(savedInstanceState);
setActionBarBackground();

View File

@ -1212,7 +1212,8 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa
final boolean is_my_status = status.account_id == status.user_id;
final boolean hasMedia = status.media != null && status.media.length > 0;
mHolder.setUserColor(getUserColor(getActivity(), status.user_id, true));
mHolder.setHighlightColor(getCardHighlightColor(false, status.is_favorite, status.is_retweet));
mHolder.setHighlightColor(getCardHighlightColor(getResources(), false,
status.is_favorite, status.is_retweet));
mHolder.setIsMyStatus(is_my_status && !prefs.getBoolean(KEY_INDICATE_MY_STATUS, true));

View File

@ -432,11 +432,6 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
public void setHomeProgressBarIndeterminateVisibility(final boolean visible) {
}
@Override
public boolean shouldOverrideActivityAnimation() {
return false;
}
@Override
public float getControlBarOffset() {
final float totalHeight = getControlBarHeight();
@ -493,8 +488,7 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
protected void onCreate(final Bundle savedInstanceState) {
setUiOptions(getWindow());
final Window window = getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.requestFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
if (!isDatabaseReady(this)) {

View File

@ -24,15 +24,19 @@ import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.ListFragment;
import android.transition.Transition;
import android.transition.TransitionInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.Window;
import android.view.WindowManager.LayoutParams;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.iface.IControlBarActivity;
@ -117,8 +121,9 @@ public class LinkHandlerActivity extends BaseSupportActivity implements OnClickL
mMultiSelectHandler.dispatchOnCreate();
final Intent intent = getIntent();
final Uri data = intent.getData();
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setUiOptions(getWindow(), data);
final int linkId = matchLinkId(data);
requestWindowFeatures(getWindow(), linkId, data);
setUiOptions(getWindow(), linkId, data);
super.onCreate(savedInstanceState);
final ActionBar actionBar = getActionBar();
if (actionBar != null) {
@ -126,11 +131,29 @@ public class LinkHandlerActivity extends BaseSupportActivity implements OnClickL
}
setContentView(R.layout.activity_content_fragment);
setProgressBarIndeterminateVisibility(false);
if (data == null || !showFragment(data)) {
if (data == null || !showFragment(linkId, data)) {
finish();
}
}
private void requestWindowFeatures(Window window, int linkId, Uri uri) {
switch (linkId) {
case LINK_ID_USER: {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
window.addFlags(LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);
final TransitionInflater inflater = TransitionInflater.from(this);
final Transition transition = inflater.inflateTransition(R.transition.transition_user_profile);
window.setSharedElementEnterTransition(transition);
window.setSharedElementExitTransition(transition);
}
break;
}
}
}
@Override
protected void onStart() {
super.onStart();
@ -152,9 +175,9 @@ public class LinkHandlerActivity extends BaseSupportActivity implements OnClickL
}
}
private void setUiOptions(final Window window, final Uri uri) {
private void setUiOptions(final Window window, int linkId, final Uri uri) {
if (!FlymeUtils.hasSmartBar()) return;
switch (matchLinkId(uri)) {
switch (linkId) {
case LINK_ID_USER: {
window.setUiOptions(ActivityInfo.UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW);
break;
@ -162,12 +185,12 @@ public class LinkHandlerActivity extends BaseSupportActivity implements OnClickL
}
}
private boolean showFragment(final Uri uri) {
private boolean showFragment(final int linkId, final Uri uri) {
final Intent intent = getIntent();
intent.setExtrasClassLoader(getClassLoader());
final Fragment fragment = createFragmentForIntent(this, intent);
final Fragment fragment = createFragmentForIntent(this, linkId, intent);
if (uri == null || fragment == null) return false;
switch (matchLinkId(uri)) {
switch (linkId) {
case LINK_ID_STATUS: {
setTitle(R.string.status);
break;

View File

@ -24,6 +24,7 @@ import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.v4.app.ActivityOptionsCompat;
import android.text.Html;
import android.text.TextUtils;
import android.view.View;
@ -119,6 +120,7 @@ public class CursorStatusesAdapter extends BaseCursorAdapter implements IStatuse
// Clear images in prder to prevent images in recycled view shown.
final Resources res = mContext.getResources();
final TwidereLinkify linkify = getLinkify();
final boolean showAccountColor = isShowAccountColor();
@ -162,7 +164,7 @@ public class CursorStatusesAdapter extends BaseCursorAdapter implements IStatuse
} else {
holder.setUserColor(getUserColor(mContext, userId));
}
holder.setHighlightColor(getCardHighlightColor(!mMentionsHighlightDisabled && isMention,
holder.setHighlightColor(getCardHighlightColor(res, !mMentionsHighlightDisabled && isMention,
!mFavoritesHighlightDisabled && isFavorite, isRetweet));
holder.setAccountColorEnabled(showAccountColor);
@ -231,7 +233,6 @@ public class CursorStatusesAdapter extends BaseCursorAdapter implements IStatuse
holder.image_preview.setBackgroundResource(0);
mImageLoader.displayPreviewImage(holder.image_preview, firstMedia, mImageLoadingHandler);
}
final Resources res = mContext.getResources();
final int count = media.length;
holder.image_preview_count.setText(res.getQuantityString(R.plurals.N_media, count, count));
holder.image_preview.setTag(position);
@ -372,9 +373,11 @@ public class CursorStatusesAdapter extends BaseCursorAdapter implements IStatuse
case R.id.profile_image: {
final ParcelableStatus status = getStatus(position);
if (status == null) return;
if (mContext instanceof Activity) {
openUserProfile((Activity) mContext, status.account_id, status.user_id, status.user_screen_name);
}
final Activity activity = (Activity) getContext();
final ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(activity,
view, "profile_image");
openUserProfile(mContext, status.account_id, status.user_id,
status.user_screen_name, options.toBundle());
break;
}
}

View File

@ -19,19 +19,6 @@
package org.mariotaku.twidere.adapter;
import static org.mariotaku.twidere.provider.TweetStore.DirectMessages.ConversationEntries.IDX_ACCOUNT_ID;
import static org.mariotaku.twidere.provider.TweetStore.DirectMessages.ConversationEntries.IDX_CONVERSATION_ID;
import static org.mariotaku.twidere.provider.TweetStore.DirectMessages.ConversationEntries.IDX_NAME;
import static org.mariotaku.twidere.provider.TweetStore.DirectMessages.ConversationEntries.IDX_PROFILE_IMAGE_URL;
import static org.mariotaku.twidere.provider.TweetStore.DirectMessages.ConversationEntries.IDX_SCREEN_NAME;
import static org.mariotaku.twidere.provider.TweetStore.DirectMessages.ConversationEntries.IDX_TEXT;
import static org.mariotaku.twidere.util.HtmlEscapeHelper.toPlainText;
import static org.mariotaku.twidere.util.UserColorNicknameUtils.getUserColor;
import static org.mariotaku.twidere.util.UserColorNicknameUtils.getUserNickname;
import static org.mariotaku.twidere.util.Utils.configBaseCardAdapter;
import static org.mariotaku.twidere.util.Utils.getAccountColor;
import static org.mariotaku.twidere.util.Utils.openUserProfile;
import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
@ -49,154 +36,167 @@ import org.mariotaku.twidere.util.MultiSelectManager;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.holder.DirectMessageEntryViewHolder;
import static org.mariotaku.twidere.provider.TweetStore.DirectMessages.ConversationEntries.IDX_ACCOUNT_ID;
import static org.mariotaku.twidere.provider.TweetStore.DirectMessages.ConversationEntries.IDX_CONVERSATION_ID;
import static org.mariotaku.twidere.provider.TweetStore.DirectMessages.ConversationEntries.IDX_NAME;
import static org.mariotaku.twidere.provider.TweetStore.DirectMessages.ConversationEntries.IDX_PROFILE_IMAGE_URL;
import static org.mariotaku.twidere.provider.TweetStore.DirectMessages.ConversationEntries.IDX_SCREEN_NAME;
import static org.mariotaku.twidere.provider.TweetStore.DirectMessages.ConversationEntries.IDX_TEXT;
import static org.mariotaku.twidere.util.HtmlEscapeHelper.toPlainText;
import static org.mariotaku.twidere.util.UserColorNicknameUtils.getUserColor;
import static org.mariotaku.twidere.util.UserColorNicknameUtils.getUserNickname;
import static org.mariotaku.twidere.util.Utils.configBaseCardAdapter;
import static org.mariotaku.twidere.util.Utils.getAccountColor;
import static org.mariotaku.twidere.util.Utils.openUserProfile;
public class DirectMessageConversationEntriesAdapter extends BaseCursorAdapter implements IBaseCardAdapter,
OnClickListener {
OnClickListener {
private final ImageLoaderWrapper mImageLoader;
private final MultiSelectManager mMultiSelectManager;
private final ImageLoaderWrapper mImageLoader;
private final MultiSelectManager mMultiSelectManager;
private boolean mAnimationEnabled;
private int mMaxAnimationPosition;
private boolean mAnimationEnabled;
private int mMaxAnimationPosition;
private final boolean mPlainList;
private final boolean mPlainList;
public DirectMessageConversationEntriesAdapter(final Context context) {
this(context, Utils.isCompactCards(context), Utils.isPlainListStyle(context));
}
public DirectMessageConversationEntriesAdapter(final Context context) {
this(context, Utils.isCompactCards(context), Utils.isPlainListStyle(context));
}
public DirectMessageConversationEntriesAdapter(final Context context, final boolean compactCards,
final boolean plainList) {
super(context, getItemResource(compactCards), null, new String[0], new int[0], 0);
mPlainList = plainList;
final TwidereApplication app = TwidereApplication.getInstance(context);
mMultiSelectManager = app.getMultiSelectManager();
mImageLoader = app.getImageLoaderWrapper();
configBaseCardAdapter(context, this);
}
public DirectMessageConversationEntriesAdapter(final Context context, final boolean compactCards,
final boolean plainList) {
super(context, getItemResource(compactCards), null, new String[0], new int[0], 0);
mPlainList = plainList;
final TwidereApplication app = TwidereApplication.getInstance(context);
mMultiSelectManager = app.getMultiSelectManager();
mImageLoader = app.getImageLoaderWrapper();
configBaseCardAdapter(context, this);
}
@Override
public void bindView(final View view, final Context context, final Cursor cursor) {
final DirectMessageEntryViewHolder holder = (DirectMessageEntryViewHolder) view.getTag();
final int position = cursor.getPosition();
final long accountId = cursor.getLong(ConversationEntries.IDX_ACCOUNT_ID);
final long conversationId = cursor.getLong(ConversationEntries.IDX_CONVERSATION_ID);
final long timestamp = cursor.getLong(ConversationEntries.IDX_MESSAGE_TIMESTAMP);
final boolean isOutgoing = cursor.getInt(ConversationEntries.IDX_IS_OUTGOING) == 1;
@Override
public void bindView(final View view, final Context context, final Cursor cursor) {
final DirectMessageEntryViewHolder holder = (DirectMessageEntryViewHolder) view.getTag();
final int position = cursor.getPosition();
final long accountId = cursor.getLong(ConversationEntries.IDX_ACCOUNT_ID);
final long conversationId = cursor.getLong(ConversationEntries.IDX_CONVERSATION_ID);
final long timestamp = cursor.getLong(ConversationEntries.IDX_MESSAGE_TIMESTAMP);
final boolean isOutgoing = cursor.getInt(ConversationEntries.IDX_IS_OUTGOING) == 1;
final String name = cursor.getString(IDX_NAME);
final String screenName = cursor.getString(IDX_SCREEN_NAME);
final String name = cursor.getString(IDX_NAME);
final String screenName = cursor.getString(IDX_SCREEN_NAME);
final boolean showAccountColor = isShowAccountColor();
final boolean showAccountColor = isShowAccountColor();
holder.setAccountColorEnabled(showAccountColor);
holder.setAccountColorEnabled(showAccountColor);
if (showAccountColor) {
holder.setAccountColor(getAccountColor(mContext, accountId));
}
if (showAccountColor) {
holder.setAccountColor(getAccountColor(mContext, accountId));
}
holder.setUserColor(getUserColor(mContext, conversationId));
holder.setUserColor(getUserColor(mContext, conversationId));
holder.setTextSize(getTextSize());
final String nick = getUserNickname(context, conversationId);
holder.name.setText(TextUtils.isEmpty(nick) ? name : isNicknameOnly() ? nick : context.getString(
R.string.name_with_nickname, name, nick));
holder.screen_name.setText("@" + screenName);
holder.screen_name.setVisibility(View.VISIBLE);
holder.text.setText(toPlainText(cursor.getString(IDX_TEXT)));
holder.time.setTime(timestamp);
holder.setIsOutgoing(isOutgoing);
final boolean displayProfileImage = isDisplayProfileImage();
holder.profile_image.setVisibility(displayProfileImage ? View.VISIBLE : View.GONE);
if (displayProfileImage) {
holder.profile_image.setTag(position);
final String profile_image_url_string = cursor.getString(IDX_PROFILE_IMAGE_URL);
mImageLoader.displayProfileImage(holder.profile_image, profile_image_url_string);
} else {
holder.setTextSize(getTextSize());
final String nick = getUserNickname(context, conversationId);
holder.name.setText(TextUtils.isEmpty(nick) ? name : isNicknameOnly() ? nick : context.getString(
R.string.name_with_nickname, name, nick));
holder.screen_name.setText("@" + screenName);
holder.screen_name.setVisibility(View.VISIBLE);
holder.text.setText(toPlainText(cursor.getString(IDX_TEXT)));
holder.time.setTime(timestamp);
holder.setIsOutgoing(isOutgoing);
final boolean displayProfileImage = isDisplayProfileImage();
holder.profile_image.setVisibility(displayProfileImage ? View.VISIBLE : View.GONE);
if (displayProfileImage) {
holder.profile_image.setTag(position);
final String profile_image_url_string = cursor.getString(IDX_PROFILE_IMAGE_URL);
mImageLoader.displayProfileImage(holder.profile_image, profile_image_url_string);
} else {
mImageLoader.cancelDisplayTask(holder.profile_image);
}
if (position > mMaxAnimationPosition) {
if (mAnimationEnabled) {
view.startAnimation(holder.item_animation);
}
mMaxAnimationPosition = position;
}
super.bindView(view, context, cursor);
}
if (position > mMaxAnimationPosition) {
if (mAnimationEnabled) {
view.startAnimation(holder.item_animation);
}
mMaxAnimationPosition = position;
}
super.bindView(view, context, cursor);
}
public long getAccountId(final int position) {
final Cursor c = getCursor();
if (c == null || c.isClosed() || !c.moveToPosition(position)) return -1;
return c.getLong(IDX_ACCOUNT_ID);
}
public long getAccountId(final int position) {
final Cursor c = getCursor();
if (c == null || c.isClosed() || !c.moveToPosition(position)) return -1;
return c.getLong(IDX_ACCOUNT_ID);
}
public long getConversationId(final int position) {
final Cursor c = getCursor();
if (c == null || c.isClosed() || !c.moveToPosition(position)) return -1;
return c.getLong(IDX_CONVERSATION_ID);
}
public long getConversationId(final int position) {
final Cursor c = getCursor();
if (c == null || c.isClosed() || !c.moveToPosition(position)) return -1;
return c.getLong(IDX_CONVERSATION_ID);
}
public String getScreenName(final int position) {
final Cursor c = getCursor();
if (c == null || c.isClosed() || !c.moveToPosition(position)) return null;
return c.getString(IDX_SCREEN_NAME);
}
public String getScreenName(final int position) {
final Cursor c = getCursor();
if (c == null || c.isClosed() || !c.moveToPosition(position)) return null;
return c.getString(IDX_SCREEN_NAME);
}
@Override
public View newView(final Context context, final Cursor cursor, final ViewGroup parent) {
final View view = super.newView(context, cursor, parent);
final Object tag = view.getTag();
if (!(tag instanceof DirectMessageEntryViewHolder)) {
final DirectMessageEntryViewHolder holder = new DirectMessageEntryViewHolder(view);
holder.profile_image.setOnClickListener(this);
if (mPlainList) {
((View) holder.content).setPadding(0, 0, 0, 0);
holder.content.setItemBackground(null);
}
view.setTag(holder);
}
return view;
}
@Override
public View newView(final Context context, final Cursor cursor, final ViewGroup parent) {
final View view = super.newView(context, cursor, parent);
final Object tag = view.getTag();
if (!(tag instanceof DirectMessageEntryViewHolder)) {
final DirectMessageEntryViewHolder holder = new DirectMessageEntryViewHolder(view);
holder.profile_image.setOnClickListener(this);
if (mPlainList) {
((View) holder.content).setPadding(0, 0, 0, 0);
holder.content.setItemBackground(null);
}
view.setTag(holder);
}
return view;
}
@Override
public void onClick(final View view) {
if (mMultiSelectManager.isActive()) return;
final Object tag = view.getTag();
final int position = tag instanceof Integer ? (Integer) tag : -1;
if (position == -1) return;
switch (view.getId()) {
case R.id.profile_image: {
if (mContext instanceof Activity) {
final long account_id = getAccountId(position);
final long user_id = getConversationId(position);
final String screen_name = getScreenName(position);
openUserProfile((Activity) mContext, account_id, user_id, screen_name);
}
break;
}
// case R.id.item_menu: {
// if (position == -1 || mListener == null) return;
// mListener.onMenuButtonClick(view, position, getItemId(position));
// break;
// }
}
}
@Override
public void onClick(final View view) {
if (mMultiSelectManager.isActive()) return;
final Object tag = view.getTag();
final int position = tag instanceof Integer ? (Integer) tag : -1;
if (position == -1) return;
switch (view.getId()) {
case R.id.profile_image: {
if (mContext instanceof Activity) {
final long account_id = getAccountId(position);
final long user_id = getConversationId(position);
final String screen_name = getScreenName(position);
openUserProfile(mContext, account_id, user_id, screen_name, null);
}
break;
}
// case R.id.item_menu: {
// if (position == -1 || mListener == null) return;
// mListener.onMenuButtonClick(view, position, getItemId(position));
// break;
// }
}
}
@Override
public void setAnimationEnabled(final boolean anim) {
if (mAnimationEnabled == anim) return;
mAnimationEnabled = anim;
}
@Override
public void setAnimationEnabled(final boolean anim) {
if (mAnimationEnabled == anim) return;
mAnimationEnabled = anim;
}
@Override
public void setMaxAnimationPosition(final int position) {
mMaxAnimationPosition = position;
}
@Override
public void setMaxAnimationPosition(final int position) {
mMaxAnimationPosition = position;
}
@Override
public void setMenuButtonClickListener(final MenuButtonClickListener listener) {
}
@Override
public void setMenuButtonClickListener(final MenuButtonClickListener listener) {
}
private static int getItemResource(final boolean compactCards) {
return compactCards ? R.layout.card_item_message_entry_compact : R.layout.card_item_message_entry;
}
private static int getItemResource(final boolean compactCards) {
return compactCards ? R.layout.card_item_message_entry_compact : R.layout.card_item_message_entry;
}
}

View File

@ -19,11 +19,6 @@
package org.mariotaku.twidere.adapter;
import static org.mariotaku.twidere.util.UserColorNicknameUtils.getUserColor;
import static org.mariotaku.twidere.util.UserColorNicknameUtils.getUserNickname;
import static org.mariotaku.twidere.util.Utils.getAccountColor;
import static org.mariotaku.twidere.util.Utils.getCardHighlightColor;
import android.content.Context;
import android.text.Html;
import android.text.TextUtils;
@ -40,261 +35,266 @@ import org.mariotaku.twidere.util.ImageLoadingHandler;
import org.mariotaku.twidere.util.TwidereLinkify;
import org.mariotaku.twidere.view.holder.ActivityListViewHolder;
import static org.mariotaku.twidere.util.UserColorNicknameUtils.getUserColor;
import static org.mariotaku.twidere.util.UserColorNicknameUtils.getUserNickname;
import static org.mariotaku.twidere.util.Utils.getAccountColor;
import static org.mariotaku.twidere.util.Utils.getCardHighlightColor;
public class ParcelableActivitiesAboutMeAdapter extends BaseParcelableActivitiesAdapter {
private final ImageLoadingHandler mImageLoadingHandler;
private final ImageLoadingHandler mImageLoadingHandler;
private boolean mGapDisallowed;
private boolean mIndicateMyStatusDisabled;
private boolean mFavoritesHighlightDisabled;
private boolean mDisplayImagePreview;
private boolean mDisplaySensitiveContents;
private boolean mGapDisallowed;
private boolean mIndicateMyStatusDisabled;
private boolean mFavoritesHighlightDisabled;
private boolean mDisplayImagePreview;
private boolean mDisplaySensitiveContents;
public ParcelableActivitiesAboutMeAdapter(final Context context, final boolean compactCards, final boolean plainList) {
super(context, compactCards, plainList);
mImageLoadingHandler = new ImageLoadingHandler();
}
public ParcelableActivitiesAboutMeAdapter(final Context context, final boolean compactCards, final boolean plainList) {
super(context, compactCards, plainList);
mImageLoadingHandler = new ImageLoadingHandler();
}
@Override
public void bindView(final int position, final ActivityListViewHolder holder, final ParcelableActivity item) {
if (item == null) return;
final ParcelableUser[] sources = item.sources;
if (sources == null || sources.length == 0) return;
final ParcelableStatus[] targetStatuses = item.target_statuses;
final int action = item.action;
final boolean displayProfileImage = shouldDisplayProfileImage();
@Override
public void bindView(final int position, final ActivityListViewHolder holder, final ParcelableActivity item) {
if (item == null) return;
final ParcelableUser[] sources = item.sources;
if (sources == null || sources.length == 0) return;
final ParcelableStatus[] targetStatuses = item.target_statuses;
final int action = item.action;
final boolean displayProfileImage = shouldDisplayProfileImage();
final TwidereLinkify linkify = getLinkify();
final int highlightOption = getLinkHighlightOption();
final TwidereLinkify linkify = getLinkify();
final int highlightOption = getLinkHighlightOption();
final Context context = getContext();
final ParcelableUser firstSource = sources[0];
final ParcelableStatus[] targetObjects = item.target_object_statuses;
final String sourceName = getName(firstSource);
switch (action) {
case ParcelableActivity.ACTION_FAVORITE: {
holder.name.setVisibility(View.VISIBLE);
holder.screen_name.setVisibility(View.GONE);
holder.profile_image.setVisibility(View.GONE);
holder.my_profile_image.setVisibility(View.GONE);
holder.text.setVisibility(View.VISIBLE);
holder.reply_retweet_status.setVisibility(View.GONE);
holder.activity_profile_images_container.setVisibility(displayProfileImage ? View.VISIBLE : View.GONE);
final Context context = getContext();
final ParcelableUser firstSource = sources[0];
final ParcelableStatus[] targetObjects = item.target_object_statuses;
final String sourceName = getName(firstSource);
switch (action) {
case ParcelableActivity.ACTION_FAVORITE: {
holder.name.setVisibility(View.VISIBLE);
holder.screen_name.setVisibility(View.GONE);
holder.profile_image.setVisibility(View.GONE);
holder.my_profile_image.setVisibility(View.GONE);
holder.text.setVisibility(View.VISIBLE);
holder.reply_retweet_status.setVisibility(View.GONE);
holder.activity_profile_images_container.setVisibility(displayProfileImage ? View.VISIBLE : View.GONE);
holder.name.setSingleLine(false);
holder.name.setSingleLine(false);
if (targetStatuses != null && targetStatuses.length > 0) {
final ParcelableStatus status = targetStatuses[0];
if (highlightOption != VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE) {
holder.text.setText(Html.fromHtml(status.text_html));
linkify.applyAllLinks(holder.text, status.account_id, status.is_possibly_sensitive);
holder.text.setMovementMethod(null);
} else {
holder.text.setText(status.text_unescaped);
}
}
if (sources.length == 1) {
holder.name.setText(context.getString(R.string.activity_about_me_favorite, sourceName));
} else {
holder.name.setText(context.getString(R.string.activity_about_me_favorite_multi, sourceName,
sources.length - 1));
}
displayActivityUserProfileImages(holder, sources);
break;
}
case ParcelableActivity.ACTION_FOLLOW: {
holder.name.setVisibility(View.VISIBLE);
holder.screen_name.setVisibility(View.GONE);
holder.profile_image.setVisibility(View.GONE);
holder.my_profile_image.setVisibility(View.GONE);
holder.text.setVisibility(View.GONE);
holder.reply_retweet_status.setVisibility(View.GONE);
if (targetStatuses != null && targetStatuses.length > 0) {
final ParcelableStatus status = targetStatuses[0];
if (highlightOption != VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE) {
holder.text.setText(Html.fromHtml(status.text_html));
linkify.applyAllLinks(holder.text, status.account_id, status.is_possibly_sensitive);
holder.text.setMovementMethod(null);
} else {
holder.text.setText(status.text_unescaped);
}
}
if (sources.length == 1) {
holder.name.setText(context.getString(R.string.activity_about_me_favorite, sourceName));
} else {
holder.name.setText(context.getString(R.string.activity_about_me_favorite_multi, sourceName,
sources.length - 1));
}
displayActivityUserProfileImages(holder, sources);
break;
}
case ParcelableActivity.ACTION_FOLLOW: {
holder.name.setVisibility(View.VISIBLE);
holder.screen_name.setVisibility(View.GONE);
holder.profile_image.setVisibility(View.GONE);
holder.my_profile_image.setVisibility(View.GONE);
holder.text.setVisibility(View.GONE);
holder.reply_retweet_status.setVisibility(View.GONE);
holder.name.setSingleLine(false);
holder.name.setSingleLine(false);
if (sources.length == 1) {
holder.name.setText(context.getString(R.string.activity_about_me_follow, sourceName));
} else {
holder.name.setText(context.getString(R.string.activity_about_me_follow_multi, sourceName,
sources.length - 1));
}
displayActivityUserProfileImages(holder, sources);
break;
}
case ParcelableActivity.ACTION_MENTION: {
if (targetObjects != null && targetObjects.length > 0) {
final ParcelableStatus status = targetObjects[0];
displayStatus(status, holder, position);
}
break;
}
case ParcelableActivity.ACTION_REPLY: {
if (targetStatuses != null && targetStatuses.length > 0) {
final ParcelableStatus status = targetStatuses[0];
displayStatus(status, holder, position);
}
break;
}
case ParcelableActivity.ACTION_RETWEET: {
if (sources.length == 1) {
holder.name.setText(context.getString(R.string.activity_about_me_follow, sourceName));
} else {
holder.name.setText(context.getString(R.string.activity_about_me_follow_multi, sourceName,
sources.length - 1));
}
displayActivityUserProfileImages(holder, sources);
break;
}
case ParcelableActivity.ACTION_MENTION: {
if (targetObjects != null && targetObjects.length > 0) {
final ParcelableStatus status = targetObjects[0];
displayStatus(status, holder, position);
}
break;
}
case ParcelableActivity.ACTION_REPLY: {
if (targetStatuses != null && targetStatuses.length > 0) {
final ParcelableStatus status = targetStatuses[0];
displayStatus(status, holder, position);
}
break;
}
case ParcelableActivity.ACTION_RETWEET: {
holder.name.setVisibility(View.VISIBLE);
holder.screen_name.setVisibility(View.GONE);
holder.profile_image.setVisibility(View.GONE);
holder.my_profile_image.setVisibility(View.GONE);
holder.text.setVisibility(View.VISIBLE);
holder.reply_retweet_status.setVisibility(View.GONE);
holder.name.setVisibility(View.VISIBLE);
holder.screen_name.setVisibility(View.GONE);
holder.profile_image.setVisibility(View.GONE);
holder.my_profile_image.setVisibility(View.GONE);
holder.text.setVisibility(View.VISIBLE);
holder.reply_retweet_status.setVisibility(View.GONE);
holder.name.setSingleLine(false);
holder.name.setSingleLine(false);
if (targetObjects != null && targetObjects.length > 0) {
final ParcelableStatus status = targetObjects[0];
if (highlightOption != VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE) {
holder.text.setText(Html.fromHtml(status.text_html));
linkify.applyAllLinks(holder.text, status.account_id, status.is_possibly_sensitive);
holder.text.setMovementMethod(null);
} else {
holder.text.setText(status.text_unescaped);
}
}
if (targetObjects != null && targetObjects.length > 0) {
final ParcelableStatus status = targetObjects[0];
if (highlightOption != VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE) {
holder.text.setText(Html.fromHtml(status.text_html));
linkify.applyAllLinks(holder.text, status.account_id, status.is_possibly_sensitive);
holder.text.setMovementMethod(null);
} else {
holder.text.setText(status.text_unescaped);
}
}
if (sources.length == 1) {
holder.name.setText(context.getString(R.string.activity_about_me_retweet, sourceName));
} else {
holder.name.setText(context.getString(R.string.activity_about_me_retweet_multi, sourceName,
sources.length - 1));
}
holder.activity_profile_images_container.setVisibility(View.VISIBLE);
displayActivityUserProfileImages(holder, sources);
break;
}
case ParcelableActivity.ACTION_LIST_MEMBER_ADDED: {
holder.name.setVisibility(View.VISIBLE);
holder.screen_name.setVisibility(View.GONE);
holder.profile_image.setVisibility(View.GONE);
holder.my_profile_image.setVisibility(View.GONE);
holder.text.setVisibility(View.GONE);
holder.reply_retweet_status.setVisibility(View.GONE);
if (sources.length == 1) {
holder.name.setText(context.getString(R.string.activity_about_me_retweet, sourceName));
} else {
holder.name.setText(context.getString(R.string.activity_about_me_retweet_multi, sourceName,
sources.length - 1));
}
holder.activity_profile_images_container.setVisibility(View.VISIBLE);
displayActivityUserProfileImages(holder, sources);
break;
}
case ParcelableActivity.ACTION_LIST_MEMBER_ADDED: {
holder.name.setVisibility(View.VISIBLE);
holder.screen_name.setVisibility(View.GONE);
holder.profile_image.setVisibility(View.GONE);
holder.my_profile_image.setVisibility(View.GONE);
holder.text.setVisibility(View.GONE);
holder.reply_retweet_status.setVisibility(View.GONE);
holder.name.setSingleLine(false);
holder.name.setSingleLine(false);
if (sources.length == 1) {
if (item.target_object_user_lists != null && item.target_object_user_lists.length > 0) {
final ParcelableUserList list = item.target_object_user_lists[0];
holder.name.setText(context.getString(R.string.activity_about_me_list_member_added_with_name,
sourceName, list.name));
} else {
holder.name
.setText(context.getString(R.string.activity_about_me_list_member_added, sourceName));
}
} else {
holder.name.setText(context.getString(R.string.activity_about_me_list_member_added_multi,
sourceName, sources.length - 1));
}
displayActivityUserProfileImages(holder, sources);
break;
}
}
}
if (sources.length == 1) {
if (item.target_object_user_lists != null && item.target_object_user_lists.length > 0) {
final ParcelableUserList list = item.target_object_user_lists[0];
holder.name.setText(context.getString(R.string.activity_about_me_list_member_added_with_name,
sourceName, list.name));
} else {
holder.name
.setText(context.getString(R.string.activity_about_me_list_member_added, sourceName));
}
} else {
holder.name.setText(context.getString(R.string.activity_about_me_list_member_added_multi,
sourceName, sources.length - 1));
}
displayActivityUserProfileImages(holder, sources);
break;
}
}
}
private void displayStatus(final ParcelableStatus status, final ActivityListViewHolder holder, final int position) {
private void displayStatus(final ParcelableStatus status, final ActivityListViewHolder holder, final int position) {
final boolean showGap = status.is_gap && !mGapDisallowed && position != getCount() - 1;
final boolean displayProfileImage = isDisplayProfileImage();
final Context context = getContext();
final boolean showGap = status.is_gap && !mGapDisallowed && position != getCount() - 1;
final boolean displayProfileImage = isDisplayProfileImage();
final Context context = getContext();
holder.setShowAsGap(showGap);
holder.name.setVisibility(View.VISIBLE);
holder.screen_name.setVisibility(View.VISIBLE);
holder.text.setVisibility(View.VISIBLE);
holder.profile_image.setVisibility(displayProfileImage ? View.VISIBLE : View.GONE);
holder.activity_profile_images_container.setVisibility(View.GONE);
holder.setShowAsGap(showGap);
holder.name.setVisibility(View.VISIBLE);
holder.screen_name.setVisibility(View.VISIBLE);
holder.text.setVisibility(View.VISIBLE);
holder.profile_image.setVisibility(displayProfileImage ? View.VISIBLE : View.GONE);
holder.activity_profile_images_container.setVisibility(View.GONE);
holder.name.setSingleLine(true);
holder.text.setSingleLine(false);
holder.name.setSingleLine(true);
holder.text.setSingleLine(false);
if (!showGap) {
final TwidereLinkify linkify = getLinkify();
final int highlightOption = getLinkHighlightOption();
final boolean showAccountColor = isShowAccountColor();
if (!showGap) {
final TwidereLinkify linkify = getLinkify();
final int highlightOption = getLinkHighlightOption();
final boolean showAccountColor = isShowAccountColor();
// Clear images in prder to prevent images in recycled view shown.
holder.profile_image.setImageDrawable(null);
holder.my_profile_image.setImageDrawable(null);
holder.image_preview.setImageDrawable(null);
// Clear images in prder to prevent images in recycled view shown.
holder.profile_image.setImageDrawable(null);
holder.my_profile_image.setImageDrawable(null);
holder.image_preview.setImageDrawable(null);
holder.setAccountColorEnabled(showAccountColor);
holder.setAccountColorEnabled(showAccountColor);
if (highlightOption != VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE) {
holder.text.setText(Html.fromHtml(status.text_html));
linkify.applyAllLinks(holder.text, status.account_id, status.is_possibly_sensitive);
holder.text.setMovementMethod(null);
} else {
holder.text.setText(status.text_unescaped);
}
if (highlightOption != VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE) {
holder.text.setText(Html.fromHtml(status.text_html));
linkify.applyAllLinks(holder.text, status.account_id, status.is_possibly_sensitive);
holder.text.setMovementMethod(null);
} else {
holder.text.setText(status.text_unescaped);
}
if (showAccountColor) {
holder.setAccountColor(getAccountColor(context, status.account_id));
}
if (showAccountColor) {
holder.setAccountColor(getAccountColor(context, status.account_id));
}
final boolean isMyStatus = status.account_id == status.user_id;
final boolean hasMedia = status.first_media != null;
holder.setUserColor(getUserColor(context, status.user_id));
holder.setHighlightColor(getCardHighlightColor(false, !mFavoritesHighlightDisabled && status.is_favorite,
status.is_retweet));
holder.setTextSize(getTextSize());
final boolean isMyStatus = status.account_id == status.user_id;
final boolean hasMedia = status.first_media != null;
holder.setUserColor(getUserColor(context, status.user_id));
holder.setHighlightColor(getCardHighlightColor(context.getResources(), false,
!mFavoritesHighlightDisabled && status.is_favorite, status.is_retweet));
holder.setTextSize(getTextSize());
holder.setIsMyStatus(isMyStatus && !mIndicateMyStatusDisabled);
holder.setIsMyStatus(isMyStatus && !mIndicateMyStatusDisabled);
holder.setUserType(status.user_is_verified, status.user_is_protected);
holder.setDisplayNameFirst(isDisplayNameFirst());
holder.setNicknameOnly(isNicknameOnly());
final String nick = getUserNickname(context, status.user_id);
holder.name.setText(TextUtils.isEmpty(nick) ? status.user_name : isNicknameOnly() ? nick : context
.getString(R.string.name_with_nickname, status.user_name, nick));
holder.screen_name.setText("@" + status.user_screen_name);
if (highlightOption != VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE) {
linkify.applyUserProfileLinkNoHighlight(holder.name, status.account_id, status.user_id,
status.user_screen_name);
linkify.applyUserProfileLinkNoHighlight(holder.screen_name, status.account_id, status.user_id,
status.user_screen_name);
holder.name.setMovementMethod(null);
holder.screen_name.setMovementMethod(null);
}
holder.time.setTime(status.timestamp);
holder.setStatusType(!mFavoritesHighlightDisabled && status.is_favorite,
ParcelableLocation.isValidLocation(status.location), hasMedia, status.is_possibly_sensitive);
holder.setIsReplyRetweet(status.in_reply_to_status_id > 0, status.is_retweet);
if (status.is_retweet) {
holder.setRetweetedBy(status.retweet_count, status.retweeted_by_id, status.retweeted_by_name,
status.retweeted_by_screen_name);
} else if (status.in_reply_to_status_id > 0) {
holder.setReplyTo(status.in_reply_to_user_id, status.in_reply_to_name, status.in_reply_to_screen_name);
}
if (displayProfileImage) {
setProfileImage(holder.my_profile_image, status);
setProfileImage(holder.profile_image, status);
holder.profile_image.setTag(position);
holder.my_profile_image.setTag(position);
} else {
holder.profile_image.setVisibility(View.GONE);
holder.my_profile_image.setVisibility(View.GONE);
}
final boolean hasPreview = mDisplayImagePreview && hasMedia;
holder.image_preview_container.setVisibility(hasPreview ? View.VISIBLE : View.GONE);
if (hasPreview) {
if (status.is_possibly_sensitive && !mDisplaySensitiveContents) {
holder.image_preview.setImageDrawable(null);
holder.image_preview.setBackgroundResource(R.drawable.image_preview_nsfw);
holder.image_preview_progress.setVisibility(View.GONE);
} else if (!status.first_media.equals(mImageLoadingHandler.getLoadingUri(holder.image_preview))) {
holder.image_preview.setBackgroundResource(0);
final ImageLoaderWrapper imageLoader = getImageLoader();
imageLoader.displayPreviewImage(holder.image_preview, status.first_media, mImageLoadingHandler);
}
holder.image_preview.setTag(position);
}
// holder.item_menu.setTag(position);
}
}
holder.setUserType(status.user_is_verified, status.user_is_protected);
holder.setDisplayNameFirst(isDisplayNameFirst());
holder.setNicknameOnly(isNicknameOnly());
final String nick = getUserNickname(context, status.user_id);
holder.name.setText(TextUtils.isEmpty(nick) ? status.user_name : isNicknameOnly() ? nick : context
.getString(R.string.name_with_nickname, status.user_name, nick));
holder.screen_name.setText("@" + status.user_screen_name);
if (highlightOption != VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE) {
linkify.applyUserProfileLinkNoHighlight(holder.name, status.account_id, status.user_id,
status.user_screen_name);
linkify.applyUserProfileLinkNoHighlight(holder.screen_name, status.account_id, status.user_id,
status.user_screen_name);
holder.name.setMovementMethod(null);
holder.screen_name.setMovementMethod(null);
}
holder.time.setTime(status.timestamp);
holder.setStatusType(!mFavoritesHighlightDisabled && status.is_favorite,
ParcelableLocation.isValidLocation(status.location), hasMedia, status.is_possibly_sensitive);
holder.setIsReplyRetweet(status.in_reply_to_status_id > 0, status.is_retweet);
if (status.is_retweet) {
holder.setRetweetedBy(status.retweet_count, status.retweeted_by_id, status.retweeted_by_name,
status.retweeted_by_screen_name);
} else if (status.in_reply_to_status_id > 0) {
holder.setReplyTo(status.in_reply_to_user_id, status.in_reply_to_name, status.in_reply_to_screen_name);
}
if (displayProfileImage) {
setProfileImage(holder.my_profile_image, status);
setProfileImage(holder.profile_image, status);
holder.profile_image.setTag(position);
holder.my_profile_image.setTag(position);
} else {
holder.profile_image.setVisibility(View.GONE);
holder.my_profile_image.setVisibility(View.GONE);
}
final boolean hasPreview = mDisplayImagePreview && hasMedia;
holder.image_preview_container.setVisibility(hasPreview ? View.VISIBLE : View.GONE);
if (hasPreview) {
if (status.is_possibly_sensitive && !mDisplaySensitiveContents) {
holder.image_preview.setImageDrawable(null);
holder.image_preview.setBackgroundResource(R.drawable.image_preview_nsfw);
holder.image_preview_progress.setVisibility(View.GONE);
} else if (!status.first_media.equals(mImageLoadingHandler.getLoadingUri(holder.image_preview))) {
holder.image_preview.setBackgroundResource(0);
final ImageLoaderWrapper imageLoader = getImageLoader();
imageLoader.displayPreviewImage(holder.image_preview, status.first_media, mImageLoadingHandler);
}
holder.image_preview.setTag(position);
}
// holder.item_menu.setTag(position);
}
}
}

View File

@ -164,6 +164,7 @@ public class ParcelableStatusesListAdapter extends BaseArrayAdapter<ParcelableSt
final View view = super.getView(position, convertView, parent);
final Object tag = view.getTag();
final StatusListViewHolder holder;
final Resources res = mContext.getResources();
if (tag instanceof StatusListViewHolder) {
holder = (StatusListViewHolder) tag;
@ -222,7 +223,8 @@ public class ParcelableStatusesListAdapter extends BaseArrayAdapter<ParcelableSt
} else {
holder.setUserColor(getUserColor(mContext, status.user_id));
}
holder.setHighlightColor(getCardHighlightColor(!mMentionsHighlightDisabled && isMention,
holder.setHighlightColor(getCardHighlightColor(res,
!mMentionsHighlightDisabled && isMention,
!mFavoritesHighlightDisabled && status.is_favorite, status.is_retweet));
holder.setTextSize(getTextSize());
@ -278,7 +280,6 @@ public class ParcelableStatusesListAdapter extends BaseArrayAdapter<ParcelableSt
holder.image_preview.setBackgroundResource(0);
loader.displayPreviewImage(holder.image_preview, status.first_media, mImageLoadingHandler);
}
final Resources res = mContext.getResources();
final int count = status.media.length;
holder.image_preview_count.setText(res.getQuantityString(R.plurals.N_media, count, count));
holder.image_preview.setTag(position);
@ -322,7 +323,8 @@ public class ParcelableStatusesListAdapter extends BaseArrayAdapter<ParcelableSt
final ParcelableStatus status = getStatus(position);
if (status == null) return;
if (mContext instanceof Activity) {
openUserProfile((Activity) mContext, status.account_id, status.user_id, status.user_screen_name);
openUserProfile(mContext, status.account_id, status.user_id,
status.user_screen_name, null);
}
break;
}

View File

@ -138,7 +138,8 @@ public class ParcelableUserListsAdapter extends BaseArrayAdapter<ParcelableUserL
case R.id.profile_image: {
if (mContext instanceof Activity) {
final ParcelableUserList item = getItem(position);
openUserProfile((Activity) mContext, item.account_id, item.user_id, item.user_screen_name);
openUserProfile(mContext, item.account_id, item.user_id, item.user_screen_name,
null);
}
break;
}

View File

@ -50,6 +50,10 @@ public class SupportTabsAdapter extends SupportFixedFragmentStatePagerAdapter im
private final int mColumns;
public SupportTabsAdapter(final Context context, final FragmentManager fm) {
this(context, fm, null);
}
public SupportTabsAdapter(final Context context, final FragmentManager fm, final PagerIndicator indicator) {
this(context, fm, indicator, 1);
}

View File

@ -59,6 +59,7 @@ import org.mariotaku.twidere.util.ImageLoaderWrapper;
import org.mariotaku.twidere.util.MessagesManager;
import org.mariotaku.twidere.util.MultiSelectManager;
import org.mariotaku.twidere.util.StrictModeUtils;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.util.content.TwidereSQLiteOpenHelper;
import org.mariotaku.twidere.util.imageloader.TwidereImageDownloader;
@ -184,6 +185,7 @@ public class TwidereApplication extends Application implements Constants, OnShar
if (Utils.isDebugBuild()) {
StrictModeUtils.detectAllVmPolicy();
}
setTheme(ThemeUtils.getThemeResource(this));
super.onCreate();
mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, MODE_PRIVATE);
mHandler = new Handler();

View File

@ -181,7 +181,8 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement
final OptionItem option = (OptionItem) item;
switch (option.id) {
case MENU_VIEW_PROFILE: {
openUserProfile(getActivity(), account.account_id, account.account_id, account.screen_name);
openUserProfile(getActivity(), account.account_id, account.account_id,
account.screen_name, null);
closeAccountsDrawer();
break;
}

View File

@ -66,7 +66,7 @@ public class ActivitiesAboutMeFragment extends BaseActivitiesListFragment {
switch (item.action) {
case ParcelableActivity.ACTION_FAVORITE: {
if (sources.length == 1) {
openUserProfile(getActivity(), sources[0]);
openUserProfile(getActivity(), sources[0], null);
} else {
final List<ParcelableUser> users = Arrays.asList(sources);
openUsers(getActivity(), users);
@ -75,7 +75,7 @@ public class ActivitiesAboutMeFragment extends BaseActivitiesListFragment {
}
case ParcelableActivity.ACTION_FOLLOW: {
if (sources.length == 1) {
openUserProfile(getActivity(), sources[0]);
openUserProfile(getActivity(), sources[0], null);
} else {
final List<ParcelableUser> users = Arrays.asList(sources);
openUsers(getActivity(), users);
@ -96,7 +96,7 @@ public class ActivitiesAboutMeFragment extends BaseActivitiesListFragment {
}
case ParcelableActivity.ACTION_RETWEET: {
if (sources.length == 1) {
openUserProfile(getActivity(), sources[0]);
openUserProfile(getActivity(), sources[0], null);
} else {
final List<ParcelableUser> users = Arrays.asList(sources);
openUsers(getActivity(), users);

View File

@ -79,7 +79,7 @@ public class ActivitiesByFriendsFragment extends BaseActivitiesListFragment {
case ParcelableActivity.ACTION_FOLLOW: {
if (targetUsers == null || targetUsers.length == 0) return;
if (targetUsers.length == 1) {
openUserProfile(getActivity(), targetUsers[0]);
openUserProfile(getActivity(), targetUsers[0], null);
} else {
final List<ParcelableUser> users = Arrays.asList(targetUsers);
openUsers(getActivity(), users);

View File

@ -34,6 +34,7 @@ import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.activity.support.BaseSupportActivity;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.fragment.iface.IBaseFragment;
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.MultiSelectManager;
@ -127,6 +128,32 @@ public class BaseSupportFragment extends Fragment implements IBaseFragment, Cons
}
}
@Override
public void onDetach() {
super.onDetach();
final Fragment fragment = getParentFragment();
if (fragment instanceof SupportFragmentCallback) {
((SupportFragmentCallback) fragment).onDetachFragment(this);
}
final Activity activity = getActivity();
if (activity instanceof SupportFragmentCallback) {
((SupportFragmentCallback) activity).onDetachFragment(this);
}
}
@Override
public void setUserVisibleHint(final boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
final Activity activity = getActivity();
final Fragment fragment = getParentFragment();
if (fragment instanceof SupportFragmentCallback) {
((SupportFragmentCallback) fragment).onSetUserVisibleHint(this, isVisibleToUser);
}
if (activity instanceof SupportFragmentCallback) {
((SupportFragmentCallback) activity).onSetUserVisibleHint(this, isVisibleToUser);
}
}
protected void fitSystemWindows(Rect insets) {
}

View File

@ -280,14 +280,14 @@ public class BaseSupportListFragment extends ListFragment implements IBaseFragme
@Override
public void onDetach() {
super.onDetach();
final Activity activity = getActivity();
if (activity instanceof SupportFragmentCallback) {
((SupportFragmentCallback) activity).onDetachFragment(this);
}
final Fragment fragment = getParentFragment();
if (fragment instanceof SupportFragmentCallback) {
((SupportFragmentCallback) fragment).onDetachFragment(this);
}
final Activity activity = getActivity();
if (activity instanceof SupportFragmentCallback) {
((SupportFragmentCallback) activity).onDetachFragment(this);
}
}
public void onPostStart() {
@ -386,14 +386,14 @@ public class BaseSupportListFragment extends ListFragment implements IBaseFragme
@Override
public void setUserVisibleHint(final boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
final Activity activity = getActivity();
if (activity instanceof SupportFragmentCallback) {
((SupportFragmentCallback) activity).onSetUserVisibleHint(this, isVisibleToUser);
}
final Fragment fragment = getParentFragment();
if (fragment instanceof SupportFragmentCallback) {
((SupportFragmentCallback) fragment).onSetUserVisibleHint(this, isVisibleToUser);
}
final Activity activity = getActivity();
if (activity instanceof SupportFragmentCallback) {
((SupportFragmentCallback) activity).onSetUserVisibleHint(this, isVisibleToUser);
}
}
@Override

View File

@ -163,14 +163,14 @@ public class BaseSupportStaggeredGridFragment extends StaggeredGridFragment impl
@Override
public void onDetach() {
super.onDetach();
final Activity activity = getActivity();
if (activity instanceof SupportFragmentCallback) {
((SupportFragmentCallback) activity).onDetachFragment(this);
}
final Fragment fragment = getParentFragment();
if (fragment instanceof SupportFragmentCallback) {
((SupportFragmentCallback) fragment).onDetachFragment(this);
}
final Activity activity = getActivity();
if (activity instanceof SupportFragmentCallback) {
((SupportFragmentCallback) activity).onDetachFragment(this);
}
}
public void onPostStart() {
@ -243,13 +243,13 @@ public class BaseSupportStaggeredGridFragment extends StaggeredGridFragment impl
public void setUserVisibleHint(final boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
final Activity activity = getActivity();
if (activity instanceof SupportFragmentCallback) {
((SupportFragmentCallback) activity).onSetUserVisibleHint(this, isVisibleToUser);
}
final Fragment fragment = getParentFragment();
if (fragment instanceof SupportFragmentCallback) {
((SupportFragmentCallback) fragment).onSetUserVisibleHint(this, isVisibleToUser);
}
if (activity instanceof SupportFragmentCallback) {
((SupportFragmentCallback) activity).onSetUserVisibleHint(this, isVisibleToUser);
}
}
@Override

View File

@ -165,7 +165,7 @@ abstract class BaseUsersListFragment extends BasePullToRefreshListFragment imple
setItemSelected(user, position, !mMultiSelectManager.isSelected(user));
return;
}
openUserProfile(getActivity(), user);
openUserProfile(getActivity(), user, null);
}
@Override

View File

@ -282,7 +282,7 @@ public class DirectMessagesConversationFragment extends BasePullToRefreshListFra
final ParcelableUser recipient = mRecipient;
if (recipient == null) return;
Utils.openUserProfile(getActivity(), recipient.account_id, recipient.id,
recipient.screen_name);
recipient.screen_name, null);
break;
}
}

View File

@ -36,12 +36,14 @@ import android.location.Geocoder;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityOptionsCompat;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.AsyncTaskLoader;
import android.support.v4.content.Loader;
import android.support.v4.util.Pair;
import android.text.Html;
import android.text.SpannableString;
import android.text.TextUtils;
@ -513,7 +515,12 @@ public class StatusFragment extends ParcelableStatusesListFragment implements On
final ParcelableStatus status = mStatus;
switch (view.getId()) {
case R.id.profile: {
openUserProfile(getActivity(), status.account_id, status.user_id, null);
final FragmentActivity activity = getActivity();
final ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(activity,
new Pair<View, String>(mProfileImageView, UserProfileFragment.TRANSITION_NAME_PROFILE_IMAGE),
new Pair<View, String>(mProfileTypeView, UserProfileFragment.TRANSITION_NAME_PROFILE_TYPE));
openUserProfile(activity, status.account_id, status.user_id, status.user_screen_name,
options.toBundle());
break;
}
case R.id.follow: {

View File

@ -19,13 +19,6 @@
package org.mariotaku.twidere.fragment.support;
import static org.mariotaku.twidere.model.ParcelableLocation.isValidLocation;
import static org.mariotaku.twidere.util.UserColorNicknameUtils.getUserColor;
import static org.mariotaku.twidere.util.Utils.getCardHighlightColor;
import static org.mariotaku.twidere.util.Utils.getDefaultTextSize;
import static org.mariotaku.twidere.util.Utils.getStatusTypeIconRes;
import static org.mariotaku.twidere.util.Utils.getUserTypeIconRes;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
@ -53,185 +46,193 @@ import twitter4j.TranslationResult;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import static org.mariotaku.twidere.model.ParcelableLocation.isValidLocation;
import static org.mariotaku.twidere.util.UserColorNicknameUtils.getUserColor;
import static org.mariotaku.twidere.util.Utils.getCardHighlightColor;
import static org.mariotaku.twidere.util.Utils.getDefaultTextSize;
import static org.mariotaku.twidere.util.Utils.getStatusTypeIconRes;
import static org.mariotaku.twidere.util.Utils.getUserTypeIconRes;
public class StatusTranslateDialogFragment extends BaseSupportDialogFragment implements
LoaderCallbacks<SingleResponse<TranslationResult>> {
LoaderCallbacks<SingleResponse<TranslationResult>> {
private StatusListViewHolder mHolder;
private ProgressBar mProgressBar;
private TextView mMessageView;
private View mProgressContainer;
private View mStatusContainer;
private StatusListViewHolder mHolder;
private ProgressBar mProgressBar;
private TextView mMessageView;
private View mProgressContainer;
private View mStatusContainer;
public StatusTranslateDialogFragment() {
setStyle(STYLE_NO_TITLE, 0);
}
public StatusTranslateDialogFragment() {
setStyle(STYLE_NO_TITLE, 0);
}
@Override
public void onActivityCreated(final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
final Bundle args = getArguments();
if (args == null || args.getParcelable(EXTRA_STATUS) == null) {
dismiss();
return;
}
getLoaderManager().initLoader(0, args, this);
}
@Override
public void onActivityCreated(final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
final Bundle args = getArguments();
if (args == null || args.getParcelable(EXTRA_STATUS) == null) {
dismiss();
return;
}
getLoaderManager().initLoader(0, args, this);
}
@Override
public Loader<SingleResponse<TranslationResult>> onCreateLoader(final int id, final Bundle args) {
final ParcelableStatus status = args.getParcelable(EXTRA_STATUS);
mStatusContainer.setVisibility(View.GONE);
mProgressContainer.setVisibility(View.VISIBLE);
mProgressBar.setVisibility(View.VISIBLE);
mMessageView.setVisibility(View.VISIBLE);
mMessageView.setText(R.string.please_wait);
return new TranslationResultLoader(getActivity(), status.account_id, status.id);
}
@Override
public Loader<SingleResponse<TranslationResult>> onCreateLoader(final int id, final Bundle args) {
final ParcelableStatus status = args.getParcelable(EXTRA_STATUS);
mStatusContainer.setVisibility(View.GONE);
mProgressContainer.setVisibility(View.VISIBLE);
mProgressBar.setVisibility(View.VISIBLE);
mMessageView.setVisibility(View.VISIBLE);
mMessageView.setText(R.string.please_wait);
return new TranslationResultLoader(getActivity(), status.account_id, status.id);
}
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup parent, final Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.dialog_translate_status, parent, false);
mProgressContainer = view.findViewById(R.id.progress_container);
mProgressBar = (ProgressBar) mProgressContainer.findViewById(android.R.id.progress);
mMessageView = (TextView) mProgressContainer.findViewById(android.R.id.message);
mStatusContainer = view.findViewById(R.id.status_container);
mHolder = new StatusListViewHolder(mStatusContainer);
mHolder.setShowAsGap(false);
mHolder.setAccountColorEnabled(true);
((View) mHolder.content).setPadding(0, 0, 0, 0);
mHolder.content.setItemBackground(null);
mHolder.content.setItemSelector(null);
return view;
}
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup parent, final Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.dialog_translate_status, parent, false);
mProgressContainer = view.findViewById(R.id.progress_container);
mProgressBar = (ProgressBar) mProgressContainer.findViewById(android.R.id.progress);
mMessageView = (TextView) mProgressContainer.findViewById(android.R.id.message);
mStatusContainer = view.findViewById(R.id.status_container);
mHolder = new StatusListViewHolder(mStatusContainer);
mHolder.setShowAsGap(false);
mHolder.setAccountColorEnabled(true);
((View) mHolder.content).setPadding(0, 0, 0, 0);
mHolder.content.setItemBackground(null);
mHolder.content.setItemSelector(null);
return view;
}
@Override
public void onLoaderReset(final Loader<SingleResponse<TranslationResult>> loader) {
@Override
public void onLoaderReset(final Loader<SingleResponse<TranslationResult>> loader) {
}
}
@Override
public void onLoadFinished(final Loader<SingleResponse<TranslationResult>> loader,
final SingleResponse<TranslationResult> data) {
final Bundle args = getArguments();
final ParcelableStatus status = args.getParcelable(EXTRA_STATUS);
if (status != null && data.getData() != null) {
displayTranslatedStatus(status, data.getData());
mStatusContainer.setVisibility(View.VISIBLE);
mProgressContainer.setVisibility(View.GONE);
} else {
mStatusContainer.setVisibility(View.GONE);
mProgressContainer.setVisibility(View.VISIBLE);
mProgressBar.setVisibility(View.GONE);
mMessageView.setVisibility(View.VISIBLE);
mMessageView.setText(Utils.getErrorMessage(getActivity(), data.getException()));
}
}
@Override
public void onLoadFinished(final Loader<SingleResponse<TranslationResult>> loader,
final SingleResponse<TranslationResult> data) {
final Bundle args = getArguments();
final ParcelableStatus status = args.getParcelable(EXTRA_STATUS);
if (status != null && data.getData() != null) {
displayTranslatedStatus(status, data.getData());
mStatusContainer.setVisibility(View.VISIBLE);
mProgressContainer.setVisibility(View.GONE);
} else {
mStatusContainer.setVisibility(View.GONE);
mProgressContainer.setVisibility(View.VISIBLE);
mProgressBar.setVisibility(View.GONE);
mMessageView.setVisibility(View.VISIBLE);
mMessageView.setText(Utils.getErrorMessage(getActivity(), data.getException()));
}
}
private void displayTranslatedStatus(final ParcelableStatus status, final TranslationResult translated) {
if (status == null || translated == null) return;
final TwidereApplication application = getApplication();
final ImageLoaderWrapper loader = application.getImageLoaderWrapper();
final SharedPreferences prefs = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
mHolder.setTextSize(prefs.getInt(KEY_TEXT_SIZE, getDefaultTextSize(getActivity())));
mHolder.text.setText(translated.getText());
mHolder.name.setText(status.user_name);
mHolder.screen_name.setText("@" + status.user_screen_name);
mHolder.screen_name.setVisibility(View.VISIBLE);
private void displayTranslatedStatus(final ParcelableStatus status, final TranslationResult translated) {
if (status == null || translated == null) return;
final TwidereApplication application = getApplication();
final ImageLoaderWrapper loader = application.getImageLoaderWrapper();
final SharedPreferences prefs = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
mHolder.setTextSize(prefs.getInt(KEY_TEXT_SIZE, getDefaultTextSize(getActivity())));
mHolder.text.setText(translated.getText());
mHolder.name.setText(status.user_name);
mHolder.screen_name.setText("@" + status.user_screen_name);
mHolder.screen_name.setVisibility(View.VISIBLE);
final String retweeted_by_name = status.retweeted_by_name;
final String retweeted_by_screen_name = status.retweeted_by_screen_name;
final String retweeted_by_name = status.retweeted_by_name;
final String retweeted_by_screen_name = status.retweeted_by_screen_name;
final boolean isMyStatus = status.account_id == status.user_id;
final boolean hasMedia = status.media != null && status.media.length > 0;
mHolder.setUserColor(getUserColor(getActivity(), status.user_id, true));
mHolder.setHighlightColor(getCardHighlightColor(false, status.is_favorite, status.is_retweet));
final boolean isMyStatus = status.account_id == status.user_id;
final boolean hasMedia = status.media != null && status.media.length > 0;
mHolder.setUserColor(getUserColor(getActivity(), status.user_id, true));
mHolder.setHighlightColor(getCardHighlightColor(getResources(), false, status.is_favorite,
status.is_retweet));
mHolder.setIsMyStatus(isMyStatus && !prefs.getBoolean(KEY_INDICATE_MY_STATUS, true));
mHolder.setIsMyStatus(isMyStatus && !prefs.getBoolean(KEY_INDICATE_MY_STATUS, true));
mHolder.name.setCompoundDrawablesWithIntrinsicBounds(0, 0,
getUserTypeIconRes(status.user_is_verified, status.user_is_protected), 0);
mHolder.time.setTime(status.timestamp);
final int type_icon = getStatusTypeIconRes(status.is_favorite, isValidLocation(status.location), hasMedia,
status.is_possibly_sensitive);
mHolder.time.setCompoundDrawablesWithIntrinsicBounds(0, 0, type_icon, 0);
mHolder.reply_retweet_status
.setVisibility(status.in_reply_to_status_id != -1 || status.is_retweet ? View.VISIBLE : View.GONE);
if (status.is_retweet && !TextUtils.isEmpty(retweeted_by_name) && !TextUtils.isEmpty(retweeted_by_screen_name)) {
if (!prefs.getBoolean(KEY_NAME_FIRST, true)) {
mHolder.reply_retweet_status.setText(status.retweet_count > 1 ? getString(
R.string.retweeted_by_name_with_count, retweeted_by_screen_name, status.retweet_count - 1)
: getString(R.string.retweeted_by_name, retweeted_by_screen_name));
} else {
mHolder.reply_retweet_status.setText(status.retweet_count > 1 ? getString(
R.string.retweeted_by_name_with_count, retweeted_by_name, status.retweet_count - 1) : getString(
R.string.retweeted_by_name, retweeted_by_name));
}
mHolder.reply_retweet_status.setText(status.retweet_count > 1 ? getString(R.string.retweeted_by_name_with_count,
retweeted_by_name, status.retweet_count - 1) : getString(R.string.retweeted_by_name, retweeted_by_name));
mHolder.reply_retweet_status.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_indicator_retweet, 0, 0,
0);
} else if (status.in_reply_to_status_id > 0 && !TextUtils.isEmpty(status.in_reply_to_screen_name)) {
mHolder.reply_retweet_status.setText(getString(R.string.in_reply_to_name, status.in_reply_to_screen_name));
mHolder.reply_retweet_status.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_indicator_conversation,
0, 0, 0);
}
if (prefs.getBoolean(KEY_DISPLAY_PROFILE_IMAGE, true)) {
loader.displayProfileImage(mHolder.my_profile_image, status.user_profile_image_url);
loader.displayProfileImage(mHolder.profile_image, status.user_profile_image_url);
} else {
mHolder.profile_image.setVisibility(View.GONE);
mHolder.my_profile_image.setVisibility(View.GONE);
}
mHolder.image_preview_container.setVisibility(View.GONE);
}
mHolder.name.setCompoundDrawablesWithIntrinsicBounds(0, 0,
getUserTypeIconRes(status.user_is_verified, status.user_is_protected), 0);
mHolder.time.setTime(status.timestamp);
final int type_icon = getStatusTypeIconRes(status.is_favorite, isValidLocation(status.location), hasMedia,
status.is_possibly_sensitive);
mHolder.time.setCompoundDrawablesWithIntrinsicBounds(0, 0, type_icon, 0);
mHolder.reply_retweet_status
.setVisibility(status.in_reply_to_status_id != -1 || status.is_retweet ? View.VISIBLE : View.GONE);
if (status.is_retweet && !TextUtils.isEmpty(retweeted_by_name) && !TextUtils.isEmpty(retweeted_by_screen_name)) {
if (!prefs.getBoolean(KEY_NAME_FIRST, true)) {
mHolder.reply_retweet_status.setText(status.retweet_count > 1 ? getString(
R.string.retweeted_by_name_with_count, retweeted_by_screen_name, status.retweet_count - 1)
: getString(R.string.retweeted_by_name, retweeted_by_screen_name));
} else {
mHolder.reply_retweet_status.setText(status.retweet_count > 1 ? getString(
R.string.retweeted_by_name_with_count, retweeted_by_name, status.retweet_count - 1) : getString(
R.string.retweeted_by_name, retweeted_by_name));
}
mHolder.reply_retweet_status.setText(status.retweet_count > 1 ? getString(R.string.retweeted_by_name_with_count,
retweeted_by_name, status.retweet_count - 1) : getString(R.string.retweeted_by_name, retweeted_by_name));
mHolder.reply_retweet_status.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_indicator_retweet, 0, 0,
0);
} else if (status.in_reply_to_status_id > 0 && !TextUtils.isEmpty(status.in_reply_to_screen_name)) {
mHolder.reply_retweet_status.setText(getString(R.string.in_reply_to_name, status.in_reply_to_screen_name));
mHolder.reply_retweet_status.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_indicator_conversation,
0, 0, 0);
}
if (prefs.getBoolean(KEY_DISPLAY_PROFILE_IMAGE, true)) {
loader.displayProfileImage(mHolder.my_profile_image, status.user_profile_image_url);
loader.displayProfileImage(mHolder.profile_image, status.user_profile_image_url);
} else {
mHolder.profile_image.setVisibility(View.GONE);
mHolder.my_profile_image.setVisibility(View.GONE);
}
mHolder.image_preview_container.setVisibility(View.GONE);
}
public static void show(final FragmentManager fm, final ParcelableStatus status) {
final StatusTranslateDialogFragment df = new StatusTranslateDialogFragment();
final Bundle args = new Bundle();
args.putParcelable(EXTRA_STATUS, status);
df.setArguments(args);
df.show(fm, "translate_status");
}
public static void show(final FragmentManager fm, final ParcelableStatus status) {
final StatusTranslateDialogFragment df = new StatusTranslateDialogFragment();
final Bundle args = new Bundle();
args.putParcelable(EXTRA_STATUS, status);
df.setArguments(args);
df.show(fm, "translate_status");
}
public static final class TranslationResultLoader extends AsyncTaskLoader<SingleResponse<TranslationResult>> {
public static final class TranslationResultLoader extends AsyncTaskLoader<SingleResponse<TranslationResult>> {
private final long mAccountId;
private final long mStatusId;
private final long mAccountId;
private final long mStatusId;
public TranslationResultLoader(final Context context, final long accountId, final long statusId) {
super(context);
mAccountId = accountId;
mStatusId = statusId;
}
public TranslationResultLoader(final Context context, final long accountId, final long statusId) {
super(context);
mAccountId = accountId;
mStatusId = statusId;
}
@Override
public SingleResponse<TranslationResult> loadInBackground() {
final Context context = getContext();
final Twitter twitter = Utils.getTwitterInstance(context, mAccountId, false);
final SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
if (twitter == null) return SingleResponse.getInstance();
try {
final String prefDest = prefs.getString(KEY_TRANSLATION_DESTINATION, null);
final String dest;
if (TextUtils.isEmpty(prefDest)) {
dest = twitter.getAccountSettings().getLanguage();
final Editor editor = prefs.edit();
editor.putString(KEY_TRANSLATION_DESTINATION, dest);
editor.apply();
} else {
dest = prefDest;
}
return SingleResponse.getInstance(twitter.showTranslation(mStatusId, dest));
} catch (final TwitterException e) {
return SingleResponse.getInstance(e);
}
}
@Override
public SingleResponse<TranslationResult> loadInBackground() {
final Context context = getContext();
final Twitter twitter = Utils.getTwitterInstance(context, mAccountId, false);
final SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
if (twitter == null) return SingleResponse.getInstance();
try {
final String prefDest = prefs.getString(KEY_TRANSLATION_DESTINATION, null);
final String dest;
if (TextUtils.isEmpty(prefDest)) {
dest = twitter.getAccountSettings().getLanguage();
final Editor editor = prefs.edit();
editor.putString(KEY_TRANSLATION_DESTINATION, dest);
editor.apply();
} else {
dest = prefDest;
}
return SingleResponse.getInstance(twitter.showTranslation(mStatusId, dest));
} catch (final TwitterException e) {
return SingleResponse.getInstance(e);
}
}
@Override
protected void onStartLoading() {
forceLoad();
}
@Override
protected void onStartLoading() {
forceLoad();
}
}
}
}

View File

@ -222,7 +222,8 @@ public class UserListDetailsFragment extends BaseSupportListFragment implements
}
case R.id.profile_image: {
if (mUserList == null) return;
openUserProfile(getActivity(), mUserList.account_id, mUserList.user_id, mUserList.user_screen_name);
openUserProfile(getActivity(), mUserList.account_id,
mUserList.user_id, mUserList.user_screen_name, null);
break;
}
}

View File

@ -76,15 +76,17 @@ public class UserMediaTimelineFragment extends BaseSupportFragment
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mRecyclerView = (RecyclerView) view.findViewById(android.R.id.list);
mProgress = (ProgressBar) view.findViewById(android.R.id.progress);
mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
mProgress = (ProgressBar) view.findViewById(R.id.progress);
}
@Override
protected void fitSystemWindows(Rect insets) {
super.fitSystemWindows(insets);
mRecyclerView.setClipToPadding(false);
mRecyclerView.setPadding(insets.left, insets.top, insets.right, insets.bottom);
if (mRecyclerView != null) {
mRecyclerView.setClipToPadding(false);
mRecyclerView.setPadding(insets.left, insets.top, insets.right, insets.bottom);
}
}
@Override

View File

@ -3,6 +3,7 @@ package org.mariotaku.twidere.fragment.support;
import android.content.Context;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.annotation.Nullable;
import android.support.v4.app.LoaderManager;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
@ -13,6 +14,7 @@ import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.OnScrollListener;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
@ -24,6 +26,7 @@ import org.mariotaku.twidere.loader.support.UserTimelineLoader;
import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.UserProfileDrawer.DrawerCallback;
import java.util.List;
@ -31,7 +34,7 @@ import java.util.List;
* Created by mariotaku on 14/11/5.
*/
public class UserTimelineFragment extends BaseSupportFragment
implements LoaderCallbacks<List<ParcelableStatus>>, OnRefreshListener {
implements LoaderCallbacks<List<ParcelableStatus>>, OnRefreshListener, DrawerCallback {
private SwipeRefreshLayout mSwipeRefreshLayout;
private RecyclerView mRecyclerView;
@ -113,7 +116,7 @@ public class UserTimelineFragment extends BaseSupportFragment
@Override
public Loader<List<ParcelableStatus>> onCreateLoader(int id, Bundle args) {
mSwipeRefreshLayout.setRefreshing(true);
// mSwipeRefreshLayout.setRefreshing(true);
final List<ParcelableStatus> data = mAdapter.getData();
final Context context = getActivity();
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
@ -146,4 +149,37 @@ public class UserTimelineFragment extends BaseSupportFragment
getStatuses(0, 0);
}
}
@Override
public void fling(float velocity) {
mRecyclerView.fling(0, (int) velocity);
}
@Override
public void scrollBy(float dy) {
mRecyclerView.scrollBy(0, (int) dy);
}
@Override
public boolean canScroll(float dy) {
return mRecyclerView.canScrollVertically((int) dy);
}
@Override
public boolean isScrollContent(float x, float y) {
final int[] location = new int[2];
mRecyclerView.getLocationOnScreen(location);
return x >= location[0] && x <= location[0] && y >= location[1] && y <= location[1];
}
@Override
public void cancelTouch() {
mRecyclerView.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(),
SystemClock.uptimeMillis(), MotionEvent.ACTION_CANCEL, 0, 0, 0));
}
@Override
public void topChanged(int offset) {
}
}

View File

@ -53,10 +53,9 @@ public class OnLinkClickHandler implements OnLinkClickListener, Constants {
// UCD
ProfilingUtil.profile(activity, account_id, "Click, " + link + ", " + type);
if (activity == null) return;
switch (type) {
case TwidereLinkify.LINK_TYPE_MENTION: {
openUserProfile(activity, account_id, -1, link);
openUserProfile(activity, account_id, -1, link, null);
break;
}
case TwidereLinkify.LINK_TYPE_HASHTAG: {
@ -72,11 +71,11 @@ public class OnLinkClickHandler implements OnLinkClickListener, Constants {
break;
}
case TwidereLinkify.LINK_TYPE_LIST: {
final String[] mention_list = link.split("\\/");
if (mention_list == null || mention_list.length != 2) {
final String[] mentionList = link.split("/");
if (mentionList.length != 2) {
break;
}
openUserListDetails(activity, account_id, -1, -1, mention_list[0], mention_list[1]);
openUserListDetails(activity, account_id, -1, -1, mentionList[0], mentionList[1]);
break;
}
case TwidereLinkify.LINK_TYPE_CASHTAG: {
@ -84,7 +83,7 @@ public class OnLinkClickHandler implements OnLinkClickListener, Constants {
break;
}
case TwidereLinkify.LINK_TYPE_USER_ID: {
openUserProfile(activity, account_id, ParseUtils.parseLong(link), null);
openUserProfile(activity, account_id, ParseUtils.parseLong(link), null, null);
break;
}
case TwidereLinkify.LINK_TYPE_STATUS: {

View File

@ -501,7 +501,7 @@ public class ThemeUtils implements Constants {
final Context wrapped = getThemedContext(context, res);
final TypedArray a = wrapped.obtainStyledAttributes(new int[]{android.R.attr.colorActivatedHighlight});
try {
return a.getColor(0, res.getColor(android.R.color.holo_blue_light));
return a.getColor(0, res.getColor(R.color.material_light_blue));
} finally {
a.recycle();
}
@ -623,7 +623,7 @@ public class ThemeUtils implements Constants {
if (context == null) return Color.TRANSPARENT;
final Resources res = getResources(context);
final SharedPreferencesWrapper pref = getSharedPreferencesWrapper(context);
final int def = res.getColor(android.R.color.holo_blue_light);
final int def = res.getColor(R.color.material_light_blue);
return pref.getInt(KEY_THEME_COLOR, def);
}
@ -834,7 +834,7 @@ public class ThemeUtils implements Constants {
final TypedArray a = appContext.obtainStyledAttributes(null,
new int[]{android.R.attr.colorActivatedHighlight}, 0, themeResourceId);
try {
return a.getColor(0, res.getColor(android.R.color.holo_blue_light));
return a.getColor(0, res.getColor(R.color.material_light_blue));
} finally {
a.recycle();
}

View File

@ -19,6 +19,7 @@
package org.mariotaku.twidere.util;
import android.app.ActionBar;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
@ -33,7 +34,6 @@ 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.TypedArray;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
@ -62,6 +62,7 @@ import android.os.SystemClock;
import android.provider.BaseColumns;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
@ -77,6 +78,7 @@ import android.text.format.Time;
import android.text.style.CharacterStyle;
import android.text.style.StyleSpan;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
@ -143,7 +145,7 @@ import org.mariotaku.twidere.fragment.support.UserListTimelineFragment;
import org.mariotaku.twidere.fragment.support.UserListsFragment;
import org.mariotaku.twidere.fragment.support.UserMediaTimelineFragment;
import org.mariotaku.twidere.fragment.support.UserMentionsFragment;
import org.mariotaku.twidere.fragment.support.UserProfileFragmentOld;
import org.mariotaku.twidere.fragment.support.UserProfileFragment;
import org.mariotaku.twidere.fragment.support.UserTimelineFragment;
import org.mariotaku.twidere.fragment.support.UsersListFragment;
import org.mariotaku.twidere.graphic.PaddingDrawable;
@ -700,7 +702,13 @@ public final class Utils implements Constants, TwitterConstants {
return output;
}
public static Fragment createFragmentForIntent(final Context context, final Intent intent) {
final Uri uri = intent.getData();
return createFragmentForIntent(context, matchLinkId(uri), intent);
}
public static Fragment createFragmentForIntent(final Context context, final int linkId, final Intent intent) {
final long start = System.currentTimeMillis();
intent.setExtrasClassLoader(context.getClassLoader());
final Bundle extras = intent.getExtras();
@ -711,7 +719,7 @@ public final class Utils implements Constants, TwitterConstants {
if (extras != null) {
args.putAll(extras);
}
switch (matchLinkId(uri)) {
switch (linkId) {
case LINK_ID_STATUS: {
fragment = new StatusFragment();
if (!args.containsKey(EXTRA_STATUS_ID)) {
@ -721,7 +729,7 @@ public final class Utils implements Constants, TwitterConstants {
break;
}
case LINK_ID_USER: {
fragment = new UserProfileFragmentOld();
fragment = new UserProfileFragment();
final String paramScreenName = uri.getQueryParameter(QUERY_PARAM_SCREEN_NAME);
final String param_user_id = uri.getQueryParameter(QUERY_PARAM_USER_ID);
if (!args.containsKey(EXTRA_SCREEN_NAME)) {
@ -1599,13 +1607,13 @@ public final class Utils implements Constants, TwitterConstants {
return def;
}
public static int getCardHighlightColor(final boolean is_mention, final boolean is_favorite,
final boolean is_retweet) {
// if (is_mention)
// return HOLO_BLUE_LIGHT;
// else if (is_favorite)
// return HOLO_ORANGE_LIGHT;
// else if (is_retweet) return HOLO_GREEN_LIGHT;
public static int getCardHighlightColor(final Resources res, final boolean isMention, final boolean isFavorite,
final boolean isRetweet) {
if (isMention)
return res.getColor(R.color.highlight_reply);
else if (isFavorite)
return res.getColor(R.color.highlight_favorite);
else if (isRetweet) res.getColor(R.color.highlight_retweet);
return Color.TRANSPARENT;
}
@ -3327,7 +3335,7 @@ public final class Utils implements Constants, TwitterConstants {
}
public static void openUserProfile(final Context context, final long accountId, final long userId,
final String screenName) {
final String screenName, final Bundle activityOptions) {
if (context == null || accountId <= 0 || userId <= 0 && isEmpty(screenName)) return;
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
@ -3340,11 +3348,24 @@ public final class Utils implements Constants, TwitterConstants {
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, screenName);
}
final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
context.startActivity(intent);
if (context instanceof Activity) {
ActivityCompat.startActivity((Activity) context, intent, activityOptions);
} else {
context.startActivity(intent);
}
}
public static void openUserProfile(final Activity activity, final ParcelableUser user) {
if (activity == null || user == null) return;
public static int getInsetsTopWithoutActionBarHeight(Context context, int top) {
if (context instanceof Activity) {
final ActionBar actionBar = ((Activity) context).getActionBar();
if (actionBar != null) return top - getActionBarHeight(actionBar);
}
return top;
}
public static void openUserProfile(final Context context, final ParcelableUser user,
final Bundle activityOptions) {
if (context == null || user == null) return;
final Bundle extras = new Bundle();
extras.putParcelable(EXTRA_USER, user);
final Uri.Builder builder = new Uri.Builder();
@ -3358,9 +3379,13 @@ public final class Utils implements Constants, TwitterConstants {
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, user.screen_name);
}
final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
intent.setExtrasClassLoader(activity.getClassLoader());
intent.setExtrasClassLoader(context.getClassLoader());
intent.putExtras(extras);
activity.startActivity(intent);
if (context instanceof Activity) {
ActivityCompat.startActivity((Activity) context, intent, activityOptions);
} else {
context.startActivity(intent);
}
}
public static void openUsers(final Activity activity, final List<ParcelableUser> users) {
@ -3487,8 +3512,8 @@ public final class Utils implements Constants, TwitterConstants {
public static void setMenuForStatus(final Context context, final Menu menu, final ParcelableStatus status) {
if (context == null || menu == null || status == null) return;
final Resources resources = context.getResources();
final int retweetHighlight = resources.getColor(android.R.color.holo_green_light);
final int favoriteHighlight = resources.getColor(android.R.color.holo_orange_light);
final int retweetHighlight = resources.getColor(R.color.highlight_retweet);
final int favoriteHighlight = resources.getColor(R.color.highlight_favorite);
final boolean isMyRetweet = isMyRetweet(status);
final MenuItem delete = menu.findItem(MENU_DELETE);
if (delete != null) {
@ -3871,13 +3896,24 @@ public final class Utils implements Constants, TwitterConstants {
}
}
public static int getActionBarHeight(Context context) {
final TypedArray a = context.obtainStyledAttributes(new int[]{android.R.attr.actionBarSize});
try {
return a.getDimensionPixelSize(0, 0);
} finally {
a.recycle();
public static int getActionBarHeight(ActionBar actionBar) {
if (actionBar == null) return 0;
final Context context = actionBar.getThemedContext();
final TypedValue tv = new TypedValue();
final int height = actionBar.getHeight();
if (height > 0) return height;
if (context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
return TypedValue.complexToDimensionPixelSize(tv.data, context.getResources().getDisplayMetrics());
}
return 0;
}
public static int getActionBarHeight(Context context) {
final TypedValue tv = new TypedValue();
if (context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
return TypedValue.complexToDimensionPixelSize(tv.data, context.getResources().getDisplayMetrics());
}
return 0;
}
public static void makeListFragmentFitsSystemWindows(ListFragment fragment) {

View File

@ -57,6 +57,7 @@ public class CircularImageView extends ImageView {
private static final int SHADOW_START_COLOR = 0x37000000;
private static final boolean USE_OUTLINE = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
private static final boolean OUTLINE_DRAW = false;
private final Matrix mMatrix;
private final RectF mSource;
@ -194,7 +195,7 @@ public class CircularImageView extends ImageView {
@Override
public void setBackgroundDrawable(Drawable background) {
if (USE_OUTLINE) {
if (OUTLINE_DRAW) {
super.setBackgroundDrawable(background);
return;
}
@ -204,7 +205,6 @@ public class CircularImageView extends ImageView {
}
private void updateBackgroundPadding() {
if (USE_OUTLINE) return;
final Drawable drawable = mBackground;
if (drawable == null) return;
final int width = getWidth(), height = getHeight();
@ -225,7 +225,7 @@ public class CircularImageView extends ImageView {
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
public void setBackground(Drawable background) {
if (USE_OUTLINE) {
if (OUTLINE_DRAW) {
super.setBackground(background);
return;
}
@ -240,11 +240,9 @@ public class CircularImageView extends ImageView {
mDestination.set(getPaddingLeft(), getPaddingTop(), getWidth() - getPaddingRight(),
getHeight() - getPaddingBottom());
if (USE_OUTLINE) {
if (OUTLINE_DRAW) {
super.onDraw(canvas);
} else {
final int contentLeft = getPaddingLeft(), contentTop = getPaddingTop(),
contentRight = getWidth() - getPaddingRight(),
contentBottom = getHeight() - getPaddingBottom();
@ -292,7 +290,7 @@ public class CircularImageView extends ImageView {
@Override
public void setColorFilter(ColorFilter cf) {
if (USE_OUTLINE) {
if (OUTLINE_DRAW) {
super.setColorFilter(cf);
return;
}

View File

@ -1,48 +0,0 @@
package org.mariotaku.twidere.view;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View;
public class HalfWidthSpace extends View {
/**
* {@inheritDoc}
*/
public HalfWidthSpace(final Context context) {
// noinspection NullableProblems
this(context, null);
}
/**
* {@inheritDoc}
*/
public HalfWidthSpace(final Context context, final AttributeSet attrs) {
this(context, attrs, 0);
}
/**
* {@inheritDoc}
*/
public HalfWidthSpace(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
}
/**
* Draw nothing.
*
* @param canvas an unused parameter.
*/
@Override
public void draw(final Canvas canvas) {
}
@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
final int width = MeasureSpec.getSize(widthMeasureSpec), height = width / 3;
setMeasuredDimension(width, height);
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
}
}

View File

@ -0,0 +1,58 @@
package org.mariotaku.twidere.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
public class ProfileBannerSpace extends View {
private final Rect mSystemWindowsInsets;
/**
* {@inheritDoc}
*/
public ProfileBannerSpace(final Context context) {
// noinspection NullableProblems
this(context, null);
}
/**
* {@inheritDoc}
*/
public ProfileBannerSpace(final Context context, final AttributeSet attrs) {
this(context, attrs, 0);
}
/**
* {@inheritDoc}
*/
public ProfileBannerSpace(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
mSystemWindowsInsets = new Rect();
}
/**
* Draw nothing.
*
* @param canvas an unused parameter.
*/
@Override
public void draw(final Canvas canvas) {
}
@Override
protected boolean fitSystemWindows(Rect insets) {
mSystemWindowsInsets.set(insets);
return super.fitSystemWindows(insets);
}
@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
final int width = MeasureSpec.getSize(widthMeasureSpec), height = width / 2 - mSystemWindowsInsets.top;
setMeasuredDimension(width, height);
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
}
}

View File

@ -0,0 +1,118 @@
/*
* 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.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.widget.FrameLayout;
import org.mariotaku.twidere.util.MathUtils;
import org.mariotaku.twidere.util.Utils;
/**
* Created by mariotaku on 14/11/26.
*/
public class UserProfileContentFrameLayout extends FrameLayout {
private final Paint mBlackPaint, mShadowPaint, mColorPaint;
private int mStatusBarHeight;
private float mFactor;
private int mColorAlpha, mShadowAlpha;
private boolean mDrawShadow, mDrawColor;
public UserProfileContentFrameLayout(Context context) {
this(context, null);
}
public UserProfileContentFrameLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public UserProfileContentFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mBlackPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBlackPaint.setColor(Color.BLACK);
mShadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mColorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
setWillNotDraw(false);
}
public void setColor(int color) {
mColorPaint.setColor(color);
mColorAlpha = Color.alpha(color);
updateAlpha();
}
public void setShadowColor(int color) {
mShadowPaint.setColor(color);
mShadowAlpha = Color.alpha(color);
updateAlpha();
}
@Override
protected boolean fitSystemWindows(Rect insets) {
setStatusBarHeight(Utils.getInsetsTopWithoutActionBarHeight(getContext(), insets.top));
return false;
}
@Override
protected void dispatchDraw(@NonNull Canvas canvas) {
super.dispatchDraw(canvas);
if (mDrawShadow) {
canvas.drawRect(0, 0, canvas.getWidth(), mStatusBarHeight, mShadowPaint);
} else if (mDrawColor) {
canvas.drawRect(0, 0, canvas.getWidth(), mStatusBarHeight, mBlackPaint);
}
canvas.drawRect(0, 0, canvas.getWidth(), mStatusBarHeight, mDrawColor ? mColorPaint : mBlackPaint);
}
private void setStatusBarHeight(int height) {
mStatusBarHeight = height;
invalidate();
}
public void setFactor(float f) {
mFactor = f;
updateAlpha();
}
public void setDrawShadow(boolean shadow) {
mDrawShadow = shadow;
invalidate();
}
public void setDrawColor(boolean color) {
mDrawColor = color;
invalidate();
}
private void updateAlpha() {
final float f = mFactor;
mShadowPaint.setAlpha(Math.round(mShadowAlpha * MathUtils.clamp(1 - f, 0, 1)));
mColorPaint.setAlpha(Math.round(0xFF * MathUtils.clamp(f, 0, 1)));
invalidate();
}
}

View File

@ -0,0 +1,490 @@
package org.mariotaku.twidere.view;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.ScrollerCompat;
import android.support.v4.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.util.MathUtils;
/**
* Created by mariotaku on 14/11/27.
*/
public class UserProfileDrawer extends ViewGroup {
static final String LOGTAG = "UserProfileDrawer";
private final ViewDragHelper mDragHelper;
private final ScrollerCompat mScroller;
private final GestureDetector mGestureDetector;
private final InternalContainer mContainer;
private final DragCallback mDragCallback;
private DrawerCallback mDrawerCallback;
private boolean mUsingDragHelper, mScrollingHeaderByGesture;
private boolean mTouchDown, mTouchingScrollableContent;
private int mHeaderOffset;
public UserProfileDrawer(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.UserProfileDrawer);
final int headerLayoutId = a.getResourceId(R.styleable.UserProfileDrawer_headerLayout, 0);
final int contentLayoutId = a.getResourceId(R.styleable.UserProfileDrawer_contentLayout, 0);
addView(mContainer = new InternalContainer(this, context, headerLayoutId, contentLayoutId),
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
a.recycle();
mDragHelper = ViewDragHelper.create(this, mDragCallback = new DragCallback(this));
mGestureDetector = new GestureDetector(context, new GestureListener(this));
mScroller = ScrollerCompat.create(context);
}
public UserProfileDrawer(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public UserProfileDrawer(Context context) {
this(context, null);
}
private static int makeChildMeasureSpec(int spec, int padding) {
final int size = MeasureSpec.getSize(spec), mode = MeasureSpec.getMode(spec);
return MeasureSpec.makeMeasureSpec(size - padding, mode);
}
private boolean isUsingDragHelper() {
return mUsingDragHelper;
}
private void setScrollingHeaderByGesture(boolean scrolling) {
mScrollingHeaderByGesture = scrolling;
}
@Override
public void computeScroll() {
boolean invalidate = mDragHelper.continueSettling(true);
if (!mTouchDown && mScroller.computeScrollOffset()) {
if (!invalidate) {
offsetHeaderBy(mScroller.getCurrY() - getHeaderTop());
}
invalidate = true;
}
updateViewOffset();
if (invalidate) {
ViewCompat.postInvalidateOnAnimation(this);
}
}
public void flingHeader(float velocity) {
if (mTouchDown) {
mScroller.abortAnimation();
return;
}
mScroller.fling(0, getHeaderTop(), 0, (int) velocity, 0, 0,
mContainer.getHeaderTopMinimum(), mContainer.getHeaderTopMaximum());
ViewCompat.postInvalidateOnAnimation(this);
}
@Override
protected void onFinishInflate() {
if (getChildCount() != 1) {
throw new IllegalArgumentException("Add subview by XML is not allowed.");
}
}
private void flingCallback(float velocity) {
mDrawerCallback.fling(velocity);
}
private void scrollByCallback(float dy) {
mDrawerCallback.scrollBy(dy);
}
private boolean isScrollContentCallback(float x, float y) {
return mDrawerCallback.isScrollContent(x, y);
}
private void cancelTouchCallback() {
mDrawerCallback.cancelTouch();
}
private boolean canScrollCallback(float dy) {
return mDrawerCallback.canScroll(dy);
}
public void setDrawerCallback(DrawerCallback callback) {
mDrawerCallback = callback;
}
private void updateViewOffset() {
}
@Override
public boolean dispatchTouchEvent(@NonNull MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN: {
mScroller.abortAnimation();
mTouchDown = true;
mTouchingScrollableContent = isScrollContentCallback(ev.getX(), ev.getY());
mUsingDragHelper = false;
mScrollingHeaderByGesture = false;
break;
}
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP: {
mTouchDown = false;
mTouchingScrollableContent = false;
mUsingDragHelper = false;
mScrollingHeaderByGesture = false;
}
}
mGestureDetector.onTouchEvent(ev);
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (mDragHelper.shouldInterceptTouchEvent(ev) || mScrollingHeaderByGesture) {
mUsingDragHelper = true;
return true;
}
return false;
}
@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);
final int left = getPaddingLeft(), right = left + child.getMeasuredWidth();
final int top = i == 0 ? mHeaderOffset + getPaddingTop() : getChildAt(i - 1).getBottom();
final int bottom = top + child.getMeasuredHeight();
child.layout(left, top, right, bottom);
}
}
@Override
public boolean onTouchEvent(@NonNull MotionEvent event) {
mDragHelper.processTouchEvent(event);
return true;
}
public View getHeader() {
return mContainer.getHeader();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final View child = getChildAt(0);
final int childWidthMeasureSpec = makeChildMeasureSpec(widthMeasureSpec, getPaddingLeft() + getPaddingRight());
final int childHeightMeasureSpec = makeChildMeasureSpec(heightMeasureSpec, getPaddingTop() + getPaddingBottom());
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public View getContent() {
return mContainer.getContent();
}
private int getScrollRange() {
return mContainer.getScrollRange();
}
public int getHeaderTop() {
return mContainer.getTop();
}
private void offsetHeaderBy(int dy) {
final int prevTop = mContainer.getTop();
final int clampedDy = MathUtils.clamp(prevTop + dy, getHeaderTopMinimum(), getHeaderTopMaximum()) - prevTop;
mContainer.offsetTopAndBottom(clampedDy);
}
public int getHeaderTopMaximum() {
return mContainer.getHeaderTopMaximum();
}
public int getHeaderTopMinimum() {
return mContainer.getHeaderTopMinimum();
}
private boolean isTouchingScrollableContent() {
return mTouchingScrollableContent;
}
private void notifyOffsetChanged() {
final int top = getHeaderTop();
mHeaderOffset = top - getPaddingTop();
mDrawerCallback.topChanged(top);
}
private float getDragTouchSlop() {
return mDragHelper.getTouchSlop();
}
private boolean isValidScroll(float direction, float other) {
return Math.abs(direction) > getDragTouchSlop() && Math.abs(direction) > Math.abs(other);
}
public static interface DrawerCallback {
void fling(float velocity);
void scrollBy(float dy);
boolean canScroll(float dy);
boolean isScrollContent(float x, float y);
void cancelTouch();
void topChanged(int offset);
}
private static class DragCallback extends ViewDragHelper.Callback {
private final UserProfileDrawer mDrawer;
private long mTime;
private float mDx, mDy, mVelocity;
private boolean mScrollingByHelper;
public DragCallback(UserProfileDrawer drawer) {
mDrawer = drawer;
mTime = -1;
mDx = Float.NaN;
mDy = Float.NaN;
mVelocity = Float.NaN;
}
@Override
public void onViewDragStateChanged(int state) {
switch (state) {
case ViewDragHelper.STATE_SETTLING:
case ViewDragHelper.STATE_DRAGGING: {
mScrollingByHelper = false;
break;
}
case ViewDragHelper.STATE_IDLE: {
if (mTime > 0 && !Float.isNaN(mVelocity)) {
final float velocity = mVelocity;
if (velocity < 0 && mDrawer.getHeaderTop() <= mDrawer.getHeaderTopMinimum()) {
mDrawer.flingCallback(-velocity);
}
}
mTime = -1;
mDx = Float.NaN;
mDy = Float.NaN;
mVelocity = Float.NaN;
mScrollingByHelper = false;
break;
}
}
super.onViewDragStateChanged(state);
}
@Override
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
super.onViewPositionChanged(changedView, left, top, dx, dy);
final long time = SystemClock.uptimeMillis();
final float timeDelta = time - mTime;
mVelocity = mDy / timeDelta * 1000;
mTime = time;
mDy = dy;
}
@Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
mDrawer.mDragHelper.flingCapturedView(mDrawer.getPaddingLeft(),
mDrawer.getHeaderTopMinimum(), mDrawer.getPaddingLeft(),
mDrawer.getHeaderTopMaximum());
ViewCompat.postInvalidateOnAnimation(mDrawer);
}
@Override
public int getViewVerticalDragRange(View child) {
return mDrawer.getScrollRange();
}
@Override
public boolean tryCaptureView(View view, int pointerId) {
return view == mDrawer.mContainer;
}
@Override
public int clampViewPositionHorizontal(View child, int left, int dx) {
mDx = dx;
return mDrawer.getPaddingLeft();
}
@Override
public int clampViewPositionVertical(View child, int top, int dy) {
final int current = mDrawer.getHeaderTop();
if (!Float.isNaN(mDx) && mDrawer.isValidScroll(mDx, dy)) {
mScrollingByHelper = false;
return current;
}
if (dy > 0 && mDrawer.canScrollCallback(-dy) && !mDrawer.isUsingDragHelper()) {
// Scrolling up while list still has space to scroll, so make header still
mScrollingByHelper = false;
return current;
} else if (dy > 0 && mDrawer.canScrollCallback(-dy) && mDrawer.isTouchingScrollableContent()) {
mDrawer.scrollByCallback(-dy);
mScrollingByHelper = false;
return current;
}
final int min = mDrawer.getHeaderTopMinimum(), max = mDrawer.getHeaderTopMaximum();
if (top < min && mDrawer.isTouchingScrollableContent()) {
mDrawer.scrollByCallback(-dy);
}
mScrollingByHelper = true;
return MathUtils.clamp(top, min, max);
}
private boolean isScrollingByHelper() {
return mScrollingByHelper;
}
}
private static class GestureListener extends SimpleOnGestureListener {
private final UserProfileDrawer mDrawer;
public GestureListener(UserProfileDrawer drawer) {
mDrawer = drawer;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
if (!mDrawer.isUsingDragHelper() && mDrawer.isValidScroll(distanceY, distanceX)) {
final int offset = mDrawer.getHeaderTop(), min = mDrawer.getHeaderTopMinimum();
if (!mDrawer.canScrollCallback(-1)) {
if (distanceY < 0) {
if (!mDrawer.mDragCallback.isScrollingByHelper()) {
mDrawer.offsetHeaderBy(Math.round(-distanceY));
}
mDrawer.setScrollingHeaderByGesture(true);
} else if (distanceY > 0 && offset > min) {
// Scrolling up when scrolling to list top, so we cancel touch event and scrolling header up
mDrawer.cancelTouchCallback();
if (!mDrawer.mDragCallback.isScrollingByHelper()) {
mDrawer.offsetHeaderBy(Math.round(-distanceY));
}
} else if (offset <= min) {
mDrawer.scrollByCallback(-distanceX);
}
}
}
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if (velocityY > 0 && !mDrawer.canScrollCallback(-1)) {
// Fling down when list reached top, so we fling header down here
if (Math.abs(velocityY) > Math.abs(velocityX)) {
mDrawer.flingHeader(velocityY);
}
} else if (velocityY < 0 && mDrawer.getHeaderTop() <= mDrawer.getHeaderTopMinimum()) {
// Fling up when showing full content, so we fling list up here
if (Math.abs(velocityY) > Math.abs(velocityX)) {
mDrawer.flingCallback(-velocityY);
}
}
return true;
}
@Override
public boolean onDown(MotionEvent e) {
return true;
}
}
@SuppressLint("ViewConstructor")
private static class InternalContainer extends ViewGroup {
private final UserProfileDrawer mParent;
private final View mHeaderView, mContentView;
public InternalContainer(UserProfileDrawer parent, Context context, int headerLayoutId, int contentLayoutId) {
super(context);
mParent = parent;
final LayoutInflater inflater = LayoutInflater.from(context);
addView(mHeaderView = inflater.inflate(headerLayoutId, this, false));
addView(mContentView = inflater.inflate(contentLayoutId, this, false));
}
public View getHeader() {
return mHeaderView;
}
public View getContent() {
return mContentView;
}
public int getHeaderTopMinimum() {
return mParent.getPaddingTop() - mHeaderView.getHeight();
}
public int getHeaderTopMaximum() {
return mParent.getPaddingTop();
}
public int getScrollRange() {
return getHeaderTopMaximum() - getHeaderTopMinimum();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int measureHeight = MeasureSpec.getSize(heightMeasureSpec);
int heightSum = 0;
for (int i = 0, j = getChildCount(); i < j; i++) {
final View child = getChildAt(i);
final LayoutParams lp = child.getLayoutParams();
final int childHeightSpec;
if (lp.height == LayoutParams.MATCH_PARENT) {
childHeightSpec = heightMeasureSpec;
} else if (lp.height == LayoutParams.WRAP_CONTENT) {
childHeightSpec = MeasureSpec.makeMeasureSpec(measureHeight, MeasureSpec.UNSPECIFIED);
} else {
childHeightSpec = MeasureSpec.makeMeasureSpec(measureHeight, MeasureSpec.EXACTLY);
}
child.measure(widthMeasureSpec, childHeightSpec);
heightSum += child.getMeasuredHeight();
}
final int hSpec = MeasureSpec.makeMeasureSpec(heightSum, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, hSpec);
}
@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);
final int left = getPaddingLeft(), right = left + child.getMeasuredWidth();
final int top = i == 0 ? getPaddingTop() : getChildAt(i - 1).getBottom();
final int bottom = top + child.getMeasuredHeight();
child.layout(left, top, right, bottom);
}
}
@Override
public void offsetTopAndBottom(int offset) {
super.offsetTopAndBottom(offset);
mParent.notifyOffsetChanged();
}
}
}

View File

@ -180,7 +180,8 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
break;
}
case R.id.profile_image: {
Utils.openUserProfile(context, status.account_id, status.user_id, status.user_screen_name);
Utils.openUserProfile(context, status.account_id, status.user_id,
status.user_screen_name, null);
break;
}
case R.id.reply_count: {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 545 B

After

Width:  |  Height:  |  Size: 766 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 383 B

After

Width:  |  Height:  |  Size: 497 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 700 B

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@android:color/holo_red_light"/>
<solid android:color="@color/unread_color"/>
<size
android:width="@dimen/unread_indicator_size"
android:height="@dimen/unread_indicator_size"/>

View File

@ -55,6 +55,7 @@
<org.mariotaku.twidere.view.CircularImageView
android:id="@+id/profile_image"
style="?profileImageStyle"
android:layout_width="@dimen/element_size_normal"
android:layout_height="@dimen/element_size_normal"
android:layout_centerVertical="true"
@ -163,8 +164,8 @@
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/profile_container"
android:layout_below="@id/media_preview_container"
android:layout_marginTop="@dimen/element_spacing_normal"
android:layout_marginBottom="@dimen/element_spacing_normal"
android:layout_marginTop="@dimen/element_spacing_normal"
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_normal"
android:textAppearance="?android:attr/textAppearanceSmall"
@ -195,7 +196,7 @@
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_normal"
android:textAppearance="?android:textAppearanceSmall"
app:activatedColor="@android:color/holo_blue_light"/>
app:activatedColor="@color/highlight_reply"/>
<org.mariotaku.twidere.view.CardActionTextView
android:id="@+id/retweet_count"
@ -208,7 +209,7 @@
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_normal"
android:textAppearance="?android:textAppearanceSmall"
app:activatedColor="@android:color/holo_green_light"/>
app:activatedColor="@color/highlight_retweet"/>
<org.mariotaku.twidere.view.CardActionTextView
android:id="@+id/favorite_count"
@ -221,7 +222,7 @@
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_normal"
android:textAppearance="?android:textAppearanceSmall"
app:activatedColor="@android:color/holo_orange_light"/>
app:activatedColor="@color/highlight_favorite"/>
</LinearLayout>
</HorizontalScrollView>

View File

@ -2,6 +2,7 @@
<RelativeLayout
android:id="@+id/item_content"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:selectableItemBackground"
@ -11,11 +12,11 @@
android:paddingTop="@dimen/element_spacing_normal">
<org.mariotaku.twidere.view.CircularImageView
android:scaleType="centerCrop"
android:id="@+id/retweet_profile_image"
android:layout_width="@dimen/element_size_small"
android:layout_height="@dimen/element_size_small"
android:layout_marginLeft="@dimen/element_spacing_normal"/>
android:layout_marginLeft="@dimen/element_spacing_normal"
android:scaleType="centerCrop"/>
<org.mariotaku.twidere.view.CardActionTextView
android:id="@+id/reply_retweet_status"
@ -47,9 +48,9 @@
android:layout_width="@dimen/icon_size_profile_type"
android:layout_height="@dimen/icon_size_profile_type"
android:layout_alignBottom="@id/profile_image"
android:layout_marginRight="@dimen/element_spacing_minus_normal"
android:layout_marginBottom="@dimen/element_spacing_minus_small"
android:layout_alignRight="@id/profile_image"
android:layout_marginBottom="@dimen/element_spacing_minus_small"
android:layout_marginRight="@dimen/element_spacing_minus_normal"
android:scaleType="centerInside"/>
<LinearLayout
@ -151,7 +152,8 @@
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
<org.mariotaku.twidere.view.CardActionTextView
android:id="@+id/reply_count"
style="?cardActionButtonStyle"
android:layout_width="wrap_content"
@ -161,9 +163,10 @@
android:gravity="center"
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_normal"
android:textAppearance="?android:textAppearanceSmall"/>
android:textAppearance="?android:textAppearanceSmall"
app:activatedColor="@color/highlight_reply"/>
<TextView
<org.mariotaku.twidere.view.CardActionTextView
android:id="@+id/retweet_count"
style="?cardActionButtonStyle"
android:layout_width="wrap_content"
@ -173,9 +176,10 @@
android:gravity="center"
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_normal"
android:textAppearance="?android:textAppearanceSmall"/>
android:textAppearance="?android:textAppearanceSmall"
app:activatedColor="@color/highlight_retweet"/>
<TextView
<org.mariotaku.twidere.view.CardActionTextView
android:id="@+id/favorite_count"
style="?cardActionButtonStyle"
android:layout_width="wrap_content"
@ -185,7 +189,8 @@
android:gravity="center"
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_normal"
android:textAppearance="?android:textAppearanceSmall"/>
android:textAppearance="?android:textAppearanceSmall"
app:activatedColor="@color/highlight_favorite"/>
</LinearLayout>
@ -193,9 +198,9 @@
<Space
android:layout_width="wrap_content"
android:layout_toRightOf="@+id/actions_scroller"
android:layout_height="wrap_content"
android:layout_toLeftOf="@+id/menu"
android:layout_height="wrap_content"/>
android:layout_toRightOf="@+id/actions_scroller"/>
<org.mariotaku.twidere.view.ActionIconButton
android:id="@+id/menu"

View File

@ -3,9 +3,8 @@
android:id="@+id/fragment_content"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:animateLayoutChanges="true"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
android:animateLayoutChanges="true">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipe_layout"
@ -24,8 +23,8 @@
<ProgressBar
android:id="@+id/progress"
android:layout_width="wrap_content"
style="?android:progressBarStyleLarge"
android:layout_gravity="center"
android:layout_height="wrap_content"/>
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
</FrameLayout>

View File

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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/>.
-->
<org.mariotaku.twidere.view.UserProfileContentFrameLayout
android:id="@+id/user_profile_fragment"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true">
<org.mariotaku.twidere.view.ExtendedFrameLayout
android:id="@+id/details_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.mariotaku.twidere.view.ProfileBannerImageView
android:id="@+id/profile_banner"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:scaleType="centerCrop"/>
<org.mariotaku.twidere.view.UserProfileDrawer
android:id="@+id/user_profile_drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentLayout="@layout/fragment_user_profile_pages"
app:headerLayout="@layout/header_user_profile"/>
</org.mariotaku.twidere.view.ExtendedFrameLayout>
<FrameLayout
android:id="@+id/progress_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
style="?android:progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
</FrameLayout>
<LinearLayout
android:id="@+id/error_retry_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:padding="16dp"
android:visibility="gone">
<TextView
android:id="@+id/error_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:visibility="gone"/>
<Button
android:id="@+id/retry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="48dp"
android:minWidth="84dp"
android:text="@string/retry"
android:textAppearance="?android:attr/textAppearanceSmall"/>
</LinearLayout>
</org.mariotaku.twidere.view.UserProfileContentFrameLayout>

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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/>.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.astuetz.PagerSlidingTabStrip
android:id="@+id/view_pager_tabs"
android:layout_width="match_parent"
android:layout_height="@dimen/element_size_normal"/>
<android.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>

View File

@ -1,24 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="@dimen/element_spacing_normal">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="@dimen/element_spacing_normal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/hidden_settings_warning_title"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@android:color/holo_orange_dark"
android:textStyle="bold"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/hidden_settings_warning_title"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/material_red"
android:textStyle="bold"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/hidden_settings_warning_message"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:textColorPrimary"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/hidden_settings_warning_message"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:textColorPrimary"/>
</LinearLayout>

View File

@ -49,7 +49,7 @@
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:contentDescription="@string/profile_image"
android:padding="@dimen/padding_profile_image_detail_page"
android:layout_margin="@dimen/padding_profile_image_detail_page"
android:scaleType="centerCrop"
app:border="true"
app:borderWidth="1dp"/>

View File

@ -4,10 +4,9 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
android:layout_height="wrap_content">
<Space
<org.mariotaku.twidere.view.ProfileBannerSpace
android:id="@+id/profile_banner_space"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>

View File

@ -36,8 +36,9 @@
android:layout_weight="0"
android:background="@drawable/list_drag_handle"/>
<ImageView
<org.mariotaku.twidere.view.CircularImageView
android:id="@android:id/icon"
style="?profileImageStyle"
android:layout_width="@dimen/icon_size_list_item"
android:layout_height="@dimen/icon_size_list_item"
android:layout_centerVertical="true"

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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/>.
-->
<transitionSet
xmlns:android="http://schemas.android.com/apk/res/android">
<changeBounds>
<targets>
<target android:targetId="@id/profile_image"/>
<target android:targetId="@id/profile_type"/>
</targets>
</changeBounds>
<autoTransition>
<targets>
<target android:targetId="@id/profile_banner"/>
</targets>
</autoTransition>
</transitionSet>

View File

@ -83,6 +83,10 @@
<attr name="borderColor" format="color"/>
<attr name="elevation" format="dimension"/>
</declare-styleable>
<declare-styleable name="UserProfileDrawer">
<attr name="headerLayout" format="reference"/>
<attr name="contentLayout" format="reference"/>
</declare-styleable>
<attr name="notificationType">
<flag name="none" value="0"/>
<flag name="ringtone" value="1"/>

View File

@ -18,5 +18,10 @@
<color name="action_icon_dark_disabled">#4D333333</color>
<color name="action_icon_light">#CCFFFFFF</color>
<color name="action_icon_light_disabled">#4DFFFFFF</color>
<color name="highlight_retweet">@color/material_light_green</color>
<color name="highlight_favorite">@color/material_amber</color>
<color name="highlight_reply">@color/material_light_blue</color>
<color name="unread_color">@color/material_red</color>
<color name="branding_color">@color/material_light_blue</color>
</resources>

View File

@ -10,7 +10,7 @@
<style name="Theme.Blank" parent="android:Theme.DeviceDefault.NoActionBar">
<!-- Window attributes -->
<item name="android:windowAnimationStyle">@style/Animation.Twidere.Activity</item>
<!--<item name="android:windowAnimationStyle">@style/Animation.Twidere.Activity</item>-->
<item name="android:windowBackground">@android:color/black</item>
</style>
@ -22,7 +22,7 @@
<!--<item name="android:colorBackgroundCacheHint">@color/bg_color_dark</item>-->
<!-- Window attributes -->
<item name="android:windowAnimationStyle">@style/Animation.Twidere.Activity</item>
<!--<item name="android:windowAnimationStyle">@style/Animation.Twidere.Activity</item>-->
<!--<item name="android:windowBackground">@color/bg_color_dark</item>-->
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowActionModeOverlay">true</item>
@ -70,7 +70,7 @@
<!--<item name="android:colorBackgroundCacheHint">@color/bg_color_light</item>-->
<!-- Window attributes -->
<item name="android:windowAnimationStyle">@style/Animation.Twidere.Activity</item>
<!--<item name="android:windowAnimationStyle">@style/Animation.Twidere.Activity</item>-->
<!--<item name="android:windowBackground">@color/bg_color_light</item>-->
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowActionModeOverlay">true</item>
@ -256,7 +256,7 @@
<!-- Window attributes -->
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowActionModeOverlay">true</item>
<item name="android:windowAnimationStyle">@style/Animation.Twidere.Activity</item>
<!--<item name="android:windowAnimationStyle">@style/Animation.Twidere.Activity</item>-->
<item name="android:windowBackground">@android:color/black</item>
<!-- ActionBar styles -->
@ -354,7 +354,7 @@
<item name="android:colorBackgroundCacheHint">@color/bg_color_dark</item>
<!-- Window attributes -->
<item name="android:windowAnimationStyle">@style/Animation.Twidere.Activity</item>
<!--<item name="android:windowAnimationStyle">@style/Animation.Twidere.Activity</item>-->
<!--<item name="android:windowBackground">@color/bg_color_dark</item>-->
<!-- ActionBar styles -->
@ -399,7 +399,7 @@
<item name="android:colorBackgroundCacheHint">@color/bg_color_light</item>
<!-- Window attributes -->
<item name="android:windowAnimationStyle">@style/Animation.Twidere.Activity</item>
<!--<item name="android:windowAnimationStyle">@style/Animation.Twidere.Activity</item>-->
<!--<item name="android:windowBackground">@color/bg_color_light</item>-->
<!-- Custom view styles -->
@ -440,7 +440,7 @@
<!--<item name="android:colorBackgroundCacheHint">@color/bg_color_light</item>-->
<!-- Window attributes -->
<item name="android:windowAnimationStyle">@style/Animation.Twidere.Activity</item>
<!--<item name="android:windowAnimationStyle">@style/Animation.Twidere.Activity</item>-->
<!--<item name="android:windowBackground">@color/bg_color_light</item>-->
<!-- Custom view styles -->
@ -480,7 +480,7 @@
<style name="Theme.Twidere.Wizard" parent="Theme.Twidere.Settings.Light">
<item name="android:windowNoTitle">true</item>
<item name="android:windowActionBar">false</item>
<item name="android:colorActivatedHighlight">@android:color/holo_blue_light</item>
<item name="android:colorActivatedHighlight">@color/branding_color</item>
</style>
</resources>

View File

@ -12,7 +12,7 @@
android:title="@string/notification_ringtone"/>
<org.mariotaku.twidere.preference.ColorPickerPreference
android:defaultValue="@android:color/holo_blue_dark"
android:defaultValue="@color/branding_color"
android:key="notification_light_color"
android:title="@string/notification_light_color"/>

View File

@ -24,7 +24,7 @@
android:title="@string/background"/>
<org.mariotaku.twidere.preference.ColorPickerPreference
android:defaultValue="@android:color/holo_blue_light"
android:defaultValue="@color/branding_color"
android:key="theme_color"
android:order="25"
android:title="@string/color"/>