mirror of
https://github.com/TwidereProject/Twidere-Android
synced 2025-02-17 04:00:48 +01:00
improved settings ui
improved base theme started to redesign all timeline fragments.
This commit is contained in:
parent
8c39dc280f
commit
4cc47a3af1
@ -28,7 +28,7 @@ package org.mariotaku.twidere;
|
||||
public interface Constants extends TwidereConstants {
|
||||
|
||||
public static final String DATABASES_NAME = "twidere.sqlite";
|
||||
public static final int DATABASES_VERSION = 72;
|
||||
public static final int DATABASES_VERSION = 74;
|
||||
|
||||
public static final int MENU_GROUP_STATUS_EXTENSION = 10;
|
||||
public static final int MENU_GROUP_COMPOSE_EXTENSION = 11;
|
||||
|
@ -31,23 +31,30 @@ import android.graphics.PorterDuff.Mode;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewGroup.LayoutParams;
|
||||
import android.view.ViewGroup.MarginLayoutParams;
|
||||
import android.view.ViewParent;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListAdapter;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.activity.support.DataExportActivity;
|
||||
import org.mariotaku.twidere.activity.support.DataImportActivity;
|
||||
import org.mariotaku.twidere.adapter.ArrayAdapter;
|
||||
import org.mariotaku.twidere.graphic.EmptyDrawable;
|
||||
import org.mariotaku.twidere.util.CompareUtils;
|
||||
import org.mariotaku.twidere.util.ThemeUtils;
|
||||
import org.mariotaku.twidere.view.holder.ViewHolder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SettingsActivity extends BasePreferenceActivity {
|
||||
@ -60,7 +67,7 @@ public class SettingsActivity extends BasePreferenceActivity {
|
||||
private HeaderAdapter mAdapter;
|
||||
|
||||
private int mCurrentThemeColor, mThemeBackgroundAlpha;
|
||||
private boolean mCompactCards, mPlainListStyle;
|
||||
private boolean mCompactCards;
|
||||
|
||||
private String mTheme;
|
||||
private String mThemeFontFamily;
|
||||
@ -179,7 +186,6 @@ public class SettingsActivity extends BasePreferenceActivity {
|
||||
mPackageManager = getPackageManager();
|
||||
mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, MODE_PRIVATE);
|
||||
mCompactCards = mPreferences.getBoolean(KEY_COMPACT_CARDS, false);
|
||||
mPlainListStyle = mPreferences.getBoolean(KEY_PLAIN_LIST_STYLE, false);
|
||||
mTheme = mPreferences.getString(KEY_THEME, DEFAULT_THEME);
|
||||
mThemeBackground = mPreferences.getString(KEY_THEME_BACKGROUND, DEFAULT_THEME_BACKGROUND);
|
||||
mThemeBackgroundAlpha = mPreferences.getInt(KEY_THEME_BACKGROUND_ALPHA, DEFAULT_THEME_BACKGROUND_ALPHA);
|
||||
@ -194,6 +200,24 @@ public class SettingsActivity extends BasePreferenceActivity {
|
||||
if (savedInstanceState != null) {
|
||||
invalidateHeaders();
|
||||
}
|
||||
final ListView listView = getListView();
|
||||
if (listView != null) {
|
||||
listView.setDivider(new EmptyDrawable());
|
||||
listView.setDividerHeight(0);
|
||||
final LayoutParams lp = listView.getLayoutParams();
|
||||
if (lp instanceof MarginLayoutParams) {
|
||||
final MarginLayoutParams mlp = (MarginLayoutParams) lp;
|
||||
mlp.leftMargin = 0;
|
||||
mlp.topMargin = 0;
|
||||
mlp.rightMargin = 0;
|
||||
mlp.bottomMargin = 0;
|
||||
listView.setLayoutParams(mlp);
|
||||
}
|
||||
final ViewParent listParent = listView.getParent();
|
||||
if (listParent instanceof ViewGroup) {
|
||||
((ViewGroup) listParent).setPadding(0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldNotifyThemeChange() {
|
||||
@ -202,91 +226,199 @@ public class SettingsActivity extends BasePreferenceActivity {
|
||||
|| !CompareUtils.objectEquals(mThemeBackground, mPreferences.getString(KEY_THEME_BACKGROUND, DEFAULT_THEME_BACKGROUND))
|
||||
|| mCurrentThemeColor != ThemeUtils.getUserAccentColor(this)
|
||||
|| mThemeBackgroundAlpha != mPreferences.getInt(KEY_THEME_BACKGROUND_ALPHA, DEFAULT_THEME_BACKGROUND_ALPHA)
|
||||
|| mCompactCards != mPreferences.getBoolean(KEY_COMPACT_CARDS, false)
|
||||
|| mPlainListStyle != mPreferences.getBoolean(KEY_PLAIN_LIST_STYLE, false);
|
||||
|| mCompactCards != mPreferences.getBoolean(KEY_COMPACT_CARDS, false);
|
||||
}
|
||||
|
||||
private static class HeaderAdapter extends ArrayAdapter<Header> {
|
||||
private static class HeaderAdapter extends BaseAdapter {
|
||||
|
||||
static final int HEADER_TYPE_CATEGORY = 0;
|
||||
static final int HEADER_TYPE_NORMAL = 1;
|
||||
static final int HEADER_TYPE_NORMAL = 0;
|
||||
static final int HEADER_TYPE_CATEGORY = 1;
|
||||
static final int HEADER_TYPE_SPACE = 2;
|
||||
|
||||
private final Context mContext;
|
||||
private final Resources mResources;
|
||||
private final int mActionIconColor;
|
||||
private final ArrayList<Header> mHeaders;
|
||||
private final LayoutInflater mInflater;
|
||||
private int mCategoriesCount;
|
||||
private boolean mFirstItemIsCategory;
|
||||
|
||||
public HeaderAdapter(final Context context) {
|
||||
super(context, R.layout.list_item_preference_header);
|
||||
mContext = context;
|
||||
mInflater = LayoutInflater.from(context);
|
||||
mHeaders = new ArrayList<>();
|
||||
mResources = context.getResources();
|
||||
mActionIconColor = ThemeUtils.getThemeForegroundColor(context);
|
||||
}
|
||||
|
||||
public void add(Header header) {
|
||||
mHeaders.add(header);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void addAll(List<Header> headers) {
|
||||
mHeaders.addAll(headers);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areAllItemsEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyDataSetChanged() {
|
||||
updateCategoriesInfo();
|
||||
super.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private void updateCategoriesInfo() {
|
||||
mFirstItemIsCategory = !mHeaders.isEmpty()
|
||||
&& getHeaderType(mHeaders.get(0)) == HEADER_TYPE_CATEGORY;
|
||||
mCategoriesCount = getCategoriesCount(0, mHeaders.size());
|
||||
}
|
||||
|
||||
private int getCategoriesCount(final int start, final int end) {
|
||||
int categoriesCount = 0;
|
||||
for (int i = start; i < end; i++) {
|
||||
if (getHeaderType(mHeaders.get(i)) == HEADER_TYPE_CATEGORY) {
|
||||
categoriesCount++;
|
||||
}
|
||||
}
|
||||
return categoriesCount;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
mHeaders.clear();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViewTypeCount() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(final int position) {
|
||||
final Header header = getItem(position);
|
||||
return getHeaderType(header);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return mHeaders.size() + mCategoriesCount + (mFirstItemIsCategory ? 0 : 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Header getItem(final int position) {
|
||||
if (position == getCount() - 1) return new Header();
|
||||
final int realPosition = mFirstItemIsCategory ? position + 1 : position;
|
||||
int categoriesCount = 0;
|
||||
int i;
|
||||
for (i = 0; i + categoriesCount < realPosition; i++) {
|
||||
if (getHeaderType(mHeaders.get(i)) == HEADER_TYPE_CATEGORY) {
|
||||
categoriesCount++;
|
||||
}
|
||||
}
|
||||
if (i + categoriesCount == realPosition && getHeaderType(mHeaders.get(i)) == HEADER_TYPE_CATEGORY) {
|
||||
return new Header();
|
||||
}
|
||||
return mHeaders.get(realPosition - categoriesCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(final int position, final View convertView, final ViewGroup parent) {
|
||||
final Header header = getItem(position);
|
||||
final int viewType = getHeaderType(header);
|
||||
final View view;
|
||||
final View view = convertView != null ? convertView : inflateItemView(viewType, parent);
|
||||
switch (viewType) {
|
||||
case HEADER_TYPE_CATEGORY: {
|
||||
view = new TextView(mContext, null, android.R.attr.listSeparatorTextViewStyle);
|
||||
((TextView) view).setText(header.getTitle(mResources));
|
||||
bindCategoryHeader(view, position, header);
|
||||
break;
|
||||
}
|
||||
case HEADER_TYPE_SPACE: {
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
final boolean viewChanged = convertView != null
|
||||
&& !(convertView.getTag() instanceof HeaderViewHolder);
|
||||
view = super.getView(position, viewChanged ? null : convertView, parent);
|
||||
final HeaderViewHolder holder;
|
||||
final Object tag = view.getTag();
|
||||
if (tag instanceof HeaderViewHolder) {
|
||||
holder = (HeaderViewHolder) tag;
|
||||
} else {
|
||||
holder = new HeaderViewHolder(view);
|
||||
view.setTag(holder);
|
||||
}
|
||||
final CharSequence title = header.getTitle(mResources);
|
||||
holder.title.setText(title);
|
||||
final CharSequence summary = header.getSummary(mResources);
|
||||
if (!TextUtils.isEmpty(summary)) {
|
||||
holder.summary.setVisibility(View.VISIBLE);
|
||||
holder.summary.setText(summary);
|
||||
} else {
|
||||
holder.summary.setVisibility(View.GONE);
|
||||
}
|
||||
if (header.iconRes != 0) {
|
||||
holder.icon.setImageResource(header.iconRes);
|
||||
} else {
|
||||
holder.icon.setImageDrawable(null);
|
||||
}
|
||||
holder.icon.setColorFilter(mActionIconColor, Mode.SRC_ATOP);
|
||||
bindHeader(view, position, header);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
private void bindCategoryHeader(View view, int position, Header header) {
|
||||
final TextView title = (TextView) view.findViewById(android.R.id.title);
|
||||
if (!TextUtils.isEmpty(header.title)) {
|
||||
title.setText(header.title);
|
||||
} else {
|
||||
title.setText(header.titleRes);
|
||||
}
|
||||
}
|
||||
|
||||
private void bindHeader(View view, int position, Header header) {
|
||||
final HeaderViewHolder holder;
|
||||
final Object tag = view.getTag();
|
||||
if (tag instanceof HeaderViewHolder) {
|
||||
holder = (HeaderViewHolder) tag;
|
||||
} else {
|
||||
holder = new HeaderViewHolder(view);
|
||||
view.setTag(holder);
|
||||
}
|
||||
final CharSequence title = header.getTitle(mResources);
|
||||
holder.title.setText(title);
|
||||
final CharSequence summary = header.getSummary(mResources);
|
||||
if (!TextUtils.isEmpty(summary)) {
|
||||
holder.summary.setVisibility(View.VISIBLE);
|
||||
holder.summary.setText(summary);
|
||||
} else {
|
||||
holder.summary.setVisibility(View.GONE);
|
||||
}
|
||||
if (header.iconRes != 0) {
|
||||
holder.icon.setImageResource(header.iconRes);
|
||||
} else {
|
||||
holder.icon.setImageDrawable(null);
|
||||
}
|
||||
holder.icon.setColorFilter(mActionIconColor, Mode.SRC_ATOP);
|
||||
}
|
||||
|
||||
private View inflateItemView(int viewType, ViewGroup parent) {
|
||||
final int layoutRes;
|
||||
switch (viewType) {
|
||||
case HEADER_TYPE_CATEGORY: {
|
||||
layoutRes = R.layout.list_item_preference_header_category;
|
||||
break;
|
||||
}
|
||||
case HEADER_TYPE_SPACE: {
|
||||
layoutRes = R.layout.list_item_preference_header_space;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
layoutRes = R.layout.list_item_preference_header_item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return mInflater.inflate(layoutRes, parent, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(final int position) {
|
||||
return getItemViewType(position) != HEADER_TYPE_CATEGORY;
|
||||
return getItemViewType(position) == HEADER_TYPE_NORMAL;
|
||||
}
|
||||
|
||||
private static int getHeaderType(final Header header) {
|
||||
if (header.fragment == null && header.intent == null)
|
||||
if (header.fragment != null || header.intent != null)
|
||||
return HEADER_TYPE_NORMAL;
|
||||
else if (header.title != null || header.titleRes != 0)
|
||||
return HEADER_TYPE_CATEGORY;
|
||||
else
|
||||
return HEADER_TYPE_NORMAL;
|
||||
return HEADER_TYPE_SPACE;
|
||||
|
||||
}
|
||||
|
||||
private static class HeaderViewHolder extends ViewHolder {
|
||||
|
@ -801,7 +801,7 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
|
||||
final Window window = getWindow();
|
||||
final Drawable windowBackground = ThemeUtils.getWindowBackground(this, getCurrentThemeResourceId());
|
||||
ViewAccessor.setBackground(mSlidingMenu.getContent(), windowBackground);
|
||||
window.setBackgroundDrawable(new EmptyDrawable());
|
||||
window.setBackgroundDrawable(new EmptyDrawable(windowBackground));
|
||||
}
|
||||
|
||||
private void showDataProfilingRequest() {
|
||||
@ -918,6 +918,8 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
|
||||
if (fragment instanceof AccountsDashboardFragment) {
|
||||
((AccountsDashboardFragment) fragment).setStatusBarHeight(insets.top);
|
||||
}
|
||||
//TODO
|
||||
mColorStatusFrameLayout.setStatusBarHeight(insets.top);
|
||||
}
|
||||
|
||||
|
||||
|
@ -203,13 +203,25 @@ public class LinkHandlerActivity extends BaseSupportActivity implements OnClickL
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
window.addFlags(LayoutParams.FLAG_TRANSLUCENT_STATUS);
|
||||
}
|
||||
final int transitionRes;
|
||||
switch (linkId) {
|
||||
case LINK_ID_USER: {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && !ThemeUtils.isTransparentBackground(this)) {
|
||||
Utils.setSharedElementTransition(this, window, R.transition.transition_user_profile);
|
||||
}
|
||||
transitionRes = R.transition.transition_user;
|
||||
break;
|
||||
}
|
||||
case LINK_ID_STATUS: {
|
||||
// transitionRes = R.transition.transition_status;
|
||||
transitionRes = 0;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
transitionRes = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (transitionRes != 0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
|
||||
&& !ThemeUtils.isTransparentBackground(this)) {
|
||||
Utils.setSharedElementTransition(this, window, R.transition.transition_status);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,27 +1,39 @@
|
||||
package org.mariotaku.twidere.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.util.Pair;
|
||||
import android.support.v7.widget.RecyclerView.Adapter;
|
||||
import android.support.v7.widget.RecyclerView.ViewHolder;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.iface.IStatusesAdapter;
|
||||
import org.mariotaku.twidere.app.TwidereApplication;
|
||||
import org.mariotaku.twidere.view.holder.LoadIndicatorViewHolder;
|
||||
import org.mariotaku.twidere.fragment.support.StatusFragment;
|
||||
import org.mariotaku.twidere.fragment.support.StatusMenuDialogFragment;
|
||||
import org.mariotaku.twidere.fragment.support.UserFragment;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
||||
import org.mariotaku.twidere.util.ImageLoadingHandler;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.view.holder.GapViewHolder;
|
||||
import org.mariotaku.twidere.view.holder.LoadIndicatorViewHolder;
|
||||
import org.mariotaku.twidere.view.holder.StatusViewHolder;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/11/19.
|
||||
*/
|
||||
public abstract class AbsStatusesAdapter extends Adapter<ViewHolder> implements IStatusesAdapter {
|
||||
* Created by mariotaku on 14/11/19.
|
||||
*/
|
||||
public abstract class AbsStatusesAdapter<D> extends Adapter<ViewHolder> implements Constants,
|
||||
IStatusesAdapter<D> {
|
||||
|
||||
private static final int ITEM_VIEW_TYPE_STATUS = 1;
|
||||
private static final int ITEM_VIEW_TYPE_LOAD_INDICATOR = 2;
|
||||
private static final int ITEM_VIEW_TYPE_GAP = 2;
|
||||
private static final int ITEM_VIEW_TYPE_LOAD_INDICATOR = 3;
|
||||
|
||||
private final Context mContext;
|
||||
private final LayoutInflater mInflater;
|
||||
@ -30,7 +42,7 @@ public abstract class AbsStatusesAdapter extends Adapter<ViewHolder> implements
|
||||
private final int mCardLayoutResource;
|
||||
private boolean mLoadMoreIndicatorEnabled;
|
||||
|
||||
public AbsStatusesAdapter(Context context, boolean compact) {
|
||||
public AbsStatusesAdapter(Context context, boolean compact) {
|
||||
mContext = context;
|
||||
mInflater = LayoutInflater.from(context);
|
||||
mImageLoader = TwidereApplication.getInstance(context).getImageLoaderWrapper();
|
||||
@ -47,7 +59,11 @@ public abstract class AbsStatusesAdapter extends Adapter<ViewHolder> implements
|
||||
switch (viewType) {
|
||||
case ITEM_VIEW_TYPE_STATUS: {
|
||||
final View view = mInflater.inflate(mCardLayoutResource, parent, false);
|
||||
return new StatusViewHolder(this, view);
|
||||
return new StatusViewHolder<>(this, view);
|
||||
}
|
||||
case ITEM_VIEW_TYPE_GAP: {
|
||||
final View view = mInflater.inflate(R.layout.card_item_gap, parent, false);
|
||||
return new GapViewHolder(this, view);
|
||||
}
|
||||
case ITEM_VIEW_TYPE_LOAD_INDICATOR: {
|
||||
final View view = mInflater.inflate(R.layout.card_item_load_indicator, parent, false);
|
||||
@ -83,6 +99,8 @@ public abstract class AbsStatusesAdapter extends Adapter<ViewHolder> implements
|
||||
public int getItemViewType(int position) {
|
||||
if (position == getItemCount() - 1) {
|
||||
return ITEM_VIEW_TYPE_LOAD_INDICATOR;
|
||||
} else if (isGapItem(position)) {
|
||||
return ITEM_VIEW_TYPE_GAP;
|
||||
}
|
||||
return ITEM_VIEW_TYPE_STATUS;
|
||||
}
|
||||
@ -107,5 +125,46 @@ public abstract class AbsStatusesAdapter extends Adapter<ViewHolder> implements
|
||||
return mLoadingHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusClick(StatusViewHolder holder, int position) {
|
||||
final Context context = getContext();
|
||||
// final View cardView = holder.getCardView();
|
||||
// if (cardView != null && context instanceof FragmentActivity) {
|
||||
// final Bundle options = Utils.makeSceneTransitionOption((FragmentActivity) context,
|
||||
// new Pair<>(cardView, StatusFragment.TRANSITION_NAME_CARD));
|
||||
// Utils.openStatus(context, getStatus(position), options);
|
||||
// } else {
|
||||
Utils.openStatus(context, getStatus(position), null);
|
||||
// }
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserProfileClick(StatusViewHolder holder, int position) {
|
||||
final Context context = getContext();
|
||||
final ParcelableStatus status = getStatus(position);
|
||||
final View profileImageView = holder.getProfileImageView();
|
||||
if (context instanceof FragmentActivity) {
|
||||
final Bundle options = Utils.makeSceneTransitionOption((FragmentActivity) context,
|
||||
new Pair<>(profileImageView, UserFragment.TRANSITION_NAME_PROFILE_IMAGE));
|
||||
Utils.openUserProfile(context, status.account_id, status.user_id, status.user_screen_name, options);
|
||||
} else {
|
||||
Utils.openUserProfile(context, status.account_id, status.user_id, status.user_screen_name, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemMenuClick(StatusViewHolder holder, int position) {
|
||||
final Context context = getContext();
|
||||
if (!(context instanceof FragmentActivity)) return;
|
||||
final Bundle args = new Bundle();
|
||||
args.putParcelable(EXTRA_STATUS, getStatus(position));
|
||||
final StatusMenuDialogFragment f = new StatusMenuDialogFragment();
|
||||
f.setArguments(args);
|
||||
f.show(((FragmentActivity) context).getSupportFragmentManager(), "status_menu");
|
||||
}
|
||||
|
||||
public abstract void setData(D data);
|
||||
|
||||
public abstract D getData();
|
||||
|
||||
}
|
||||
|
@ -19,12 +19,6 @@
|
||||
|
||||
package org.mariotaku.twidere.adapter;
|
||||
|
||||
import static org.mariotaku.twidere.util.Utils.configBaseCardAdapter;
|
||||
import static org.mariotaku.twidere.util.Utils.getAccountColor;
|
||||
import static org.mariotaku.twidere.util.Utils.getDisplayName;
|
||||
import static org.mariotaku.twidere.util.Utils.isCompactCards;
|
||||
import static org.mariotaku.twidere.util.Utils.isPlainListStyle;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@ -42,196 +36,195 @@ import org.mariotaku.twidere.view.holder.ActivityListViewHolder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.mariotaku.twidere.util.Utils.configBaseCardAdapter;
|
||||
import static org.mariotaku.twidere.util.Utils.getAccountColor;
|
||||
import static org.mariotaku.twidere.util.Utils.getDisplayName;
|
||||
import static org.mariotaku.twidere.util.Utils.isCompactCards;
|
||||
|
||||
public abstract class BaseParcelableActivitiesAdapter extends BaseArrayAdapter<ParcelableActivity> implements
|
||||
IBaseCardAdapter {
|
||||
IBaseCardAdapter {
|
||||
|
||||
private final MultiSelectManager mMultiSelectManager;
|
||||
private final ImageLoaderWrapper mImageLoader;
|
||||
private final MultiSelectManager mMultiSelectManager;
|
||||
private final ImageLoaderWrapper mImageLoader;
|
||||
|
||||
private boolean mShowAbsoluteTime, mAnimationEnabled;
|
||||
private int mMaxAnimationPosition;
|
||||
private boolean mShowAbsoluteTime, mAnimationEnabled;
|
||||
private int mMaxAnimationPosition;
|
||||
|
||||
private MenuButtonClickListener mListener;
|
||||
private final boolean mPlainList;
|
||||
private MenuButtonClickListener mListener;
|
||||
|
||||
public BaseParcelableActivitiesAdapter(final Context context) {
|
||||
this(context, isCompactCards(context), isPlainListStyle(context));
|
||||
}
|
||||
public BaseParcelableActivitiesAdapter(final Context context) {
|
||||
this(context, isCompactCards(context));
|
||||
}
|
||||
|
||||
public BaseParcelableActivitiesAdapter(final Context context, final boolean compactCards, final boolean plainList) {
|
||||
super(context, getItemResource(compactCards));
|
||||
mPlainList = plainList;
|
||||
final TwidereApplication app = TwidereApplication.getInstance(context);
|
||||
mMultiSelectManager = app.getMultiSelectManager();
|
||||
mImageLoader = app.getImageLoaderWrapper();
|
||||
configBaseCardAdapter(context, this);
|
||||
}
|
||||
public BaseParcelableActivitiesAdapter(final Context context, final boolean compactCards) {
|
||||
super(context, getItemResource(compactCards));
|
||||
final TwidereApplication app = TwidereApplication.getInstance(context);
|
||||
mMultiSelectManager = app.getMultiSelectManager();
|
||||
mImageLoader = app.getImageLoaderWrapper();
|
||||
configBaseCardAdapter(context, this);
|
||||
}
|
||||
|
||||
public abstract void bindView(final int position, final ActivityListViewHolder holder, final ParcelableActivity item);
|
||||
public abstract void bindView(final int position, final ActivityListViewHolder holder, final ParcelableActivity item);
|
||||
|
||||
@Override
|
||||
public ImageLoaderWrapper getImageLoader() {
|
||||
return mImageLoader;
|
||||
}
|
||||
@Override
|
||||
public ImageLoaderWrapper getImageLoader() {
|
||||
return mImageLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(final int position) {
|
||||
final Object obj = getItem(position);
|
||||
return obj != null ? obj.hashCode() : 0;
|
||||
}
|
||||
@Override
|
||||
public long getItemId(final int position) {
|
||||
final Object obj = getItem(position);
|
||||
return obj != null ? obj.hashCode() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(final int position, final View convertView, final ViewGroup parent) {
|
||||
final View view = super.getView(position, convertView, parent);
|
||||
final Object tag = view.getTag();
|
||||
final ActivityListViewHolder holder = tag instanceof ActivityListViewHolder ? (ActivityListViewHolder) tag
|
||||
: new ActivityListViewHolder(view);
|
||||
if (!(tag instanceof ActivityListViewHolder)) {
|
||||
if (mPlainList) {
|
||||
((View) holder.content).setPadding(0, 0, 0, 0);
|
||||
holder.content.setItemBackground(null);
|
||||
}
|
||||
view.setTag(holder);
|
||||
}
|
||||
@Override
|
||||
public View getView(final int position, final View convertView, final ViewGroup parent) {
|
||||
final View view = super.getView(position, convertView, parent);
|
||||
final Object tag = view.getTag();
|
||||
final ActivityListViewHolder holder = tag instanceof ActivityListViewHolder ? (ActivityListViewHolder) tag
|
||||
: new ActivityListViewHolder(view);
|
||||
if (!(tag instanceof ActivityListViewHolder)) {
|
||||
view.setTag(holder);
|
||||
}
|
||||
|
||||
final boolean showAccountColor = isShowAccountColor();
|
||||
final boolean showAccountColor = isShowAccountColor();
|
||||
|
||||
holder.setTextSize(getTextSize());
|
||||
holder.my_profile_image.setVisibility(View.GONE);
|
||||
final ParcelableActivity item = getItem(position);
|
||||
holder.setAccountColorEnabled(showAccountColor);
|
||||
if (showAccountColor) {
|
||||
holder.setAccountColor(getAccountColor(getContext(), item.account_id));
|
||||
}
|
||||
if (mShowAbsoluteTime) {
|
||||
holder.time.setTime(item.activity_timestamp);
|
||||
} else {
|
||||
holder.time.setTime(item.activity_timestamp);
|
||||
}
|
||||
bindView(position, holder, item);
|
||||
return view;
|
||||
}
|
||||
holder.setTextSize(getTextSize());
|
||||
holder.my_profile_image.setVisibility(View.GONE);
|
||||
final ParcelableActivity item = getItem(position);
|
||||
holder.setAccountColorEnabled(showAccountColor);
|
||||
if (showAccountColor) {
|
||||
holder.setAccountColor(getAccountColor(getContext(), item.account_id));
|
||||
}
|
||||
if (mShowAbsoluteTime) {
|
||||
holder.time.setTime(item.activity_timestamp);
|
||||
} else {
|
||||
holder.time.setTime(item.activity_timestamp);
|
||||
}
|
||||
bindView(position, holder, item);
|
||||
return view;
|
||||
}
|
||||
|
||||
public void onItemSelected(final Object item) {
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
public void onItemSelected(final Object item) {
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void onItemUnselected(final Object item) {
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
public void onItemUnselected(final Object item) {
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
public void setData(final List<ParcelableActivity> data) {
|
||||
clear();
|
||||
if (data == null) return;
|
||||
addAll(data);
|
||||
}
|
||||
public void setData(final List<ParcelableActivity> data) {
|
||||
clear();
|
||||
if (data == null) return;
|
||||
addAll(data);
|
||||
}
|
||||
|
||||
@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) {
|
||||
mListener = listener;
|
||||
}
|
||||
@Override
|
||||
public void setMenuButtonClickListener(final MenuButtonClickListener listener) {
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
public void setShowAbsoluteTime(final boolean show) {
|
||||
if (show != mShowAbsoluteTime) {
|
||||
mShowAbsoluteTime = show;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
public void setShowAbsoluteTime(final boolean show) {
|
||||
if (show != mShowAbsoluteTime) {
|
||||
mShowAbsoluteTime = show;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
protected void displayActivityUserProfileImages(final ActivityListViewHolder holder, final ParcelableStatus[] statuses) {
|
||||
if (statuses == null) {
|
||||
displayActivityUserProfileImages(holder, new String[0]);
|
||||
} else {
|
||||
final String[] urls = new String[statuses.length];
|
||||
for (int i = 0, j = statuses.length; i < j; i++) {
|
||||
urls[i] = statuses[i].user_profile_image_url;
|
||||
}
|
||||
displayActivityUserProfileImages(holder, urls);
|
||||
}
|
||||
}
|
||||
protected void displayActivityUserProfileImages(final ActivityListViewHolder holder, final ParcelableStatus[] statuses) {
|
||||
if (statuses == null) {
|
||||
displayActivityUserProfileImages(holder, new String[0]);
|
||||
} else {
|
||||
final String[] urls = new String[statuses.length];
|
||||
for (int i = 0, j = statuses.length; i < j; i++) {
|
||||
urls[i] = statuses[i].user_profile_image_url;
|
||||
}
|
||||
displayActivityUserProfileImages(holder, urls);
|
||||
}
|
||||
}
|
||||
|
||||
protected void displayActivityUserProfileImages(final ActivityListViewHolder holder, final ParcelableUser[] users) {
|
||||
if (users == null) {
|
||||
displayActivityUserProfileImages(holder, new String[0]);
|
||||
} else {
|
||||
final String[] urls = new String[users.length];
|
||||
for (int i = 0, j = users.length; i < j; i++) {
|
||||
urls[i] = users[i].profile_image_url;
|
||||
}
|
||||
displayActivityUserProfileImages(holder, urls);
|
||||
}
|
||||
}
|
||||
protected void displayActivityUserProfileImages(final ActivityListViewHolder holder, final ParcelableUser[] users) {
|
||||
if (users == null) {
|
||||
displayActivityUserProfileImages(holder, new String[0]);
|
||||
} else {
|
||||
final String[] urls = new String[users.length];
|
||||
for (int i = 0, j = users.length; i < j; i++) {
|
||||
urls[i] = users[i].profile_image_url;
|
||||
}
|
||||
displayActivityUserProfileImages(holder, urls);
|
||||
}
|
||||
}
|
||||
|
||||
protected void displayProfileImage(final ImageView view, final ParcelableUser user) {
|
||||
if (isDisplayProfileImage()) {
|
||||
mImageLoader.displayProfileImage(view, user.profile_image_url);
|
||||
} else {
|
||||
view.setImageDrawable(null);
|
||||
}
|
||||
}
|
||||
protected void displayProfileImage(final ImageView view, final ParcelableUser user) {
|
||||
if (isDisplayProfileImage()) {
|
||||
mImageLoader.displayProfileImage(view, user.profile_image_url);
|
||||
} else {
|
||||
view.setImageDrawable(null);
|
||||
}
|
||||
}
|
||||
|
||||
protected String getName(final ParcelableStatus status) {
|
||||
if (status == null) return null;
|
||||
return getDisplayName(getContext(), status.user_id, status.user_name, status.user_screen_name,
|
||||
isDisplayNameFirst(), isNicknameOnly());
|
||||
}
|
||||
protected String getName(final ParcelableStatus status) {
|
||||
if (status == null) return null;
|
||||
return getDisplayName(getContext(), status.user_id, status.user_name, status.user_screen_name,
|
||||
isDisplayNameFirst(), isNicknameOnly());
|
||||
}
|
||||
|
||||
protected String getName(final ParcelableUser user) {
|
||||
if (user == null) return null;
|
||||
return getDisplayName(getContext(), user.id, user.name, user.screen_name, isDisplayNameFirst(),
|
||||
isNicknameOnly());
|
||||
}
|
||||
protected String getName(final ParcelableUser user) {
|
||||
if (user == null) return null;
|
||||
return getDisplayName(getContext(), user.id, user.name, user.screen_name, isDisplayNameFirst(),
|
||||
isNicknameOnly());
|
||||
}
|
||||
|
||||
protected void setProfileImage(final ImageView view, final ParcelableStatus status) {
|
||||
if (isDisplayProfileImage()) {
|
||||
mImageLoader.displayProfileImage(view, status.user_profile_image_url);
|
||||
} else {
|
||||
view.setImageDrawable(null);
|
||||
}
|
||||
}
|
||||
protected void setProfileImage(final ImageView view, final ParcelableStatus status) {
|
||||
if (isDisplayProfileImage()) {
|
||||
mImageLoader.displayProfileImage(view, status.user_profile_image_url);
|
||||
} else {
|
||||
view.setImageDrawable(null);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean shouldDisplayProfileImage() {
|
||||
return isDisplayProfileImage();
|
||||
}
|
||||
protected boolean shouldDisplayProfileImage() {
|
||||
return isDisplayProfileImage();
|
||||
}
|
||||
|
||||
private void displayActivityUserProfileImages(final ActivityListViewHolder holder, final String[] urls) {
|
||||
final int length = urls != null ? Math.min(holder.activity_profile_images.length, urls.length) : 0;
|
||||
final boolean shouldDisplayImages = isDisplayProfileImage() && length > 0;
|
||||
holder.activity_profile_images_container.setVisibility(shouldDisplayImages ? View.VISIBLE : View.GONE);
|
||||
if (!shouldDisplayImages) return;
|
||||
for (int i = 0, j = holder.activity_profile_images.length; i < j; i++) {
|
||||
final ImageView view = holder.activity_profile_images[i];
|
||||
view.setImageDrawable(null);
|
||||
if (i < length) {
|
||||
view.setVisibility(View.VISIBLE);
|
||||
mImageLoader.displayProfileImage(view, urls[i]);
|
||||
} else {
|
||||
private void displayActivityUserProfileImages(final ActivityListViewHolder holder, final String[] urls) {
|
||||
final int length = urls != null ? Math.min(holder.activity_profile_images.length, urls.length) : 0;
|
||||
final boolean shouldDisplayImages = isDisplayProfileImage() && length > 0;
|
||||
holder.activity_profile_images_container.setVisibility(shouldDisplayImages ? View.VISIBLE : View.GONE);
|
||||
if (!shouldDisplayImages) return;
|
||||
for (int i = 0, j = holder.activity_profile_images.length; i < j; i++) {
|
||||
final ImageView view = holder.activity_profile_images[i];
|
||||
view.setImageDrawable(null);
|
||||
if (i < length) {
|
||||
view.setVisibility(View.VISIBLE);
|
||||
mImageLoader.displayProfileImage(view, urls[i]);
|
||||
} else {
|
||||
mImageLoader.cancelDisplayTask(view);
|
||||
view.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
if (urls.length > holder.activity_profile_images.length) {
|
||||
final int moreNumber = urls.length - holder.activity_profile_images.length;
|
||||
holder.activity_profile_image_more_number.setVisibility(View.VISIBLE);
|
||||
holder.activity_profile_image_more_number.setText(getContext().getString(R.string.and_more, moreNumber));
|
||||
} else {
|
||||
holder.activity_profile_image_more_number.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
view.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
if (urls.length > holder.activity_profile_images.length) {
|
||||
final int moreNumber = urls.length - holder.activity_profile_images.length;
|
||||
holder.activity_profile_image_more_number.setVisibility(View.VISIBLE);
|
||||
holder.activity_profile_image_more_number.setText(getContext().getString(R.string.and_more, moreNumber));
|
||||
} else {
|
||||
holder.activity_profile_image_more_number.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private static int getItemResource(final boolean compactCards) {
|
||||
return compactCards ? R.layout.card_item_activity_compact : R.layout.card_item_activity;
|
||||
}
|
||||
private static int getItemResource(final boolean compactCards) {
|
||||
return compactCards ? R.layout.card_item_activity_compact : R.layout.card_item_activity;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,517 +1,85 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* 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.adapter;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.util.Pair;
|
||||
import android.text.Html;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView.ScaleType;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.iface.IStatusesListAdapter;
|
||||
import org.mariotaku.twidere.app.TwidereApplication;
|
||||
import org.mariotaku.twidere.fragment.support.UserFragment;
|
||||
import org.mariotaku.twidere.model.ParcelableMedia;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.model.ParcelableUserMention;
|
||||
import org.mariotaku.twidere.provider.TweetStore.Statuses;
|
||||
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
||||
import org.mariotaku.twidere.util.ImageLoadingHandler;
|
||||
import org.mariotaku.twidere.util.MultiSelectManager;
|
||||
import org.mariotaku.twidere.util.TwidereLinkify;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.view.holder.StatusListViewHolder;
|
||||
import org.mariotaku.twidere.view.iface.ICardItemView.OnOverflowIconClickListener;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus.CursorIndices;
|
||||
import org.mariotaku.twidere.view.holder.StatusViewHolder;
|
||||
|
||||
import java.util.Locale;
|
||||
/**
|
||||
* Created by mariotaku on 14/11/19.
|
||||
*/
|
||||
public class CursorStatusesAdapter extends AbsStatusesAdapter<Cursor> {
|
||||
|
||||
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.findStatusInDatabases;
|
||||
import static org.mariotaku.twidere.util.Utils.getAccountColor;
|
||||
import static org.mariotaku.twidere.util.Utils.getCardHighlightColor;
|
||||
import static org.mariotaku.twidere.util.Utils.getCardHighlightOptionInt;
|
||||
import static org.mariotaku.twidere.util.Utils.isFiltered;
|
||||
import static org.mariotaku.twidere.util.Utils.openImage;
|
||||
import static org.mariotaku.twidere.util.Utils.openUserProfile;
|
||||
private Cursor mCursor;
|
||||
private CursorIndices mIndices;
|
||||
|
||||
public class CursorStatusesAdapter extends BaseCursorAdapter implements IStatusesListAdapter<Cursor>, OnClickListener,
|
||||
OnOverflowIconClickListener {
|
||||
|
||||
public static final String[] CURSOR_COLS = Statuses.COLUMNS;
|
||||
|
||||
private final Context mContext;
|
||||
private final ImageLoaderWrapper mImageLoader;
|
||||
private final MultiSelectManager mMultiSelectManager;
|
||||
private final SQLiteDatabase mDatabase;
|
||||
private final ImageLoadingHandler mImageLoadingHandler;
|
||||
|
||||
private MenuButtonClickListener mListener;
|
||||
|
||||
private final boolean mPlainList;
|
||||
|
||||
private boolean mDisplayImagePreview, mGapDisallowed, mMentionsHighlightDisabled, mFavoritesHighlightDisabled,
|
||||
mDisplaySensitiveContents, mIndicateMyStatusDisabled, mIsLastItemFiltered, mFiltersEnabled,
|
||||
mAnimationEnabled;
|
||||
private boolean mFilterIgnoreUser, mFilterIgnoreSource, mFilterIgnoreTextHtml, mFilterIgnoreTextPlain,
|
||||
mFilterRetweetedById;
|
||||
private int mMaxAnimationPosition, mCardHighlightOption;
|
||||
|
||||
private ParcelableStatus.CursorIndices mIndices;
|
||||
|
||||
private ScaleType mImagePreviewScaleType;
|
||||
|
||||
public CursorStatusesAdapter(final Context context) {
|
||||
this(context, Utils.isCompactCards(context), Utils.isPlainListStyle(context));
|
||||
}
|
||||
|
||||
public CursorStatusesAdapter(final Context context, final boolean compactCards, final boolean plainList) {
|
||||
super(context, getItemResource(compactCards), null, new String[0], new int[0], 0);
|
||||
mPlainList = plainList;
|
||||
mContext = context;
|
||||
final TwidereApplication application = TwidereApplication.getInstance(context);
|
||||
mMultiSelectManager = application.getMultiSelectManager();
|
||||
mImageLoader = application.getImageLoaderWrapper();
|
||||
mDatabase = application.getSQLiteDatabase();
|
||||
mImageLoadingHandler = new ImageLoadingHandler();
|
||||
configBaseCardAdapter(context, this);
|
||||
setMaxAnimationPosition(-1);
|
||||
public CursorStatusesAdapter(Context context, boolean compact) {
|
||||
super(context, compact);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindView(final View view, final Context context, final Cursor cursor) {
|
||||
final int position = cursor.getPosition();
|
||||
final StatusListViewHolder holder = (StatusListViewHolder) view.getTag();
|
||||
public boolean isGapItem(int position) {
|
||||
final Cursor c = mCursor;
|
||||
return c != null && c.moveToPosition(position) && c.getInt(mIndices.is_gap) == 1;
|
||||
}
|
||||
|
||||
final boolean isGap = cursor.getShort(mIndices.is_gap) == 1;
|
||||
final boolean showGap = isGap && !mGapDisallowed && position != getCount() - 1;
|
||||
@Override
|
||||
protected void bindStatus(StatusViewHolder holder, int position) {
|
||||
mCursor.moveToPosition(position);
|
||||
holder.displayStatus(mCursor, mIndices);
|
||||
}
|
||||
|
||||
holder.setShowAsGap(showGap);
|
||||
holder.position = position;
|
||||
holder.setDisplayProfileImage(isDisplayProfileImage());
|
||||
holder.setCardHighlightOption(mCardHighlightOption);
|
||||
|
||||
if (!showGap) {
|
||||
|
||||
// Clear images in prder to prevent images in recycled view shown.
|
||||
|
||||
final Resources res = mContext.getResources();
|
||||
final TwidereLinkify linkify = getLinkify();
|
||||
final boolean showAccountColor = isShowAccountColor();
|
||||
|
||||
final long accountId = cursor.getLong(mIndices.account_id);
|
||||
final long userId = cursor.getLong(mIndices.user_id);
|
||||
final long timestamp = cursor.getLong(mIndices.status_timestamp);
|
||||
final long retweetTimestamp = cursor.getLong(mIndices.retweet_timestamp);
|
||||
final long retweetCount = cursor.getLong(mIndices.retweet_count);
|
||||
final long retweetedByUserId = cursor.getLong(mIndices.retweeted_by_user_id);
|
||||
final long inReplyToUserId = cursor.getLong(mIndices.in_reply_to_user_id);
|
||||
|
||||
final String retweetedByName = cursor.getString(mIndices.retweeted_by_user_name);
|
||||
final String retweetedByScreenName = cursor.getString(mIndices.retweeted_by_user_screen_name);
|
||||
final String text = getLinkHighlightOption() != VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE ? cursor
|
||||
.getString(mIndices.text_html) : cursor.getString(mIndices.text_unescaped);
|
||||
final String screen_name = cursor.getString(mIndices.user_screen_name);
|
||||
final String name = cursor.getString(mIndices.user_name);
|
||||
final String inReplyToName = cursor.getString(mIndices.in_reply_to_user_name);
|
||||
final String inReplyToScreenName = cursor.getString(mIndices.in_reply_to_user_screen_name);
|
||||
final ParcelableMedia[] media = ParcelableMedia.fromJSONString(cursor.getString(mIndices.media));
|
||||
final String firstMedia = media != null && media.length > 0 ? media[0].media_url : null;
|
||||
|
||||
// Tweet type (favorite/location/media)
|
||||
final boolean isFavorite = cursor.getShort(mIndices.is_favorite) == 1;
|
||||
final boolean hasLocation = !TextUtils.isEmpty(cursor.getString(mIndices.location));
|
||||
final boolean possiblySensitive = cursor.getInt(mIndices.is_possibly_sensitive) == 1;
|
||||
final boolean hasMedia = media != null && media.length > 0;
|
||||
|
||||
// User type (protected/verified)
|
||||
final boolean isVerified = cursor.getShort(mIndices.is_verified) == 1;
|
||||
final boolean isProtected = cursor.getShort(mIndices.is_protected) == 1;
|
||||
|
||||
final boolean isRetweet = cursor.getShort(mIndices.is_retweet) == 1;
|
||||
final boolean isReply = cursor.getLong(mIndices.in_reply_to_status_id) > 0;
|
||||
final boolean isMention = ParcelableUserMention.hasMention(cursor.getString(mIndices.mentions), accountId);
|
||||
final boolean isMyStatus = accountId == userId;
|
||||
|
||||
holder.setUserColor(getUserColor(mContext, userId));
|
||||
if (isRetweet) {
|
||||
holder.setUserColor(getUserColor(mContext, userId), getUserColor(mContext, retweetedByUserId));
|
||||
} else {
|
||||
holder.setUserColor(getUserColor(mContext, userId));
|
||||
}
|
||||
holder.setHighlightColor(getCardHighlightColor(res, !mMentionsHighlightDisabled && isMention,
|
||||
!mFavoritesHighlightDisabled && isFavorite, isRetweet));
|
||||
|
||||
holder.setAccountColorEnabled(showAccountColor);
|
||||
|
||||
if (showAccountColor) {
|
||||
holder.setAccountColor(getAccountColor(mContext, accountId));
|
||||
}
|
||||
|
||||
holder.setTextSize(getTextSize());
|
||||
|
||||
holder.setIsMyStatus(isMyStatus && !mIndicateMyStatusDisabled);
|
||||
if (getLinkHighlightOption() != VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE) {
|
||||
holder.text.setText(Html.fromHtml(text));
|
||||
linkify.applyAllLinks(holder.text, accountId, possiblySensitive);
|
||||
holder.text.setMovementMethod(null);
|
||||
} else {
|
||||
holder.text.setText(text);
|
||||
}
|
||||
holder.setUserType(isVerified, isProtected);
|
||||
holder.setDisplayNameFirst(isDisplayNameFirst());
|
||||
holder.setNicknameOnly(isNicknameOnly());
|
||||
final String nick = getUserNickname(context, userId);
|
||||
holder.name.setText(TextUtils.isEmpty(nick) ? name : isNicknameOnly() ? nick : context.getString(
|
||||
R.string.name_with_nickname, name, nick));
|
||||
holder.screen_name.setText("@" + screen_name);
|
||||
if (getLinkHighlightOption() != VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE) {
|
||||
linkify.applyUserProfileLinkNoHighlight(holder.name, accountId, userId, screen_name);
|
||||
linkify.applyUserProfileLinkNoHighlight(holder.screen_name, accountId, userId, screen_name);
|
||||
holder.name.setMovementMethod(null);
|
||||
holder.screen_name.setMovementMethod(null);
|
||||
}
|
||||
holder.time.setTime(retweetTimestamp > 0 ? retweetTimestamp : timestamp);
|
||||
holder.setStatusType(!mFavoritesHighlightDisabled && isFavorite, hasLocation, hasMedia, possiblySensitive);
|
||||
|
||||
holder.setIsReplyRetweet(isReply, isRetweet);
|
||||
if (isRetweet) {
|
||||
holder.setRetweetedBy(retweetCount, retweetedByUserId, retweetedByName, retweetedByScreenName);
|
||||
} else if (isReply) {
|
||||
holder.setReplyTo(inReplyToUserId, inReplyToName, inReplyToScreenName);
|
||||
}
|
||||
|
||||
if (isDisplayProfileImage()) {
|
||||
final String profile_image_url = cursor.getString(mIndices.user_profile_image_url);
|
||||
mImageLoader.displayProfileImage(holder.my_profile_image, profile_image_url);
|
||||
mImageLoader.displayProfileImage(holder.profile_image, profile_image_url);
|
||||
holder.profile_image.setTag(position);
|
||||
holder.my_profile_image.setTag(position);
|
||||
} else {
|
||||
mImageLoader.cancelDisplayTask(holder.profile_image);
|
||||
mImageLoader.cancelDisplayTask(holder.my_profile_image);
|
||||
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 && firstMedia != null && media != null) {
|
||||
if (mImagePreviewScaleType != null) {
|
||||
holder.image_preview.setScaleType(mImagePreviewScaleType);
|
||||
}
|
||||
if (possiblySensitive && !mDisplaySensitiveContents) {
|
||||
holder.image_preview.setImageDrawable(null);
|
||||
holder.image_preview.setBackgroundResource(R.drawable.image_preview_nsfw);
|
||||
holder.image_preview_progress.setVisibility(View.GONE);
|
||||
mImageLoader.cancelDisplayTask(holder.image_preview);
|
||||
} else if (!firstMedia.equals(mImageLoadingHandler.getLoadingUri(holder.image_preview))) {
|
||||
holder.image_preview.setBackgroundResource(0);
|
||||
mImageLoader.displayPreviewImage(holder.image_preview, firstMedia, mImageLoadingHandler);
|
||||
}
|
||||
final int count = media.length;
|
||||
holder.image_preview_count.setText(res.getQuantityString(R.plurals.N_media, count, count));
|
||||
holder.image_preview.setTag(position);
|
||||
} else {
|
||||
mImageLoader.cancelDisplayTask(holder.image_preview);
|
||||
}
|
||||
} else {
|
||||
mImageLoader.cancelDisplayTask(holder.profile_image);
|
||||
mImageLoader.cancelDisplayTask(holder.my_profile_image);
|
||||
mImageLoader.cancelDisplayTask(holder.image_preview);
|
||||
@Override
|
||||
public ParcelableStatus getStatus(int position) {
|
||||
if (hasLoadMoreIndicator() && position == getStatusCount() - 1) return null;
|
||||
final Cursor c = mCursor;
|
||||
if (c != null && !c.isClosed() && c.moveToPosition(position)) {
|
||||
return new ParcelableStatus(c, mIndices);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int findPositionByStatusId(final long status_id) {
|
||||
final Cursor c = getCursor();
|
||||
if (c == null || c.isClosed()) return -1;
|
||||
for (int i = 0, count = c.getCount(); i < count; i++) {
|
||||
if (c.moveToPosition(i) && c.getLong(mIndices.status_id) == status_id) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getAccountId(final int position) {
|
||||
final Cursor c = getCursor();
|
||||
if (c == null || c.isClosed() || !c.moveToPosition(position)) return -1;
|
||||
return c.getLong(mIndices.account_id);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatusCount() {
|
||||
return super.getCount();
|
||||
if (mCursor == null) return 0;
|
||||
return mCursor.getCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
final int count = super.getCount();
|
||||
return mFiltersEnabled && mIsLastItemFiltered && count > 0 ? count - 1 : count;
|
||||
public void setData(Cursor data) {
|
||||
mCursor = data;
|
||||
mIndices = data != null ? new CursorIndices(data) : null;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelableStatus getLastStatus() {
|
||||
final Cursor c = getCursor();
|
||||
if (c == null || c.isClosed() || !c.moveToLast()) return null;
|
||||
final long account_id = c.getLong(mIndices.account_id);
|
||||
final long status_id = c.getLong(mIndices.status_id);
|
||||
return findStatusInDatabases(mContext, account_id, status_id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastStatusId() {
|
||||
final Cursor c = getCursor();
|
||||
try {
|
||||
if (c == null || c.isClosed() || !c.moveToLast()) return -1;
|
||||
return c.getLong(mIndices.status_id);
|
||||
} catch (final IllegalStateException e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context getContext() {
|
||||
return mContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageLoadingHandler getImageLoadingHandler() {
|
||||
return mImageLoadingHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelableStatus getStatus(final int position) {
|
||||
final Cursor c = getCursor();
|
||||
if (c == null || c.isClosed() || !c.moveToPosition(position)) return null;
|
||||
return new ParcelableStatus(c, mIndices);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getStatusId(final int position) {
|
||||
final Cursor c = getCursor();
|
||||
if (c == null || c.isClosed() || !c.moveToPosition(position)) return -1;
|
||||
return c.getLong(mIndices.status_id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(final int position, final View convertView, final ViewGroup parent) {
|
||||
final View view = super.getView(position, convertView, parent);
|
||||
final Object tag = view.getTag();
|
||||
// animate the item
|
||||
if (tag instanceof StatusListViewHolder && position > mMaxAnimationPosition) {
|
||||
if (mAnimationEnabled) {
|
||||
view.startAnimation(((StatusListViewHolder) tag).item_animation);
|
||||
}
|
||||
mMaxAnimationPosition = position;
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLastItemFiltered() {
|
||||
return mFiltersEnabled && mIsLastItemFiltered;
|
||||
}
|
||||
|
||||
@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 StatusListViewHolder)) {
|
||||
final StatusListViewHolder holder = new StatusListViewHolder(view);
|
||||
holder.profile_image.setOnClickListener(this);
|
||||
holder.my_profile_image.setOnClickListener(this);
|
||||
holder.image_preview.setOnClickListener(this);
|
||||
holder.content.setOnOverflowIconClickListener(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.image_preview: {
|
||||
final ParcelableStatus status = getStatus(position);
|
||||
if (status == null || status.first_media == null) return;
|
||||
openImage(mContext, status.account_id, status.first_media, status.is_possibly_sensitive);
|
||||
break;
|
||||
}
|
||||
case R.id.my_profile_image:
|
||||
case R.id.profile_image: {
|
||||
final ParcelableStatus status = getStatus(position);
|
||||
if (status == null) return;
|
||||
final Activity activity = (Activity) getContext();
|
||||
final Bundle options = Utils.makeSceneTransitionOption(activity,
|
||||
new Pair<>(view, UserFragment.TRANSITION_NAME_PROFILE_IMAGE));
|
||||
openUserProfile(mContext, status.account_id, status.user_id,
|
||||
status.user_screen_name, options);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOverflowIconClick(final View view) {
|
||||
if (mMultiSelectManager.isActive()) return;
|
||||
final Object tag = view.getTag();
|
||||
if (tag instanceof StatusListViewHolder) {
|
||||
final StatusListViewHolder holder = (StatusListViewHolder) tag;
|
||||
final int position = holder.position;
|
||||
if (position == -1 || mListener == null) return;
|
||||
mListener.onMenuButtonClick(view, position, getItemId(position));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAnimationEnabled(final boolean anim) {
|
||||
mAnimationEnabled = anim;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCardHighlightOption(final String option) {
|
||||
mCardHighlightOption = getCardHighlightOptionInt(option);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(final Cursor data) {
|
||||
swapCursor(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDisplayImagePreview(final boolean display) {
|
||||
mDisplayImagePreview = display;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDisplaySensitiveContents(final boolean display) {
|
||||
mDisplaySensitiveContents = display;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFavoritesHightlightDisabled(final boolean disable) {
|
||||
mFavoritesHighlightDisabled = disable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFiltersEnabled(final boolean enabled) {
|
||||
if (mFiltersEnabled == enabled) return;
|
||||
mFiltersEnabled = enabled;
|
||||
rebuildFilterInfo(getCursor(), mIndices);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGapDisallowed(final boolean disallowed) {
|
||||
mGapDisallowed = disallowed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHighlightKeyword(final String... keywords) {
|
||||
// TODO Auto-generated method stub
|
||||
public void onGapClick(StatusViewHolder holder, int position) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIgnoredFilterFields(final boolean user, final boolean textPlain, final boolean textHtml,
|
||||
final boolean source, final boolean retweetedById) {
|
||||
mFilterIgnoreTextPlain = textPlain;
|
||||
mFilterIgnoreTextHtml = textHtml;
|
||||
mFilterIgnoreUser = user;
|
||||
mFilterIgnoreSource = source;
|
||||
mFilterRetweetedById = retweetedById;
|
||||
rebuildFilterInfo(getCursor(), mIndices);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImagePreviewScaleType(final String scaleTypeString) {
|
||||
final ScaleType scaleType = ScaleType.valueOf(scaleTypeString.toUpperCase(Locale.US));
|
||||
mImagePreviewScaleType = scaleType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIndicateMyStatusDisabled(final boolean disable) {
|
||||
mIndicateMyStatusDisabled = disable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxAnimationPosition(final int position) {
|
||||
mMaxAnimationPosition = position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMentionsHightlightDisabled(final boolean disable) {
|
||||
mMentionsHighlightDisabled = disable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMenuButtonClickListener(final MenuButtonClickListener listener) {
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor swapCursor(final Cursor cursor) {
|
||||
mIndices = cursor != null ? new ParcelableStatus.CursorIndices(cursor) : null;
|
||||
rebuildFilterInfo(cursor, mIndices);
|
||||
return super.swapCursor(cursor);
|
||||
}
|
||||
|
||||
private void rebuildFilterInfo(final Cursor c, final ParcelableStatus.CursorIndices i) {
|
||||
if (i != null && c != null && moveCursorToLast(c)) {
|
||||
final long userId = mFilterIgnoreUser ? -1 : c.getLong(mIndices.user_id);
|
||||
final String textPlain = mFilterIgnoreTextPlain ? null : c.getString(mIndices.text_plain);
|
||||
final String textHtml = mFilterIgnoreTextHtml ? null : c.getString(mIndices.text_html);
|
||||
final String source = mFilterIgnoreSource ? null : c.getString(mIndices.source);
|
||||
final long retweetedById = mFilterRetweetedById ? -1 : c.getLong(mIndices.retweeted_by_user_id);
|
||||
mIsLastItemFiltered = isFiltered(mDatabase, userId, textPlain, textHtml, source, retweetedById);
|
||||
} else {
|
||||
mIsLastItemFiltered = false;
|
||||
}
|
||||
}
|
||||
|
||||
private static int getItemResource(final boolean compactCards) {
|
||||
return compactCards ? R.layout.card_item_status_compact : R.layout.card_item_status;
|
||||
}
|
||||
|
||||
private static boolean moveCursorToLast(final Cursor c) {
|
||||
if (c == null || c.isClosed()) return false;
|
||||
try {
|
||||
return c.moveToNext();
|
||||
} catch (final Exception e) {
|
||||
return false;
|
||||
}
|
||||
public Cursor getData() {
|
||||
return mCursor;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,370 @@
|
||||
/*
|
||||
* 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.adapter;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.util.Pair;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView.ScaleType;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.iface.IStatusesListAdapter;
|
||||
import org.mariotaku.twidere.app.TwidereApplication;
|
||||
import org.mariotaku.twidere.fragment.support.UserFragment;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.provider.TweetStore.Statuses;
|
||||
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
||||
import org.mariotaku.twidere.util.ImageLoadingHandler;
|
||||
import org.mariotaku.twidere.util.MultiSelectManager;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.view.holder.StatusViewHolder;
|
||||
import org.mariotaku.twidere.view.iface.ICardItemView.OnOverflowIconClickListener;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import static org.mariotaku.twidere.util.Utils.configBaseCardAdapter;
|
||||
import static org.mariotaku.twidere.util.Utils.findStatusInDatabases;
|
||||
import static org.mariotaku.twidere.util.Utils.getCardHighlightOptionInt;
|
||||
import static org.mariotaku.twidere.util.Utils.isFiltered;
|
||||
import static org.mariotaku.twidere.util.Utils.openImage;
|
||||
import static org.mariotaku.twidere.util.Utils.openUserProfile;
|
||||
|
||||
public class CursorStatusesListAdapter extends BaseCursorAdapter implements IStatusesListAdapter<Cursor>, OnClickListener,
|
||||
OnOverflowIconClickListener {
|
||||
|
||||
public static final String[] CURSOR_COLS = Statuses.COLUMNS;
|
||||
|
||||
private final Context mContext;
|
||||
private final ImageLoaderWrapper mImageLoader;
|
||||
private final MultiSelectManager mMultiSelectManager;
|
||||
private final SQLiteDatabase mDatabase;
|
||||
private final ImageLoadingHandler mImageLoadingHandler;
|
||||
|
||||
private MenuButtonClickListener mListener;
|
||||
|
||||
private boolean mDisplayImagePreview, mGapDisallowed, mMentionsHighlightDisabled, mFavoritesHighlightDisabled,
|
||||
mDisplaySensitiveContents, mIndicateMyStatusDisabled, mIsLastItemFiltered, mFiltersEnabled,
|
||||
mAnimationEnabled;
|
||||
private boolean mFilterIgnoreUser, mFilterIgnoreSource, mFilterIgnoreTextHtml, mFilterIgnoreTextPlain,
|
||||
mFilterRetweetedById;
|
||||
private int mMaxAnimationPosition, mCardHighlightOption;
|
||||
|
||||
private ParcelableStatus.CursorIndices mIndices;
|
||||
|
||||
private ScaleType mImagePreviewScaleType;
|
||||
|
||||
public CursorStatusesListAdapter(final Context context) {
|
||||
this(context, Utils.isCompactCards(context));
|
||||
}
|
||||
|
||||
public CursorStatusesListAdapter(final Context context, final boolean compactCards) {
|
||||
super(context, getItemResource(compactCards), null, new String[0], new int[0], 0);
|
||||
mContext = context;
|
||||
final TwidereApplication application = TwidereApplication.getInstance(context);
|
||||
mMultiSelectManager = application.getMultiSelectManager();
|
||||
mImageLoader = application.getImageLoaderWrapper();
|
||||
mDatabase = application.getSQLiteDatabase();
|
||||
mImageLoadingHandler = new ImageLoadingHandler();
|
||||
configBaseCardAdapter(context, this);
|
||||
setMaxAnimationPosition(-1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindView(final View view, final Context context, final Cursor cursor) {
|
||||
final StatusViewHolder holder = (StatusViewHolder) view.getTag();
|
||||
holder.displayStatus(cursor, mIndices);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int findPositionByStatusId(final long status_id) {
|
||||
final Cursor c = getCursor();
|
||||
if (c == null || c.isClosed()) return -1;
|
||||
for (int i = 0, count = c.getCount(); i < count; i++) {
|
||||
if (c.moveToPosition(i) && c.getLong(mIndices.status_id) == status_id) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getAccountId(final int position) {
|
||||
final Cursor c = getCursor();
|
||||
if (c == null || c.isClosed() || !c.moveToPosition(position)) return -1;
|
||||
return c.getLong(mIndices.account_id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatusCount() {
|
||||
return super.getCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemMenuClick(StatusViewHolder holder, int position) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusClick(StatusViewHolder holder, int position) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserProfileClick(StatusViewHolder holder, int position) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
final int count = super.getCount();
|
||||
return mFiltersEnabled && mIsLastItemFiltered && count > 0 ? count - 1 : count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelableStatus getLastStatus() {
|
||||
final Cursor c = getCursor();
|
||||
if (c == null || c.isClosed() || !c.moveToLast()) return null;
|
||||
final long account_id = c.getLong(mIndices.account_id);
|
||||
final long status_id = c.getLong(mIndices.status_id);
|
||||
return findStatusInDatabases(mContext, account_id, status_id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastStatusId() {
|
||||
final Cursor c = getCursor();
|
||||
try {
|
||||
if (c == null || c.isClosed() || !c.moveToLast()) return -1;
|
||||
return c.getLong(mIndices.status_id);
|
||||
} catch (final IllegalStateException e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context getContext() {
|
||||
return mContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageLoadingHandler getImageLoadingHandler() {
|
||||
return mImageLoadingHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelableStatus getStatus(final int position) {
|
||||
final Cursor c = getCursor();
|
||||
if (c == null || c.isClosed() || !c.moveToPosition(position)) return null;
|
||||
return new ParcelableStatus(c, mIndices);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getStatusId(final int position) {
|
||||
final Cursor c = getCursor();
|
||||
if (c == null || c.isClosed() || !c.moveToPosition(position)) return -1;
|
||||
return c.getLong(mIndices.status_id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGapItem(int position) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLastItemFiltered() {
|
||||
return mFiltersEnabled && mIsLastItemFiltered;
|
||||
}
|
||||
|
||||
@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 StatusViewHolder)) {
|
||||
final StatusViewHolder holder = new StatusViewHolder(this, view);
|
||||
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.image_preview: {
|
||||
final ParcelableStatus status = getStatus(position);
|
||||
if (status == null || status.first_media == null) return;
|
||||
openImage(mContext, status.account_id, status.first_media, status.is_possibly_sensitive);
|
||||
break;
|
||||
}
|
||||
case R.id.my_profile_image:
|
||||
case R.id.profile_image: {
|
||||
final ParcelableStatus status = getStatus(position);
|
||||
if (status == null) return;
|
||||
final Activity activity = (Activity) getContext();
|
||||
final Bundle options = Utils.makeSceneTransitionOption(activity,
|
||||
new Pair<>(view, UserFragment.TRANSITION_NAME_PROFILE_IMAGE));
|
||||
openUserProfile(mContext, status.account_id, status.user_id,
|
||||
status.user_screen_name, options);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOverflowIconClick(final View view) {
|
||||
if (mMultiSelectManager.isActive()) return;
|
||||
final Object tag = view.getTag();
|
||||
if (tag instanceof StatusViewHolder) {
|
||||
final StatusViewHolder holder = (StatusViewHolder) tag;
|
||||
final int position = holder.getPosition();
|
||||
if (position == -1 || mListener == null) return;
|
||||
mListener.onMenuButtonClick(view, position, getItemId(position));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAnimationEnabled(final boolean anim) {
|
||||
mAnimationEnabled = anim;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCardHighlightOption(final String option) {
|
||||
mCardHighlightOption = getCardHighlightOptionInt(option);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(final Cursor data) {
|
||||
swapCursor(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDisplayImagePreview(final boolean display) {
|
||||
mDisplayImagePreview = display;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDisplaySensitiveContents(final boolean display) {
|
||||
mDisplaySensitiveContents = display;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFavoritesHightlightDisabled(final boolean disable) {
|
||||
mFavoritesHighlightDisabled = disable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFiltersEnabled(final boolean enabled) {
|
||||
if (mFiltersEnabled == enabled) return;
|
||||
mFiltersEnabled = enabled;
|
||||
rebuildFilterInfo(getCursor(), mIndices);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGapDisallowed(final boolean disallowed) {
|
||||
mGapDisallowed = disallowed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHighlightKeyword(final String... keywords) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIgnoredFilterFields(final boolean user, final boolean textPlain, final boolean textHtml,
|
||||
final boolean source, final boolean retweetedById) {
|
||||
mFilterIgnoreTextPlain = textPlain;
|
||||
mFilterIgnoreTextHtml = textHtml;
|
||||
mFilterIgnoreUser = user;
|
||||
mFilterIgnoreSource = source;
|
||||
mFilterRetweetedById = retweetedById;
|
||||
rebuildFilterInfo(getCursor(), mIndices);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImagePreviewScaleType(final String scaleTypeString) {
|
||||
final ScaleType scaleType = ScaleType.valueOf(scaleTypeString.toUpperCase(Locale.US));
|
||||
mImagePreviewScaleType = scaleType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIndicateMyStatusDisabled(final boolean disable) {
|
||||
mIndicateMyStatusDisabled = disable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxAnimationPosition(final int position) {
|
||||
mMaxAnimationPosition = position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMentionsHightlightDisabled(final boolean disable) {
|
||||
mMentionsHighlightDisabled = disable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMenuButtonClickListener(final MenuButtonClickListener listener) {
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor swapCursor(final Cursor cursor) {
|
||||
mIndices = cursor != null ? new ParcelableStatus.CursorIndices(cursor) : null;
|
||||
rebuildFilterInfo(cursor, mIndices);
|
||||
return super.swapCursor(cursor);
|
||||
}
|
||||
|
||||
private void rebuildFilterInfo(final Cursor c, final ParcelableStatus.CursorIndices i) {
|
||||
if (i != null && c != null && moveCursorToLast(c)) {
|
||||
final long userId = mFilterIgnoreUser ? -1 : c.getLong(mIndices.user_id);
|
||||
final String textPlain = mFilterIgnoreTextPlain ? null : c.getString(mIndices.text_plain);
|
||||
final String textHtml = mFilterIgnoreTextHtml ? null : c.getString(mIndices.text_html);
|
||||
final String source = mFilterIgnoreSource ? null : c.getString(mIndices.source);
|
||||
final long retweetedById = mFilterRetweetedById ? -1 : c.getLong(mIndices.retweeted_by_user_id);
|
||||
mIsLastItemFiltered = isFiltered(mDatabase, userId, textPlain, textHtml, source, retweetedById);
|
||||
} else {
|
||||
mIsLastItemFiltered = false;
|
||||
}
|
||||
}
|
||||
|
||||
private static int getItemResource(final boolean compactCards) {
|
||||
return compactCards ? R.layout.card_item_list_status_compat : R.layout.card_item_list_status;
|
||||
}
|
||||
|
||||
private static boolean moveCursorToLast(final Cursor c) {
|
||||
if (c == null || c.isClosed()) return false;
|
||||
try {
|
||||
return c.moveToNext();
|
||||
} catch (final Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGapClick(StatusViewHolder holder, int position) {
|
||||
|
||||
}
|
||||
}
|
@ -58,16 +58,12 @@ public class DirectMessageConversationEntriesAdapter extends BaseCursorAdapter i
|
||||
private boolean mAnimationEnabled;
|
||||
private int mMaxAnimationPosition;
|
||||
|
||||
private final boolean mPlainList;
|
||||
|
||||
public DirectMessageConversationEntriesAdapter(final Context context) {
|
||||
this(context, Utils.isCompactCards(context), Utils.isPlainListStyle(context));
|
||||
this(context, Utils.isCompactCards(context));
|
||||
}
|
||||
|
||||
public DirectMessageConversationEntriesAdapter(final Context context, final boolean compactCards,
|
||||
final boolean plainList) {
|
||||
public DirectMessageConversationEntriesAdapter(final Context context, final boolean compactCards) {
|
||||
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();
|
||||
@ -148,10 +144,6 @@ public class DirectMessageConversationEntriesAdapter extends BaseCursorAdapter i
|
||||
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;
|
||||
|
@ -50,8 +50,8 @@ public class ParcelableActivitiesAboutMeAdapter extends BaseParcelableActivities
|
||||
private boolean mDisplayImagePreview;
|
||||
private boolean mDisplaySensitiveContents;
|
||||
|
||||
public ParcelableActivitiesAboutMeAdapter(final Context context, final boolean compactCards, final boolean plainList) {
|
||||
super(context, compactCards, plainList);
|
||||
public ParcelableActivitiesAboutMeAdapter(final Context context, final boolean compactCards) {
|
||||
super(context, compactCards);
|
||||
mImageLoadingHandler = new ImageLoadingHandler();
|
||||
}
|
||||
|
||||
|
@ -34,140 +34,139 @@ import org.mariotaku.twidere.view.holder.ActivityListViewHolder;
|
||||
|
||||
public class ParcelableActivitiesByFriendsAdapter extends BaseParcelableActivitiesAdapter {
|
||||
|
||||
public ParcelableActivitiesByFriendsAdapter(final Context context, final boolean compactCards,
|
||||
final boolean plainList) {
|
||||
super(context, compactCards, plainList);
|
||||
}
|
||||
public ParcelableActivitiesByFriendsAdapter(final Context context, final boolean compactCards) {
|
||||
super(context, compactCards);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindView(final int position, final ActivityListViewHolder holder, final ParcelableActivity item) {
|
||||
if (item == null) return;
|
||||
final ParcelableUser[] sources = item.sources;
|
||||
final ParcelableStatus[] targetStatuses = item.target_statuses;
|
||||
final ParcelableUser[] targetUsers = item.target_users;
|
||||
final ParcelableStatus[] target_object_statuses = item.target_object_statuses;
|
||||
final ParcelableUserList[] targetUserLists = item.target_user_lists;
|
||||
final ParcelableUserList[] target_object_user_lists = item.target_object_user_lists;
|
||||
final int sourcesLength = sources != null ? sources.length : 0;
|
||||
final int targetStatusesLength = targetStatuses != null ? targetStatuses.length : 0;
|
||||
final int target_users_length = targetUsers != null ? targetUsers.length : 0;
|
||||
final int target_object_user_lists_length = target_object_user_lists != null ? target_object_user_lists.length
|
||||
: 0;
|
||||
final int target_user_lists_length = targetUserLists != null ? targetUserLists.length : 0;
|
||||
final int action = item.action;
|
||||
final Context context = getContext();
|
||||
@Override
|
||||
public void bindView(final int position, final ActivityListViewHolder holder, final ParcelableActivity item) {
|
||||
if (item == null) return;
|
||||
final ParcelableUser[] sources = item.sources;
|
||||
final ParcelableStatus[] targetStatuses = item.target_statuses;
|
||||
final ParcelableUser[] targetUsers = item.target_users;
|
||||
final ParcelableStatus[] target_object_statuses = item.target_object_statuses;
|
||||
final ParcelableUserList[] targetUserLists = item.target_user_lists;
|
||||
final ParcelableUserList[] target_object_user_lists = item.target_object_user_lists;
|
||||
final int sourcesLength = sources != null ? sources.length : 0;
|
||||
final int targetStatusesLength = targetStatuses != null ? targetStatuses.length : 0;
|
||||
final int target_users_length = targetUsers != null ? targetUsers.length : 0;
|
||||
final int target_object_user_lists_length = target_object_user_lists != null ? target_object_user_lists.length
|
||||
: 0;
|
||||
final int target_user_lists_length = targetUserLists != null ? targetUserLists.length : 0;
|
||||
final int action = item.action;
|
||||
final Context context = getContext();
|
||||
|
||||
final TwidereLinkify linkify = getLinkify();
|
||||
final int highlightOption = getLinkHighlightOption();
|
||||
final TwidereLinkify linkify = getLinkify();
|
||||
final int highlightOption = getLinkHighlightOption();
|
||||
|
||||
holder.name.setSingleLine(false);
|
||||
holder.screen_name.setVisibility(View.GONE);
|
||||
holder.reply_retweet_status.setVisibility(View.GONE);
|
||||
if (holder.divider != null) {
|
||||
holder.divider.setVisibility(View.VISIBLE);
|
||||
}
|
||||
if (sources != null && sources.length != 0) {
|
||||
final ParcelableUser firstSource = sources[0];
|
||||
final String firstSourceName = getName(firstSource);
|
||||
switch (action) {
|
||||
case ParcelableActivity.ACTION_FAVORITE: {
|
||||
if (targetStatuses == null || targetStatuses.length == 0) return;
|
||||
final ParcelableStatus status = targetStatuses[0];
|
||||
if (targetStatusesLength == 1) {
|
||||
holder.text.setVisibility(View.VISIBLE);
|
||||
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);
|
||||
}
|
||||
holder.name.setText(context.getString(R.string.activity_by_friends_favorite, firstSourceName,
|
||||
getName(status)));
|
||||
} else {
|
||||
holder.text.setVisibility(View.GONE);
|
||||
holder.name.setText(context.getString(R.string.activity_by_friends_favorite_multi,
|
||||
firstSourceName, getName(status), targetStatusesLength - 1));
|
||||
}
|
||||
displayProfileImage(holder.profile_image, firstSource);
|
||||
displayActivityUserProfileImages(holder, targetStatuses);
|
||||
break;
|
||||
}
|
||||
case ParcelableActivity.ACTION_FOLLOW: {
|
||||
holder.text.setVisibility(View.GONE);
|
||||
if (targetUsers == null || targetUsers.length == 0) return;
|
||||
if (targetUsers.length == 1) {
|
||||
holder.name.setText(context.getString(R.string.activity_by_friends_follow, firstSourceName,
|
||||
getName(targetUsers[0])));
|
||||
} else {
|
||||
holder.name.setText(context.getString(R.string.activity_by_friends_follow_multi,
|
||||
firstSourceName, getName(targetUsers[0]), target_users_length - 1));
|
||||
}
|
||||
displayProfileImage(holder.profile_image, firstSource);
|
||||
displayActivityUserProfileImages(holder, targetUsers);
|
||||
break;
|
||||
}
|
||||
case ParcelableActivity.ACTION_RETWEET: {
|
||||
holder.text.setVisibility(View.VISIBLE);
|
||||
if (target_object_statuses != null && target_object_statuses.length > 0) {
|
||||
final ParcelableStatus status = target_object_statuses[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 (sourcesLength == 1) {
|
||||
holder.name.setText(context.getString(R.string.activity_by_friends_retweet, firstSourceName,
|
||||
getName(targetStatuses[0])));
|
||||
} else {
|
||||
holder.name.setText(context.getString(R.string.activity_about_me_retweet_multi,
|
||||
firstSourceName, sourcesLength - 1));
|
||||
}
|
||||
displayActivityUserProfileImages(holder, sources);
|
||||
break;
|
||||
}
|
||||
case ParcelableActivity.ACTION_LIST_MEMBER_ADDED: {
|
||||
holder.text.setVisibility(View.GONE);
|
||||
if (target_object_user_lists_length == 1) {
|
||||
holder.name.setText(context.getString(R.string.activity_by_friends_list_member_added,
|
||||
firstSourceName, getName(targetUsers[0])));
|
||||
} else {
|
||||
holder.name.setText(context.getString(R.string.activity_about_me_list_member_added_multi,
|
||||
firstSourceName, sourcesLength - 1));
|
||||
}
|
||||
displayProfileImage(holder.profile_image, firstSource);
|
||||
displayActivityUserProfileImages(holder, targetUsers);
|
||||
break;
|
||||
}
|
||||
case ParcelableActivity.ACTION_LIST_CREATED: {
|
||||
if (target_user_lists_length == 0) return;
|
||||
holder.activity_profile_images_container.setVisibility(View.GONE);
|
||||
final ParcelableUserList userList = targetUserLists[0];
|
||||
if (target_user_lists_length == 1) {
|
||||
if (!TextUtils.isEmpty(userList.description)) {
|
||||
holder.text.setVisibility(View.VISIBLE);
|
||||
holder.text.setText(userList.description);
|
||||
} else {
|
||||
if (holder.divider != null) {
|
||||
holder.divider.setVisibility(View.GONE);
|
||||
}
|
||||
holder.text.setVisibility(View.GONE);
|
||||
}
|
||||
holder.name.setText(context.getString(R.string.activity_by_friends_list_created,
|
||||
firstSourceName, userList.name));
|
||||
} else {
|
||||
holder.text.setVisibility(View.GONE);
|
||||
holder.name.setText(context.getString(R.string.activity_by_friends_list_created_multi,
|
||||
firstSourceName, userList.name, target_user_lists_length - 1));
|
||||
}
|
||||
displayProfileImage(holder.profile_image, firstSource);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
holder.name.setSingleLine(false);
|
||||
holder.screen_name.setVisibility(View.GONE);
|
||||
holder.reply_retweet_status.setVisibility(View.GONE);
|
||||
if (holder.divider != null) {
|
||||
holder.divider.setVisibility(View.VISIBLE);
|
||||
}
|
||||
if (sources != null && sources.length != 0) {
|
||||
final ParcelableUser firstSource = sources[0];
|
||||
final String firstSourceName = getName(firstSource);
|
||||
switch (action) {
|
||||
case ParcelableActivity.ACTION_FAVORITE: {
|
||||
if (targetStatuses == null || targetStatuses.length == 0) return;
|
||||
final ParcelableStatus status = targetStatuses[0];
|
||||
if (targetStatusesLength == 1) {
|
||||
holder.text.setVisibility(View.VISIBLE);
|
||||
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);
|
||||
}
|
||||
holder.name.setText(context.getString(R.string.activity_by_friends_favorite, firstSourceName,
|
||||
getName(status)));
|
||||
} else {
|
||||
holder.text.setVisibility(View.GONE);
|
||||
holder.name.setText(context.getString(R.string.activity_by_friends_favorite_multi,
|
||||
firstSourceName, getName(status), targetStatusesLength - 1));
|
||||
}
|
||||
displayProfileImage(holder.profile_image, firstSource);
|
||||
displayActivityUserProfileImages(holder, targetStatuses);
|
||||
break;
|
||||
}
|
||||
case ParcelableActivity.ACTION_FOLLOW: {
|
||||
holder.text.setVisibility(View.GONE);
|
||||
if (targetUsers == null || targetUsers.length == 0) return;
|
||||
if (targetUsers.length == 1) {
|
||||
holder.name.setText(context.getString(R.string.activity_by_friends_follow, firstSourceName,
|
||||
getName(targetUsers[0])));
|
||||
} else {
|
||||
holder.name.setText(context.getString(R.string.activity_by_friends_follow_multi,
|
||||
firstSourceName, getName(targetUsers[0]), target_users_length - 1));
|
||||
}
|
||||
displayProfileImage(holder.profile_image, firstSource);
|
||||
displayActivityUserProfileImages(holder, targetUsers);
|
||||
break;
|
||||
}
|
||||
case ParcelableActivity.ACTION_RETWEET: {
|
||||
holder.text.setVisibility(View.VISIBLE);
|
||||
if (target_object_statuses != null && target_object_statuses.length > 0) {
|
||||
final ParcelableStatus status = target_object_statuses[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 (sourcesLength == 1) {
|
||||
holder.name.setText(context.getString(R.string.activity_by_friends_retweet, firstSourceName,
|
||||
getName(targetStatuses[0])));
|
||||
} else {
|
||||
holder.name.setText(context.getString(R.string.activity_about_me_retweet_multi,
|
||||
firstSourceName, sourcesLength - 1));
|
||||
}
|
||||
displayActivityUserProfileImages(holder, sources);
|
||||
break;
|
||||
}
|
||||
case ParcelableActivity.ACTION_LIST_MEMBER_ADDED: {
|
||||
holder.text.setVisibility(View.GONE);
|
||||
if (target_object_user_lists_length == 1) {
|
||||
holder.name.setText(context.getString(R.string.activity_by_friends_list_member_added,
|
||||
firstSourceName, getName(targetUsers[0])));
|
||||
} else {
|
||||
holder.name.setText(context.getString(R.string.activity_about_me_list_member_added_multi,
|
||||
firstSourceName, sourcesLength - 1));
|
||||
}
|
||||
displayProfileImage(holder.profile_image, firstSource);
|
||||
displayActivityUserProfileImages(holder, targetUsers);
|
||||
break;
|
||||
}
|
||||
case ParcelableActivity.ACTION_LIST_CREATED: {
|
||||
if (target_user_lists_length == 0) return;
|
||||
holder.activity_profile_images_container.setVisibility(View.GONE);
|
||||
final ParcelableUserList userList = targetUserLists[0];
|
||||
if (target_user_lists_length == 1) {
|
||||
if (!TextUtils.isEmpty(userList.description)) {
|
||||
holder.text.setVisibility(View.VISIBLE);
|
||||
holder.text.setText(userList.description);
|
||||
} else {
|
||||
if (holder.divider != null) {
|
||||
holder.divider.setVisibility(View.GONE);
|
||||
}
|
||||
holder.text.setVisibility(View.GONE);
|
||||
}
|
||||
holder.name.setText(context.getString(R.string.activity_by_friends_list_created,
|
||||
firstSourceName, userList.name));
|
||||
} else {
|
||||
holder.text.setVisibility(View.GONE);
|
||||
holder.name.setText(context.getString(R.string.activity_by_friends_list_created_multi,
|
||||
firstSourceName, userList.name, target_user_lists_length - 1));
|
||||
}
|
||||
displayProfileImage(holder.profile_image, firstSource);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import java.util.List;
|
||||
/**
|
||||
* Created by mariotaku on 14/11/19.
|
||||
*/
|
||||
public class ParcelableStatusesAdapter extends AbsStatusesAdapter {
|
||||
public class ParcelableStatusesAdapter extends AbsStatusesAdapter<List<ParcelableStatus>> {
|
||||
|
||||
private List<ParcelableStatus> mData;
|
||||
|
||||
@ -18,6 +18,16 @@ public class ParcelableStatusesAdapter extends AbsStatusesAdapter {
|
||||
super(context, compact);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGapItem(int position) {
|
||||
return getStatus(position).is_gap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGapClick(StatusViewHolder holder, int position) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindStatus(StatusViewHolder holder, int position) {
|
||||
holder.displayStatus(getStatus(position));
|
||||
@ -43,4 +53,5 @@ public class ParcelableStatusesAdapter extends AbsStatusesAdapter {
|
||||
public List<ParcelableStatus> getData() {
|
||||
return mData;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -21,10 +21,7 @@ package org.mariotaku.twidere.adapter;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.text.Html;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
@ -34,24 +31,17 @@ import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.iface.IStatusesListAdapter;
|
||||
import org.mariotaku.twidere.app.TwidereApplication;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.model.ParcelableUserMention;
|
||||
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
||||
import org.mariotaku.twidere.util.ImageLoadingHandler;
|
||||
import org.mariotaku.twidere.util.MultiSelectManager;
|
||||
import org.mariotaku.twidere.util.TwidereLinkify;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.view.holder.StatusListViewHolder;
|
||||
import org.mariotaku.twidere.view.holder.StatusViewHolder;
|
||||
import org.mariotaku.twidere.view.iface.ICardItemView.OnOverflowIconClickListener;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static org.mariotaku.twidere.model.ParcelableLocation.isValidLocation;
|
||||
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.getCardHighlightColor;
|
||||
import static org.mariotaku.twidere.util.Utils.getCardHighlightOptionInt;
|
||||
import static org.mariotaku.twidere.util.Utils.isFiltered;
|
||||
import static org.mariotaku.twidere.util.Utils.openImage;
|
||||
@ -67,7 +57,6 @@ public class ParcelableStatusesListAdapter extends BaseArrayAdapter<ParcelableSt
|
||||
|
||||
private MenuButtonClickListener mListener;
|
||||
|
||||
private final boolean mPlainList;
|
||||
|
||||
private boolean mDisplayImagePreview, mGapDisallowed, mMentionsHighlightDisabled, mFavoritesHighlightDisabled,
|
||||
mDisplaySensitiveContents, mIndicateMyStatusDisabled, mIsLastItemFiltered, mFiltersEnabled,
|
||||
@ -79,12 +68,11 @@ public class ParcelableStatusesListAdapter extends BaseArrayAdapter<ParcelableSt
|
||||
private String[] mHighlightKeywords;
|
||||
|
||||
public ParcelableStatusesListAdapter(final Context context) {
|
||||
this(context, Utils.isCompactCards(context), Utils.isPlainListStyle(context));
|
||||
this(context, Utils.isCompactCards(context));
|
||||
}
|
||||
|
||||
public ParcelableStatusesListAdapter(final Context context, final boolean compactCards, final boolean plainList) {
|
||||
public ParcelableStatusesListAdapter(final Context context, final boolean compactCards) {
|
||||
super(context, getItemResource(compactCards));
|
||||
mPlainList = plainList;
|
||||
mContext = context;
|
||||
final TwidereApplication app = TwidereApplication.getInstance(context);
|
||||
mMultiSelectManager = app.getMultiSelectManager();
|
||||
@ -116,6 +104,21 @@ public class ParcelableStatusesListAdapter extends BaseArrayAdapter<ParcelableSt
|
||||
return super.getCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemMenuClick(StatusViewHolder holder, int position) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusClick(StatusViewHolder holder, int position) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserProfileClick(StatusViewHolder holder, int position) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
final int count = super.getCount();
|
||||
@ -163,143 +166,28 @@ public class ParcelableStatusesListAdapter extends BaseArrayAdapter<ParcelableSt
|
||||
public View getView(final int position, final View convertView, final ViewGroup parent) {
|
||||
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;
|
||||
final StatusViewHolder holder;
|
||||
if (tag instanceof StatusViewHolder) {
|
||||
holder = (StatusViewHolder) tag;
|
||||
} else {
|
||||
holder = new StatusListViewHolder(view);
|
||||
holder.profile_image.setOnClickListener(this);
|
||||
holder.my_profile_image.setOnClickListener(this);
|
||||
holder.image_preview.setOnClickListener(this);
|
||||
holder.content.setOnOverflowIconClickListener(this);
|
||||
if (mPlainList) {
|
||||
((View) holder.content).setPadding(0, 0, 0, 0);
|
||||
holder.content.setItemBackground(null);
|
||||
}
|
||||
holder = new StatusViewHolder(this, view);
|
||||
view.setTag(holder);
|
||||
}
|
||||
|
||||
final ParcelableStatus status = getItem(position);
|
||||
|
||||
final boolean showGap = status.is_gap && !mGapDisallowed && position != getCount() - 1;
|
||||
|
||||
holder.position = position;
|
||||
holder.setShowAsGap(showGap);
|
||||
holder.setDisplayProfileImage(isDisplayProfileImage());
|
||||
holder.setCardHighlightOption(mCardHighlightOption);
|
||||
|
||||
final ImageLoaderWrapper loader = getImageLoader();
|
||||
if (!showGap) {
|
||||
final TwidereLinkify linkify = getLinkify();
|
||||
final int highlightOption = getLinkHighlightOption();
|
||||
final boolean mShowAccountColor = isShowAccountColor();
|
||||
|
||||
holder.setAccountColorEnabled(mShowAccountColor);
|
||||
|
||||
if (highlightOption != VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE) {
|
||||
holder.text.setText(Utils.getKeywordBoldedText(Html.fromHtml(status.text_html), mHighlightKeywords));
|
||||
linkify.applyAllLinks(holder.text, status.account_id, status.is_possibly_sensitive);
|
||||
holder.text.setMovementMethod(null);
|
||||
} else {
|
||||
if (mHighlightKeywords == null || mHighlightKeywords.length == 0) {
|
||||
holder.text.setText(status.text_unescaped);
|
||||
} else {
|
||||
holder.text.setText(Utils.getKeywordBoldedText(status.text_unescaped, mHighlightKeywords));
|
||||
}
|
||||
}
|
||||
|
||||
if (mShowAccountColor) {
|
||||
holder.setAccountColor(getAccountColor(mContext, status.account_id));
|
||||
}
|
||||
|
||||
final boolean isMention = ParcelableUserMention.hasMention(status.mentions, status.account_id);
|
||||
final boolean isMyStatus = status.account_id == status.user_id;
|
||||
final boolean hasMedia = status.first_media != null;
|
||||
if (status.is_retweet) {
|
||||
holder.setUserColor(getUserColor(mContext, status.user_id),
|
||||
getUserColor(mContext, status.retweeted_by_id));
|
||||
} else {
|
||||
holder.setUserColor(getUserColor(mContext, status.user_id));
|
||||
}
|
||||
holder.setHighlightColor(getCardHighlightColor(res,
|
||||
!mMentionsHighlightDisabled && isMention,
|
||||
!mFavoritesHighlightDisabled && status.is_favorite, status.is_retweet));
|
||||
holder.setTextSize(getTextSize());
|
||||
|
||||
holder.setIsMyStatus(isMyStatus && !mIndicateMyStatusDisabled);
|
||||
|
||||
holder.setUserType(status.user_is_verified, status.user_is_protected);
|
||||
holder.setDisplayNameFirst(isDisplayNameFirst());
|
||||
holder.setNicknameOnly(isNicknameOnly());
|
||||
final String nick = getUserNickname(mContext, status.user_id);
|
||||
holder.name.setText(TextUtils.isEmpty(nick) ? status.user_name : isNicknameOnly() ? nick : mContext
|
||||
.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.retweet_timestamp > 0 ? status.retweet_timestamp : status.timestamp);
|
||||
holder.setStatusType(!mFavoritesHighlightDisabled && status.is_favorite, 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 (isDisplayProfileImage()) {
|
||||
loader.displayProfileImage(holder.my_profile_image, status.user_profile_image_url);
|
||||
loader.displayProfileImage(holder.profile_image, status.user_profile_image_url);
|
||||
holder.profile_image.setTag(position);
|
||||
holder.my_profile_image.setTag(position);
|
||||
} else {
|
||||
loader.cancelDisplayTask(holder.profile_image);
|
||||
loader.cancelDisplayTask(holder.my_profile_image);
|
||||
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 (mImagePreviewScaleType != null) {
|
||||
holder.image_preview.setScaleType(mImagePreviewScaleType);
|
||||
}
|
||||
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);
|
||||
loader.displayPreviewImage(holder.image_preview, status.first_media, mImageLoadingHandler);
|
||||
}
|
||||
final int count = status.media.length;
|
||||
holder.image_preview_count.setText(res.getQuantityString(R.plurals.N_media, count, count));
|
||||
holder.image_preview.setTag(position);
|
||||
} else {
|
||||
loader.cancelDisplayTask(holder.image_preview);
|
||||
}
|
||||
} else {
|
||||
loader.cancelDisplayTask(holder.profile_image);
|
||||
loader.cancelDisplayTask(holder.my_profile_image);
|
||||
loader.cancelDisplayTask(holder.image_preview);
|
||||
}
|
||||
if (position > mMaxAnimationPosition) {
|
||||
if (mAnimationEnabled) {
|
||||
view.startAnimation(holder.item_animation);
|
||||
}
|
||||
mMaxAnimationPosition = position;
|
||||
}
|
||||
holder.displayStatus(status);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGapItem(int position) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGapClick(StatusViewHolder holder, int position) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLastItemFiltered() {
|
||||
return mIsLastItemFiltered;
|
||||
@ -447,6 +335,7 @@ public class ParcelableStatusesListAdapter extends BaseArrayAdapter<ParcelableSt
|
||||
}
|
||||
|
||||
private static int getItemResource(final boolean compactCards) {
|
||||
return compactCards ? R.layout.card_item_status_compact : R.layout.card_item_status;
|
||||
return compactCards ? R.layout.card_item_list_status_compat : R.layout.card_item_list_status;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -56,15 +56,13 @@ public class ParcelableUserListsAdapter extends BaseArrayAdapter<ParcelableUserL
|
||||
|
||||
private boolean mAnimationEnabled;
|
||||
private int mMaxAnimationPosition;
|
||||
private final boolean mPlainList;
|
||||
|
||||
public ParcelableUserListsAdapter(final Context context) {
|
||||
this(context, Utils.isCompactCards(context), Utils.isPlainListStyle(context));
|
||||
this(context, Utils.isCompactCards(context));
|
||||
}
|
||||
|
||||
public ParcelableUserListsAdapter(final Context context, final boolean compactCards, final boolean plainList) {
|
||||
public ParcelableUserListsAdapter(final Context context, final boolean compactCards) {
|
||||
super(context, getItemResource(compactCards));
|
||||
mPlainList = plainList;
|
||||
mContext = context;
|
||||
mLocale = context.getResources().getConfiguration().locale;
|
||||
final TwidereApplication app = TwidereApplication.getInstance(context);
|
||||
@ -93,10 +91,6 @@ public class ParcelableUserListsAdapter extends BaseArrayAdapter<ParcelableUserL
|
||||
holder = new UserListViewHolder(view);
|
||||
holder.profile_image.setOnClickListener(this);
|
||||
holder.content.setOnOverflowIconClickListener(this);
|
||||
if (mPlainList) {
|
||||
((View) holder.content).setPadding(0, 0, 0, 0);
|
||||
holder.content.setItemBackground(null);
|
||||
}
|
||||
view.setTag(holder);
|
||||
}
|
||||
|
||||
|
@ -53,18 +53,16 @@ public class ParcelableUsersAdapter extends BaseArrayAdapter<ParcelableUser> imp
|
||||
private MenuButtonClickListener mListener;
|
||||
|
||||
private final Locale mLocale;
|
||||
private final boolean mPlainList;
|
||||
|
||||
private boolean mAnimationEnabled;
|
||||
private int mMaxAnimationPosition;
|
||||
|
||||
public ParcelableUsersAdapter(final Context context) {
|
||||
this(context, Utils.isCompactCards(context), Utils.isPlainListStyle(context));
|
||||
this(context, Utils.isCompactCards(context));
|
||||
}
|
||||
|
||||
public ParcelableUsersAdapter(final Context context, final boolean compactCards, final boolean plainList) {
|
||||
public ParcelableUsersAdapter(final Context context, final boolean compactCards) {
|
||||
super(context, getItemResource(compactCards));
|
||||
mPlainList = plainList;
|
||||
mContext = context;
|
||||
mLocale = context.getResources().getConfiguration().locale;
|
||||
final TwidereApplication app = TwidereApplication.getInstance(context);
|
||||
@ -88,10 +86,6 @@ public class ParcelableUsersAdapter extends BaseArrayAdapter<ParcelableUser> imp
|
||||
} else {
|
||||
holder = new UserViewHolder(view);
|
||||
holder.content.setOnOverflowIconClickListener(this);
|
||||
if (mPlainList) {
|
||||
((View) holder.content).setPadding(0, 0, 0, 0);
|
||||
holder.content.setItemBackground(null);
|
||||
}
|
||||
view.setTag(holder);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.adapter.iface;
|
||||
|
||||
import android.support.v7.widget.RecyclerView.ViewHolder;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/12/3.
|
||||
*/
|
||||
public interface IGapSupportedAdapter<VH extends ViewHolder> {
|
||||
|
||||
boolean isGapItem(int position);
|
||||
|
||||
void onGapClick(VH holder, int position);
|
||||
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.adapter.iface;
|
||||
|
||||
import android.support.v7.widget.RecyclerView.ViewHolder;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/12/3.
|
||||
*/
|
||||
public interface IItemMenuSupportedAdapter<VH extends ViewHolder> {
|
||||
void onItemMenuClick(VH holder, int position);
|
||||
}
|
@ -5,11 +5,13 @@ import android.content.Context;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
||||
import org.mariotaku.twidere.util.ImageLoadingHandler;
|
||||
import org.mariotaku.twidere.view.holder.StatusViewHolder;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/11/18.
|
||||
*/
|
||||
public interface IStatusesAdapter {
|
||||
public interface IStatusesAdapter<Data> extends IGapSupportedAdapter<StatusViewHolder>,
|
||||
IItemMenuSupportedAdapter<StatusViewHolder> {
|
||||
|
||||
ImageLoaderWrapper getImageLoader();
|
||||
|
||||
@ -20,4 +22,10 @@ public interface IStatusesAdapter {
|
||||
ParcelableStatus getStatus(int position);
|
||||
|
||||
int getStatusCount();
|
||||
|
||||
void onStatusClick(StatusViewHolder holder, int position);
|
||||
|
||||
void onUserProfileClick(StatusViewHolder holder, int position);
|
||||
|
||||
void setData(Data data);
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ package org.mariotaku.twidere.adapter.iface;
|
||||
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
|
||||
public interface IStatusesListAdapter<Data> extends IBaseCardAdapter, IStatusesAdapter {
|
||||
public interface IStatusesListAdapter<Data> extends IBaseCardAdapter, IStatusesAdapter<Data> {
|
||||
|
||||
public int findPositionByStatusId(final long statusId);
|
||||
|
||||
@ -31,16 +31,12 @@ public interface IStatusesListAdapter<Data> extends IBaseCardAdapter, IStatusesA
|
||||
|
||||
public long getLastStatusId();
|
||||
|
||||
public ParcelableStatus getStatus(int position);
|
||||
|
||||
public long getStatusId(final int position);
|
||||
|
||||
public boolean isLastItemFiltered();
|
||||
|
||||
public void setCardHighlightOption(String option);
|
||||
|
||||
public void setData(Data data);
|
||||
|
||||
public void setDisplayImagePreview(boolean display);
|
||||
|
||||
public void setDisplaySensitiveContents(boolean display);
|
||||
|
@ -281,8 +281,6 @@ public interface SharedPreferenceConstants {
|
||||
@Preference(type = STRING, hasDefault = true, defaultString = "CENTER_CROP")
|
||||
public static final String KEY_IMAGE_PREVIEW_SCALE_TYPE = "image_preview_scale_type";
|
||||
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false)
|
||||
public static final String KEY_PLAIN_LIST_STYLE = "plain_list_style";
|
||||
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false)
|
||||
public static final String KEY_SORT_TIMELINE_BY_ID = "sort_timeline_by_id";
|
||||
|
||||
public static final String KEY_QUICK_MENU_EXPANDED = "quick_menu_expanded";
|
||||
|
@ -0,0 +1,187 @@
|
||||
package org.mariotaku.twidere.fragment.support;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.support.v4.widget.SwipeRefreshLayout;
|
||||
import android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener;
|
||||
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.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.AbsStatusesAdapter;
|
||||
import org.mariotaku.twidere.adapter.decorator.DividerItemDecoration;
|
||||
import org.mariotaku.twidere.util.SimpleDrawerCallback;
|
||||
import org.mariotaku.twidere.util.ThemeUtils;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.view.HeaderDrawerLayout.DrawerCallback;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/11/5.
|
||||
*/
|
||||
public abstract class AbsStatusesFragment<Data> extends BaseSupportFragment
|
||||
implements LoaderCallbacks<Data>, OnRefreshListener, DrawerCallback {
|
||||
|
||||
private View mContentView;
|
||||
private SharedPreferences mPreferences;
|
||||
|
||||
@Override
|
||||
public void fling(float velocity) {
|
||||
mDrawerCallback.fling(velocity);
|
||||
}
|
||||
|
||||
public abstract int getStatuses(long[] accountIds, long[] maxIds, long[] sinceIds);
|
||||
|
||||
@Override
|
||||
public void scrollBy(float dy) {
|
||||
mDrawerCallback.scrollBy(dy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldLayoutHeaderBottom() {
|
||||
return mDrawerCallback.shouldLayoutHeaderBottom();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canScroll(float dy) {
|
||||
return mDrawerCallback.canScroll(dy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isScrollContent(float x, float y) {
|
||||
return mDrawerCallback.isScrollContent(x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelTouch() {
|
||||
mDrawerCallback.cancelTouch();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void topChanged(int offset) {
|
||||
mDrawerCallback.topChanged(offset);
|
||||
}
|
||||
|
||||
private View mProgressContainer;
|
||||
private SwipeRefreshLayout mSwipeRefreshLayout;
|
||||
private RecyclerView mRecyclerView;
|
||||
|
||||
private AbsStatusesAdapter<Data> mAdapter;
|
||||
|
||||
private SimpleDrawerCallback mDrawerCallback;
|
||||
|
||||
private OnScrollListener mOnScrollListener = new OnScrollListener() {
|
||||
@Override
|
||||
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
|
||||
super.onScrollStateChanged(recyclerView, newState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
||||
final LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
|
||||
final LoaderManager lm = getLoaderManager();
|
||||
if (lm.hasRunningLoaders()) return;
|
||||
if (layoutManager.findLastVisibleItemPosition() == mAdapter.getItemCount() - 1) {
|
||||
final long[] maxIds = new long[]{mAdapter.getStatus(mAdapter.getStatusCount() - 1).id};
|
||||
getStatuses(null, maxIds, null);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
final View view = getView();
|
||||
if (view == null) throw new AssertionError();
|
||||
final Context context = view.getContext();
|
||||
final boolean compact = Utils.isCompactCards(context);
|
||||
mDrawerCallback = new SimpleDrawerCallback(mRecyclerView);
|
||||
mSwipeRefreshLayout.setOnRefreshListener(this);
|
||||
mSwipeRefreshLayout.setColorSchemeColors(ThemeUtils.getUserAccentColor(context));
|
||||
mAdapter = onCreateAdapter(context, compact);
|
||||
final LinearLayoutManager layoutManager = new LinearLayoutManager(context);
|
||||
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
|
||||
mRecyclerView.setLayoutManager(layoutManager);
|
||||
if (compact) {
|
||||
mRecyclerView.addItemDecoration(new DividerItemDecoration(context, layoutManager.getOrientation()));
|
||||
}
|
||||
mRecyclerView.setAdapter(mAdapter);
|
||||
mRecyclerView.setOnScrollListener(mOnScrollListener);
|
||||
getLoaderManager().initLoader(0, getArguments(), this);
|
||||
setListShown(false);
|
||||
}
|
||||
|
||||
protected abstract AbsStatusesAdapter<Data> onCreateAdapter(Context context, boolean compact);
|
||||
|
||||
private void setListShown(boolean shown) {
|
||||
mProgressContainer.setVisibility(shown ? View.GONE : View.VISIBLE);
|
||||
mSwipeRefreshLayout.setVisibility(shown ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||
mContentView = view.findViewById(R.id.fragment_content);
|
||||
mProgressContainer = view.findViewById(R.id.progress_container);
|
||||
mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_layout);
|
||||
mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fitSystemWindows(Rect insets) {
|
||||
super.fitSystemWindows(insets);
|
||||
mContentView.setPadding(insets.left, insets.top, insets.right, insets.bottom);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.fragment_recycler_view, container, false);
|
||||
}
|
||||
|
||||
protected Data getAdapterData() {
|
||||
return mAdapter.getData();
|
||||
}
|
||||
|
||||
public void setRefreshing(boolean refreshing) {
|
||||
mSwipeRefreshLayout.setRefreshing(refreshing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(Loader<Data> loader, Data data) {
|
||||
setRefreshing(false);
|
||||
mAdapter.setData(data);
|
||||
setListShown(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<Data> loader) {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onRefresh() {
|
||||
if (mAdapter.getStatusCount() > 0) {
|
||||
final long[] sinceIds = new long[]{mAdapter.getStatus(0).id};
|
||||
getStatuses(null, null, sinceIds);
|
||||
} else {
|
||||
getStatuses(null, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
public SharedPreferences getSharedPreferences() {
|
||||
if (mPreferences != null) return mPreferences;
|
||||
return mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -122,14 +122,14 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement
|
||||
mAppMenuAdapter = new AppMenuAdapter(context);
|
||||
mAppMenuSectionView = newSectionView(context, R.string.more);
|
||||
mAccountSelectorView = inflater.inflate(R.layout.header_drawer_account_selector, listView, false);
|
||||
mAccountsSelector = (RecyclerView) mAccountSelectorView.findViewById(R.id.account_selector);
|
||||
mAccountsSelector = (RecyclerView) mAccountSelectorView.findViewById(R.id.other_accounts_list);
|
||||
final LinearLayoutManager layoutManager = new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
|
||||
layoutManager.setStackFromEnd(true);
|
||||
mAccountsSelector.setLayoutManager(layoutManager);
|
||||
mAccountsSelector.setAdapter(mAccountsAdapter);
|
||||
mAccountProfileContainer = mAccountSelectorView.findViewById(R.id.profile_container);
|
||||
mAccountProfileImageView = (ImageView) mAccountSelectorView.findViewById(R.id.profile_image);
|
||||
mAccountProfileBannerView = (ImageView) mAccountSelectorView.findViewById(R.id.profile_banner);
|
||||
mAccountProfileBannerView = (ImageView) mAccountSelectorView.findViewById(R.id.account_profile_banner);
|
||||
mAccountProfileNameView = (TextView) mAccountSelectorView.findViewById(R.id.name);
|
||||
mAccountProfileScreenNameView = (TextView) mAccountSelectorView.findViewById(R.id.screen_name);
|
||||
mAccountsToggle = (Switch) mAccountSelectorView.findViewById(R.id.toggle);
|
||||
|
@ -19,10 +19,6 @@
|
||||
|
||||
package org.mariotaku.twidere.fragment.support;
|
||||
|
||||
import static org.mariotaku.twidere.util.Utils.openStatus;
|
||||
import static org.mariotaku.twidere.util.Utils.openUserProfile;
|
||||
import static org.mariotaku.twidere.util.Utils.openUsers;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.content.Loader;
|
||||
@ -39,81 +35,84 @@ import org.mariotaku.twidere.model.ParcelableUser;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.mariotaku.twidere.util.Utils.openStatus;
|
||||
import static org.mariotaku.twidere.util.Utils.openUserProfile;
|
||||
import static org.mariotaku.twidere.util.Utils.openUsers;
|
||||
|
||||
public class ActivitiesAboutMeFragment extends BaseActivitiesListFragment {
|
||||
|
||||
@Override
|
||||
public BaseParcelableActivitiesAdapter createListAdapter(final Context context, final boolean compactCards,
|
||||
final boolean plainListStyle) {
|
||||
return new ParcelableActivitiesAboutMeAdapter(context, compactCards, plainListStyle);
|
||||
}
|
||||
@Override
|
||||
public BaseParcelableActivitiesAdapter createListAdapter(final Context context, final boolean compactCards) {
|
||||
return new ParcelableActivitiesAboutMeAdapter(context, compactCards);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loader<List<ParcelableActivity>> onCreateLoader(final int id, final Bundle args) {
|
||||
setProgressBarIndeterminateVisibility(true);
|
||||
return new ActivitiesAboutMeLoader(getActivity(), getAccountIds(), getData(), getSavedActivitiesFileArgs(),
|
||||
true);
|
||||
}
|
||||
@Override
|
||||
public Loader<List<ParcelableActivity>> onCreateLoader(final int id, final Bundle args) {
|
||||
setProgressBarIndeterminateVisibility(true);
|
||||
return new ActivitiesAboutMeLoader(getActivity(), getAccountIds(), getData(), getSavedActivitiesFileArgs(),
|
||||
true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onListItemClick(final ListView l, final View v, final int position, final long id) {
|
||||
final int adapter_pos = position - l.getHeaderViewsCount();
|
||||
final ParcelableActivity item = getListAdapter().getItem(adapter_pos);
|
||||
if (item == null) return;
|
||||
final ParcelableUser[] sources = item.sources;
|
||||
if (sources == null || sources.length == 0) return;
|
||||
final ParcelableStatus[] target_statuses = item.target_statuses;
|
||||
final ParcelableStatus[] target_objects = item.target_object_statuses;
|
||||
switch (item.action) {
|
||||
case ParcelableActivity.ACTION_FAVORITE: {
|
||||
if (sources.length == 1) {
|
||||
openUserProfile(getActivity(), sources[0], null);
|
||||
} else {
|
||||
final List<ParcelableUser> users = Arrays.asList(sources);
|
||||
openUsers(getActivity(), users);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ParcelableActivity.ACTION_FOLLOW: {
|
||||
if (sources.length == 1) {
|
||||
openUserProfile(getActivity(), sources[0], null);
|
||||
} else {
|
||||
final List<ParcelableUser> users = Arrays.asList(sources);
|
||||
openUsers(getActivity(), users);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ParcelableActivity.ACTION_MENTION: {
|
||||
if (target_objects != null && target_objects.length > 0) {
|
||||
openStatus(getActivity(), target_objects[0]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ParcelableActivity.ACTION_REPLY: {
|
||||
if (target_statuses != null && target_statuses.length > 0) {
|
||||
openStatus(getActivity(), target_statuses[0]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ParcelableActivity.ACTION_RETWEET: {
|
||||
if (sources.length == 1) {
|
||||
openUserProfile(getActivity(), sources[0], null);
|
||||
} else {
|
||||
final List<ParcelableUser> users = Arrays.asList(sources);
|
||||
openUsers(getActivity(), users);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onListItemClick(final ListView l, final View v, final int position, final long id) {
|
||||
final int adapter_pos = position - l.getHeaderViewsCount();
|
||||
final ParcelableActivity item = getListAdapter().getItem(adapter_pos);
|
||||
if (item == null) return;
|
||||
final ParcelableUser[] sources = item.sources;
|
||||
if (sources == null || sources.length == 0) return;
|
||||
final ParcelableStatus[] target_statuses = item.target_statuses;
|
||||
final ParcelableStatus[] target_objects = item.target_object_statuses;
|
||||
switch (item.action) {
|
||||
case ParcelableActivity.ACTION_FAVORITE: {
|
||||
if (sources.length == 1) {
|
||||
openUserProfile(getActivity(), sources[0], null);
|
||||
} else {
|
||||
final List<ParcelableUser> users = Arrays.asList(sources);
|
||||
openUsers(getActivity(), users);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ParcelableActivity.ACTION_FOLLOW: {
|
||||
if (sources.length == 1) {
|
||||
openUserProfile(getActivity(), sources[0], null);
|
||||
} else {
|
||||
final List<ParcelableUser> users = Arrays.asList(sources);
|
||||
openUsers(getActivity(), users);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ParcelableActivity.ACTION_MENTION: {
|
||||
if (target_objects != null && target_objects.length > 0) {
|
||||
openStatus(getActivity(), target_objects[0], null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ParcelableActivity.ACTION_REPLY: {
|
||||
if (target_statuses != null && target_statuses.length > 0) {
|
||||
openStatus(getActivity(), target_statuses[0], null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ParcelableActivity.ACTION_RETWEET: {
|
||||
if (sources.length == 1) {
|
||||
openUserProfile(getActivity(), sources[0], null);
|
||||
} else {
|
||||
final List<ParcelableUser> users = Arrays.asList(sources);
|
||||
openUsers(getActivity(), users);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] getSavedActivitiesFileArgs() {
|
||||
final Bundle args = getArguments();
|
||||
if (args != null && args.containsKey(EXTRA_ACCOUNT_ID)) {
|
||||
final long account_id = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
return new String[] { AUTHORITY_ACTIVITIES_ABOUT_ME, "account" + account_id };
|
||||
}
|
||||
return new String[] { AUTHORITY_ACTIVITIES_ABOUT_ME };
|
||||
}
|
||||
@Override
|
||||
protected String[] getSavedActivitiesFileArgs() {
|
||||
final Bundle args = getArguments();
|
||||
if (args != null && args.containsKey(EXTRA_ACCOUNT_ID)) {
|
||||
final long account_id = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
return new String[]{AUTHORITY_ACTIVITIES_ABOUT_ME, "account" + account_id};
|
||||
}
|
||||
return new String[]{AUTHORITY_ACTIVITIES_ABOUT_ME};
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,11 +19,6 @@
|
||||
|
||||
package org.mariotaku.twidere.fragment.support;
|
||||
|
||||
import static org.mariotaku.twidere.util.Utils.openStatus;
|
||||
import static org.mariotaku.twidere.util.Utils.openStatuses;
|
||||
import static org.mariotaku.twidere.util.Utils.openUserProfile;
|
||||
import static org.mariotaku.twidere.util.Utils.openUsers;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.content.Loader;
|
||||
@ -40,85 +35,89 @@ import org.mariotaku.twidere.model.ParcelableUser;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.mariotaku.twidere.util.Utils.openStatus;
|
||||
import static org.mariotaku.twidere.util.Utils.openStatuses;
|
||||
import static org.mariotaku.twidere.util.Utils.openUserProfile;
|
||||
import static org.mariotaku.twidere.util.Utils.openUsers;
|
||||
|
||||
public class ActivitiesByFriendsFragment extends BaseActivitiesListFragment {
|
||||
|
||||
@Override
|
||||
public BaseParcelableActivitiesAdapter createListAdapter(final Context context, final boolean compactCards,
|
||||
final boolean plainListStyle) {
|
||||
return new ParcelableActivitiesByFriendsAdapter(context, compactCards, plainListStyle);
|
||||
}
|
||||
@Override
|
||||
public BaseParcelableActivitiesAdapter createListAdapter(final Context context, final boolean compactCards) {
|
||||
return new ParcelableActivitiesByFriendsAdapter(context, compactCards);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loader<List<ParcelableActivity>> onCreateLoader(final int id, final Bundle args) {
|
||||
setProgressBarIndeterminateVisibility(true);
|
||||
return new ActivitiesAboutMeLoader(getActivity(), getAccountIds(), getData(), getSavedActivitiesFileArgs(),
|
||||
getTabPosition() >= 0);
|
||||
}
|
||||
@Override
|
||||
public Loader<List<ParcelableActivity>> onCreateLoader(final int id, final Bundle args) {
|
||||
setProgressBarIndeterminateVisibility(true);
|
||||
return new ActivitiesAboutMeLoader(getActivity(), getAccountIds(), getData(), getSavedActivitiesFileArgs(),
|
||||
getTabPosition() >= 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onListItemClick(final ListView l, final View v, final int position, final long id) {
|
||||
final int adapterPos = position - l.getHeaderViewsCount();
|
||||
final ParcelableActivity item = getListAdapter().getItem(adapterPos);
|
||||
if (item == null) return;
|
||||
final ParcelableUser[] sources = item.sources;
|
||||
if (sources == null || sources.length == 0) return;
|
||||
final ParcelableStatus[] targetStatuses = item.target_statuses;
|
||||
final ParcelableUser[] targetUsers = item.target_users;
|
||||
final ParcelableStatus[] target_object_statuses = item.target_object_statuses;
|
||||
switch (item.action) {
|
||||
case ParcelableActivity.ACTION_FAVORITE: {
|
||||
if (targetStatuses == null || targetStatuses.length == 0) return;
|
||||
if (targetStatuses.length == 1) {
|
||||
openStatus(getActivity(), targetStatuses[0]);
|
||||
} else {
|
||||
final List<ParcelableStatus> statuses = Arrays.asList(targetStatuses);
|
||||
openStatuses(getActivity(), statuses);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ParcelableActivity.ACTION_FOLLOW: {
|
||||
if (targetUsers == null || targetUsers.length == 0) return;
|
||||
if (targetUsers.length == 1) {
|
||||
openUserProfile(getActivity(), targetUsers[0], null);
|
||||
} else {
|
||||
final List<ParcelableUser> users = Arrays.asList(targetUsers);
|
||||
openUsers(getActivity(), users);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ParcelableActivity.ACTION_MENTION: {
|
||||
if (target_object_statuses != null && target_object_statuses.length > 0) {
|
||||
openStatus(getActivity(), target_object_statuses[0]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ParcelableActivity.ACTION_REPLY: {
|
||||
if (targetStatuses != null && targetStatuses.length > 0) {
|
||||
openStatus(getActivity(), targetStatuses[0]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ParcelableActivity.ACTION_RETWEET: {
|
||||
if (targetStatuses == null || targetStatuses.length == 0) return;
|
||||
if (targetStatuses.length == 1) {
|
||||
openStatus(getActivity(), targetStatuses[0]);
|
||||
} else {
|
||||
final List<ParcelableStatus> statuses = Arrays.asList(targetStatuses);
|
||||
openStatuses(getActivity(), statuses);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onListItemClick(final ListView l, final View v, final int position, final long id) {
|
||||
final int adapterPos = position - l.getHeaderViewsCount();
|
||||
final ParcelableActivity item = getListAdapter().getItem(adapterPos);
|
||||
if (item == null) return;
|
||||
final ParcelableUser[] sources = item.sources;
|
||||
if (sources == null || sources.length == 0) return;
|
||||
final ParcelableStatus[] targetStatuses = item.target_statuses;
|
||||
final ParcelableUser[] targetUsers = item.target_users;
|
||||
final ParcelableStatus[] target_object_statuses = item.target_object_statuses;
|
||||
switch (item.action) {
|
||||
case ParcelableActivity.ACTION_FAVORITE: {
|
||||
if (targetStatuses == null || targetStatuses.length == 0) return;
|
||||
if (targetStatuses.length == 1) {
|
||||
openStatus(getActivity(), targetStatuses[0], null);
|
||||
} else {
|
||||
final List<ParcelableStatus> statuses = Arrays.asList(targetStatuses);
|
||||
openStatuses(getActivity(), statuses);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ParcelableActivity.ACTION_FOLLOW: {
|
||||
if (targetUsers == null || targetUsers.length == 0) return;
|
||||
if (targetUsers.length == 1) {
|
||||
openUserProfile(getActivity(), targetUsers[0], null);
|
||||
} else {
|
||||
final List<ParcelableUser> users = Arrays.asList(targetUsers);
|
||||
openUsers(getActivity(), users);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ParcelableActivity.ACTION_MENTION: {
|
||||
if (target_object_statuses != null && target_object_statuses.length > 0) {
|
||||
openStatus(getActivity(), target_object_statuses[0], null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ParcelableActivity.ACTION_REPLY: {
|
||||
if (targetStatuses != null && targetStatuses.length > 0) {
|
||||
openStatus(getActivity(), targetStatuses[0], null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ParcelableActivity.ACTION_RETWEET: {
|
||||
if (targetStatuses == null || targetStatuses.length == 0) return;
|
||||
if (targetStatuses.length == 1) {
|
||||
openStatus(getActivity(), targetStatuses[0], null);
|
||||
} else {
|
||||
final List<ParcelableStatus> statuses = Arrays.asList(targetStatuses);
|
||||
openStatuses(getActivity(), statuses);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] getSavedActivitiesFileArgs() {
|
||||
final Bundle args = getArguments();
|
||||
if (args != null && args.containsKey(EXTRA_ACCOUNT_ID)) {
|
||||
final long account_id = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
return new String[] { AUTHORITY_ACTIVITIES_BY_FRIENDS, "account" + account_id };
|
||||
}
|
||||
return new String[] { AUTHORITY_ACTIVITIES_BY_FRIENDS };
|
||||
}
|
||||
@Override
|
||||
protected String[] getSavedActivitiesFileArgs() {
|
||||
final Bundle args = getArguments();
|
||||
if (args != null && args.containsKey(EXTRA_ACCOUNT_ID)) {
|
||||
final long account_id = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
return new String[]{AUTHORITY_ACTIVITIES_BY_FRIENDS, "account" + account_id};
|
||||
}
|
||||
return new String[]{AUTHORITY_ACTIVITIES_BY_FRIENDS};
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,9 +19,6 @@
|
||||
|
||||
package org.mariotaku.twidere.fragment.support;
|
||||
|
||||
import static org.mariotaku.twidere.util.Utils.encodeQueryParams;
|
||||
import static org.mariotaku.twidere.util.Utils.getDefaultTextSize;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
@ -38,102 +35,105 @@ import org.mariotaku.twidere.util.Utils;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static org.mariotaku.twidere.util.Utils.encodeQueryParams;
|
||||
import static org.mariotaku.twidere.util.Utils.getDefaultTextSize;
|
||||
|
||||
public abstract class BaseActivitiesListFragment extends BasePullToRefreshListFragment implements
|
||||
LoaderCallbacks<List<ParcelableActivity>> {
|
||||
LoaderCallbacks<List<ParcelableActivity>> {
|
||||
|
||||
private BaseParcelableActivitiesAdapter mAdapter;
|
||||
private SharedPreferences mPreferences;
|
||||
private BaseParcelableActivitiesAdapter mAdapter;
|
||||
private SharedPreferences mPreferences;
|
||||
|
||||
private List<ParcelableActivity> mData;
|
||||
private List<ParcelableActivity> mData;
|
||||
|
||||
public abstract BaseParcelableActivitiesAdapter createListAdapter(Context context, boolean compactCards,
|
||||
boolean plainListStyle);
|
||||
public abstract BaseParcelableActivitiesAdapter createListAdapter(final Context context,
|
||||
final boolean compactCards);
|
||||
|
||||
@Override
|
||||
public BaseParcelableActivitiesAdapter getListAdapter() {
|
||||
return mAdapter;
|
||||
}
|
||||
@Override
|
||||
public BaseParcelableActivitiesAdapter getListAdapter() {
|
||||
return mAdapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
||||
final boolean plainListStyle = mPreferences.getBoolean(KEY_PLAIN_LIST_STYLE, false);
|
||||
final boolean compactCards = mPreferences.getBoolean(KEY_COMPACT_CARDS, false);
|
||||
mAdapter = createListAdapter(getActivity(), compactCards, plainListStyle);
|
||||
setListAdapter(mAdapter);
|
||||
final ListView lv = getListView();
|
||||
if (!plainListStyle) {
|
||||
lv.setDivider(null);
|
||||
}
|
||||
lv.setSelector(android.R.color.transparent);
|
||||
getLoaderManager().initLoader(0, getArguments(), this);
|
||||
setListShown(false);
|
||||
}
|
||||
@Override
|
||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
||||
final boolean compactCards = mPreferences.getBoolean(KEY_COMPACT_CARDS, false);
|
||||
mAdapter = createListAdapter(getActivity(), compactCards);
|
||||
setListAdapter(mAdapter);
|
||||
final ListView lv = getListView();
|
||||
if (!compactCards) {
|
||||
lv.setDivider(null);
|
||||
}
|
||||
lv.setSelector(android.R.color.transparent);
|
||||
getLoaderManager().initLoader(0, getArguments(), this);
|
||||
setListShown(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(final Loader<List<ParcelableActivity>> loader) {
|
||||
mAdapter.setData(null);
|
||||
mData = null;
|
||||
}
|
||||
@Override
|
||||
public void onLoaderReset(final Loader<List<ParcelableActivity>> loader) {
|
||||
mAdapter.setData(null);
|
||||
mData = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(final Loader<List<ParcelableActivity>> loader, final List<ParcelableActivity> data) {
|
||||
setProgressBarIndeterminateVisibility(false);
|
||||
setRefreshComplete();
|
||||
mData = data;
|
||||
mAdapter.setData(data);
|
||||
if (loader instanceof Twitter4JActivitiesLoader) {
|
||||
final boolean multipleAccounts = ((Twitter4JActivitiesLoader) loader).getAccountIds().length > 1;
|
||||
mAdapter.setShowAccountColor(multipleAccounts);
|
||||
}
|
||||
setRefreshComplete();
|
||||
setListShown(true);
|
||||
}
|
||||
@Override
|
||||
public void onLoadFinished(final Loader<List<ParcelableActivity>> loader, final List<ParcelableActivity> data) {
|
||||
setProgressBarIndeterminateVisibility(false);
|
||||
setRefreshComplete();
|
||||
mData = data;
|
||||
mAdapter.setData(data);
|
||||
if (loader instanceof Twitter4JActivitiesLoader) {
|
||||
final boolean multipleAccounts = ((Twitter4JActivitiesLoader) loader).getAccountIds().length > 1;
|
||||
mAdapter.setShowAccountColor(multipleAccounts);
|
||||
}
|
||||
setRefreshComplete();
|
||||
setListShown(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRefreshFromEnd() {
|
||||
@Override
|
||||
public void onRefreshFromEnd() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRefreshFromStart() {
|
||||
if (isRefreshing()) return;
|
||||
getLoaderManager().restartLoader(0, getArguments(), this);
|
||||
}
|
||||
@Override
|
||||
public void onRefreshFromStart() {
|
||||
if (isRefreshing()) return;
|
||||
getLoaderManager().restartLoader(0, getArguments(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
final float text_size = mPreferences.getInt(KEY_TEXT_SIZE, getDefaultTextSize(getActivity()));
|
||||
final boolean display_profile_image = mPreferences.getBoolean(KEY_DISPLAY_PROFILE_IMAGE, true);
|
||||
final boolean show_absolute_time = mPreferences.getBoolean(KEY_SHOW_ABSOLUTE_TIME, false);
|
||||
mAdapter.setDisplayProfileImage(display_profile_image);
|
||||
mAdapter.setTextSize(text_size);
|
||||
mAdapter.setShowAbsoluteTime(show_absolute_time);
|
||||
}
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
final float text_size = mPreferences.getInt(KEY_TEXT_SIZE, getDefaultTextSize(getActivity()));
|
||||
final boolean display_profile_image = mPreferences.getBoolean(KEY_DISPLAY_PROFILE_IMAGE, true);
|
||||
final boolean show_absolute_time = mPreferences.getBoolean(KEY_SHOW_ABSOLUTE_TIME, false);
|
||||
mAdapter.setDisplayProfileImage(display_profile_image);
|
||||
mAdapter.setTextSize(text_size);
|
||||
mAdapter.setShowAbsoluteTime(show_absolute_time);
|
||||
}
|
||||
|
||||
protected final long[] getAccountIds() {
|
||||
final Bundle args = getArguments();
|
||||
if (args != null && args.containsKey(EXTRA_ACCOUNT_ID)) return new long[] { args.getLong(EXTRA_ACCOUNT_ID) };
|
||||
return Utils.getActivatedAccountIds(getActivity());
|
||||
}
|
||||
protected final long[] getAccountIds() {
|
||||
final Bundle args = getArguments();
|
||||
if (args != null && args.containsKey(EXTRA_ACCOUNT_ID))
|
||||
return new long[]{args.getLong(EXTRA_ACCOUNT_ID)};
|
||||
return Utils.getActivatedAccountIds(getActivity());
|
||||
}
|
||||
|
||||
protected final List<ParcelableActivity> getData() {
|
||||
return mData;
|
||||
}
|
||||
protected final List<ParcelableActivity> getData() {
|
||||
return mData;
|
||||
}
|
||||
|
||||
protected final String getPositionKey() {
|
||||
final Object[] args = getSavedActivitiesFileArgs();
|
||||
if (args == null || args.length <= 0) return null;
|
||||
try {
|
||||
return encodeQueryParams(ArrayUtils.toString(args, '.', false) + "." + getTabPosition());
|
||||
} catch (final IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
protected final String getPositionKey() {
|
||||
final Object[] args = getSavedActivitiesFileArgs();
|
||||
if (args == null || args.length <= 0) return null;
|
||||
try {
|
||||
return encodeQueryParams(ArrayUtils.toString(args, '.', false) + "." + getTabPosition());
|
||||
} catch (final IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected abstract Object[] getSavedActivitiesFileArgs();
|
||||
protected abstract Object[] getSavedActivitiesFileArgs();
|
||||
|
||||
}
|
||||
|
@ -137,14 +137,13 @@ abstract class BaseStatusesListFragment<Data> extends BasePullToRefreshListFragm
|
||||
mPositionManager = new PositionManager(context);
|
||||
mMultiSelectManager = getMultiSelectManager();
|
||||
mListView = getListView();
|
||||
final boolean plainListStyle = mPreferences.getBoolean(KEY_PLAIN_LIST_STYLE, false);
|
||||
final boolean compactCards = mPreferences.getBoolean(KEY_COMPACT_CARDS, false);
|
||||
mAdapter = newAdapterInstance(compactCards, plainListStyle);
|
||||
mAdapter = newAdapterInstance(compactCards);
|
||||
mAdapter.setMenuButtonClickListener(this);
|
||||
setListAdapter(null);
|
||||
setListHeaderFooters(mListView);
|
||||
setListAdapter(mAdapter);
|
||||
if (!plainListStyle) {
|
||||
if (!compactCards) {
|
||||
mListView.setDivider(null);
|
||||
}
|
||||
mListView.setSelector(android.R.color.transparent);
|
||||
@ -291,7 +290,7 @@ abstract class BaseStatusesListFragment<Data> extends BasePullToRefreshListFragm
|
||||
if (status == null || twitter == null) return false;
|
||||
switch (item.getItemId()) {
|
||||
case MENU_VIEW: {
|
||||
openStatus(getActivity(), status);
|
||||
openStatus(getActivity(), status, null);
|
||||
break;
|
||||
}
|
||||
case MENU_SHARE: {
|
||||
@ -480,7 +479,7 @@ abstract class BaseStatusesListFragment<Data> extends BasePullToRefreshListFragm
|
||||
|
||||
protected abstract void loadMoreStatuses();
|
||||
|
||||
protected abstract IStatusesListAdapter<Data> newAdapterInstance(boolean compact, boolean plain);
|
||||
protected abstract IStatusesListAdapter<Data> newAdapterInstance(boolean compact);
|
||||
|
||||
@Override
|
||||
protected void onReachedBottom() {
|
||||
|
@ -203,7 +203,7 @@ abstract class BaseStatusesStaggeredGridFragment<Data> extends BasePullToRefresh
|
||||
setItemSelected(status, position, !mMultiSelectManager.isSelected(status));
|
||||
return;
|
||||
}
|
||||
openStatus(getActivity(), status);
|
||||
openStatus(getActivity(), status, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -281,7 +281,7 @@ abstract class BaseStatusesStaggeredGridFragment<Data> extends BasePullToRefresh
|
||||
if (status == null || twitter == null) return false;
|
||||
switch (item.getItemId()) {
|
||||
case MENU_VIEW: {
|
||||
openStatus(getActivity(), status);
|
||||
openStatus(getActivity(), status, null);
|
||||
break;
|
||||
}
|
||||
case MENU_SHARE: {
|
||||
|
@ -114,7 +114,7 @@ abstract class BaseUsersListFragment extends BasePullToRefreshListFragment imple
|
||||
mData.clear();
|
||||
}
|
||||
mAccountId = accountId;
|
||||
if (!mPreferences.getBoolean(KEY_PLAIN_LIST_STYLE, false)) {
|
||||
if (!mPreferences.getBoolean(KEY_COMPACT_CARDS, false)) {
|
||||
mListView.setDivider(null);
|
||||
}
|
||||
mListView.setSelector(android.R.color.transparent);
|
||||
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.fragment.support;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
|
||||
import org.mariotaku.twidere.adapter.CursorStatusesAdapter;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/12/3.
|
||||
*/
|
||||
public abstract class CursorStatusesFragment extends AbsStatusesFragment<Cursor> {
|
||||
|
||||
@Override
|
||||
protected CursorStatusesAdapter onCreateAdapter(final Context context, final boolean compact) {
|
||||
return new CursorStatusesAdapter(context, compact);
|
||||
}
|
||||
|
||||
}
|
@ -35,7 +35,7 @@ import org.mariotaku.querybuilder.RawItemArray;
|
||||
import org.mariotaku.querybuilder.Where;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.activity.support.HomeActivity;
|
||||
import org.mariotaku.twidere.adapter.CursorStatusesAdapter;
|
||||
import org.mariotaku.twidere.adapter.CursorStatusesListAdapter;
|
||||
import org.mariotaku.twidere.provider.TweetStore.Accounts;
|
||||
import org.mariotaku.twidere.provider.TweetStore.Filters;
|
||||
import org.mariotaku.twidere.provider.TweetStore.Statuses;
|
||||
@ -92,7 +92,7 @@ public abstract class CursorStatusesListFragment extends BaseStatusesListFragmen
|
||||
where = accountWhere;
|
||||
}
|
||||
final String selection = processWhere(where).getSQL();
|
||||
return new CursorLoader(context, uri, CursorStatusesAdapter.CURSOR_COLS, selection, null, sortOrder);
|
||||
return new CursorLoader(context, uri, CursorStatusesListAdapter.CURSOR_COLS, selection, null, sortOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -206,8 +206,8 @@ public abstract class CursorStatusesListFragment extends BaseStatusesListFragmen
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CursorStatusesAdapter newAdapterInstance(final boolean compact, final boolean plain) {
|
||||
return new CursorStatusesAdapter(getActivity(), compact, plain);
|
||||
protected CursorStatusesListAdapter newAdapterInstance(final boolean compact) {
|
||||
return new CursorStatusesListAdapter(getActivity(), compact);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -40,7 +40,7 @@ import org.mariotaku.querybuilder.RawItemArray;
|
||||
import org.mariotaku.querybuilder.Where;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.activity.support.HomeActivity;
|
||||
import org.mariotaku.twidere.adapter.CursorStatusesAdapter;
|
||||
import org.mariotaku.twidere.adapter.CursorStatusesListAdapter;
|
||||
import org.mariotaku.twidere.provider.TweetStore.Accounts;
|
||||
import org.mariotaku.twidere.provider.TweetStore.Filters;
|
||||
import org.mariotaku.twidere.provider.TweetStore.Statuses;
|
||||
@ -86,7 +86,7 @@ public abstract class CursorStatusesStaggeredGridFragment extends BaseStatusesSt
|
||||
} else {
|
||||
where = accountWhere;
|
||||
}
|
||||
return new CursorLoader(getActivity(), uri, CursorStatusesAdapter.CURSOR_COLS, where.getSQL(), null, sort_by);
|
||||
return new CursorLoader(getActivity(), uri, CursorStatusesListAdapter.CURSOR_COLS, where.getSQL(), null, sort_by);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -194,8 +194,8 @@ public abstract class CursorStatusesStaggeredGridFragment extends BaseStatusesSt
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CursorStatusesAdapter newAdapterInstance() {
|
||||
return new CursorStatusesAdapter(getActivity());
|
||||
protected CursorStatusesListAdapter newAdapterInstance() {
|
||||
return new CursorStatusesListAdapter(getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -19,12 +19,6 @@
|
||||
|
||||
package org.mariotaku.twidere.fragment.support;
|
||||
|
||||
import static org.mariotaku.twidere.util.Utils.configBaseCardAdapter;
|
||||
import static org.mariotaku.twidere.util.Utils.getActivatedAccountIds;
|
||||
import static org.mariotaku.twidere.util.Utils.getNewestMessageIdsFromDatabase;
|
||||
import static org.mariotaku.twidere.util.Utils.getOldestMessageIdsFromDatabase;
|
||||
import static org.mariotaku.twidere.util.Utils.openDirectMessagesConversation;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
@ -61,316 +55,323 @@ import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.mariotaku.twidere.util.Utils.configBaseCardAdapter;
|
||||
import static org.mariotaku.twidere.util.Utils.getActivatedAccountIds;
|
||||
import static org.mariotaku.twidere.util.Utils.getNewestMessageIdsFromDatabase;
|
||||
import static org.mariotaku.twidere.util.Utils.getOldestMessageIdsFromDatabase;
|
||||
import static org.mariotaku.twidere.util.Utils.openDirectMessagesConversation;
|
||||
|
||||
public class DirectMessagesFragment extends BasePullToRefreshListFragment implements LoaderCallbacks<Cursor> {
|
||||
|
||||
private final SupportFragmentReloadCursorObserver mReloadContentObserver = new SupportFragmentReloadCursorObserver(
|
||||
this, 0, this);
|
||||
private final SupportFragmentReloadCursorObserver mReloadContentObserver = new SupportFragmentReloadCursorObserver(
|
||||
this, 0, this);
|
||||
|
||||
private final BroadcastReceiver mStatusReceiver = new BroadcastReceiver() {
|
||||
private final BroadcastReceiver mStatusReceiver = new BroadcastReceiver() {
|
||||
|
||||
@Override
|
||||
public void onReceive(final Context context, final Intent intent) {
|
||||
if (getActivity() == null || !isAdded() || isDetached()) return;
|
||||
final String action = intent.getAction();
|
||||
if (BROADCAST_TASK_STATE_CHANGED.equals(action)) {
|
||||
updateRefreshState();
|
||||
}
|
||||
}
|
||||
};
|
||||
@Override
|
||||
public void onReceive(final Context context, final Intent intent) {
|
||||
if (getActivity() == null || !isAdded() || isDetached()) return;
|
||||
final String action = intent.getAction();
|
||||
if (BROADCAST_TASK_STATE_CHANGED.equals(action)) {
|
||||
updateRefreshState();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private MultiSelectManager mMultiSelectManager;
|
||||
private MultiSelectManager mMultiSelectManager;
|
||||
|
||||
private SharedPreferences mPreferences;
|
||||
private ListView mListView;
|
||||
private SharedPreferences mPreferences;
|
||||
private ListView mListView;
|
||||
|
||||
private boolean mLoadMoreAutomatically;
|
||||
private boolean mLoadMoreAutomatically;
|
||||
|
||||
private DirectMessageConversationEntriesAdapter mAdapter;
|
||||
private int mFirstVisibleItem;
|
||||
private DirectMessageConversationEntriesAdapter mAdapter;
|
||||
private int mFirstVisibleItem;
|
||||
|
||||
private final Map<Long, Set<Long>> mUnreadCountsToRemove = Collections
|
||||
.synchronizedMap(new HashMap<Long, Set<Long>>());
|
||||
private final Map<Long, Set<Long>> mUnreadCountsToRemove = Collections
|
||||
.synchronizedMap(new HashMap<Long, Set<Long>>());
|
||||
|
||||
private final Set<Integer> mReadPositions = Collections.synchronizedSet(new HashSet<Integer>());
|
||||
private final Set<Integer> mReadPositions = Collections.synchronizedSet(new HashSet<Integer>());
|
||||
|
||||
private RemoveUnreadCountsTask mRemoveUnreadCountsTask;
|
||||
private RemoveUnreadCountsTask mRemoveUnreadCountsTask;
|
||||
|
||||
@Override
|
||||
public DirectMessageConversationEntriesAdapter getListAdapter() {
|
||||
return (DirectMessageConversationEntriesAdapter) super.getListAdapter();
|
||||
}
|
||||
@Override
|
||||
public DirectMessageConversationEntriesAdapter getListAdapter() {
|
||||
return (DirectMessageConversationEntriesAdapter) super.getListAdapter();
|
||||
}
|
||||
|
||||
public final Map<Long, Set<Long>> getUnreadCountsToRemove() {
|
||||
return mUnreadCountsToRemove;
|
||||
}
|
||||
public final Map<Long, Set<Long>> getUnreadCountsToRemove() {
|
||||
return mUnreadCountsToRemove;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||
mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
mMultiSelectManager = getMultiSelectManager();
|
||||
mAdapter = new DirectMessageConversationEntriesAdapter(getActivity());
|
||||
setListAdapter(mAdapter);
|
||||
mListView = getListView();
|
||||
if (!mPreferences.getBoolean(KEY_PLAIN_LIST_STYLE, false)) {
|
||||
mListView.setDivider(null);
|
||||
}
|
||||
mListView.setSelector(android.R.color.transparent);
|
||||
getLoaderManager().initLoader(0, null, this);
|
||||
setListShown(false);
|
||||
}
|
||||
@Override
|
||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||
mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
mMultiSelectManager = getMultiSelectManager();
|
||||
mAdapter = new DirectMessageConversationEntriesAdapter(getActivity());
|
||||
setListAdapter(mAdapter);
|
||||
mListView = getListView();
|
||||
if (!mPreferences.getBoolean(KEY_COMPACT_CARDS, false)) {
|
||||
mListView.setDivider(null);
|
||||
}
|
||||
mListView.setSelector(android.R.color.transparent);
|
||||
getLoaderManager().initLoader(0, null, this);
|
||||
setListShown(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loader<Cursor> onCreateLoader(final int id, final Bundle args) {
|
||||
final Uri uri = DirectMessages.ConversationEntries.CONTENT_URI;
|
||||
final long account_id = getAccountId();
|
||||
final long[] account_ids = account_id > 0 ? new long[] { account_id } : getActivatedAccountIds(getActivity());
|
||||
final boolean no_account_selected = account_ids.length == 0;
|
||||
setEmptyText(no_account_selected ? getString(R.string.no_account_selected) : null);
|
||||
if (!no_account_selected) {
|
||||
getListView().setEmptyView(null);
|
||||
}
|
||||
final Where account_where = Where.in(new Column(Statuses.ACCOUNT_ID), new RawItemArray(account_ids));
|
||||
return new CursorLoader(getActivity(), uri, null, account_where.getSQL(), null, null);
|
||||
}
|
||||
@Override
|
||||
public Loader<Cursor> onCreateLoader(final int id, final Bundle args) {
|
||||
final Uri uri = DirectMessages.ConversationEntries.CONTENT_URI;
|
||||
final long account_id = getAccountId();
|
||||
final long[] account_ids = account_id > 0 ? new long[]{account_id} : getActivatedAccountIds(getActivity());
|
||||
final boolean no_account_selected = account_ids.length == 0;
|
||||
setEmptyText(no_account_selected ? getString(R.string.no_account_selected) : null);
|
||||
if (!no_account_selected) {
|
||||
getListView().setEmptyView(null);
|
||||
}
|
||||
final Where account_where = Where.in(new Column(Statuses.ACCOUNT_ID), new RawItemArray(account_ids));
|
||||
return new CursorLoader(getActivity(), uri, null, account_where.getSQL(), null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onListItemClick(final ListView l, final View v, final int position, final long id) {
|
||||
if (mMultiSelectManager.isActive()) return;
|
||||
final int pos = position - l.getHeaderViewsCount();
|
||||
final long conversationId = mAdapter.getConversationId(pos);
|
||||
final long accountId = mAdapter.getAccountId(pos);
|
||||
mReadPositions.add(pos);
|
||||
removeUnreadCounts();
|
||||
if (conversationId > 0 && accountId > 0) {
|
||||
openDirectMessagesConversation(getActivity(), accountId, conversationId);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onListItemClick(final ListView l, final View v, final int position, final long id) {
|
||||
if (mMultiSelectManager.isActive()) return;
|
||||
final int pos = position - l.getHeaderViewsCount();
|
||||
final long conversationId = mAdapter.getConversationId(pos);
|
||||
final long accountId = mAdapter.getAccountId(pos);
|
||||
mReadPositions.add(pos);
|
||||
removeUnreadCounts();
|
||||
if (conversationId > 0 && accountId > 0) {
|
||||
openDirectMessagesConversation(getActivity(), accountId, conversationId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(final Loader<Cursor> loader) {
|
||||
mAdapter.changeCursor(null);
|
||||
}
|
||||
@Override
|
||||
public void onLoaderReset(final Loader<Cursor> loader) {
|
||||
mAdapter.changeCursor(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(final Loader<Cursor> loader, final Cursor cursor) {
|
||||
if (getActivity() == null) return;
|
||||
mFirstVisibleItem = -1;
|
||||
mAdapter.changeCursor(cursor);
|
||||
mAdapter.setShowAccountColor(getActivatedAccountIds(getActivity()).length > 1);
|
||||
setListShown(true);
|
||||
}
|
||||
@Override
|
||||
public void onLoadFinished(final Loader<Cursor> loader, final Cursor cursor) {
|
||||
if (getActivity() == null) return;
|
||||
mFirstVisibleItem = -1;
|
||||
mAdapter.changeCursor(cursor);
|
||||
mAdapter.setShowAccountColor(getActivatedAccountIds(getActivity()).length > 1);
|
||||
setListShown(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case MENU_COMPOSE: {
|
||||
openDirectMessagesConversation(getActivity(), -1, -1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case MENU_COMPOSE: {
|
||||
openDirectMessagesConversation(getActivity(), -1, -1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRefreshFromEnd() {
|
||||
if (mLoadMoreAutomatically) return;
|
||||
loadMoreMessages();
|
||||
}
|
||||
@Override
|
||||
public void onRefreshFromEnd() {
|
||||
if (mLoadMoreAutomatically) return;
|
||||
loadMoreMessages();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRefreshFromStart() {
|
||||
if (isRefreshing()) return;
|
||||
new AsyncTask<Void, Void, long[][]>() {
|
||||
@Override
|
||||
public void onRefreshFromStart() {
|
||||
if (isRefreshing()) return;
|
||||
new AsyncTask<Void, Void, long[][]>() {
|
||||
|
||||
@Override
|
||||
protected long[][] doInBackground(final Void... params) {
|
||||
final long[][] result = new long[2][];
|
||||
result[0] = getActivatedAccountIds(getActivity());
|
||||
result[1] = getNewestMessageIdsFromDatabase(getActivity(), DirectMessages.Inbox.CONTENT_URI);
|
||||
return result;
|
||||
}
|
||||
@Override
|
||||
protected long[][] doInBackground(final Void... params) {
|
||||
final long[][] result = new long[2][];
|
||||
result[0] = getActivatedAccountIds(getActivity());
|
||||
result[1] = getNewestMessageIdsFromDatabase(getActivity(), DirectMessages.Inbox.CONTENT_URI);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(final long[][] result) {
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
if (twitter == null) return;
|
||||
twitter.getReceivedDirectMessagesAsync(result[0], null, result[1]);
|
||||
twitter.getSentDirectMessagesAsync(result[0], null, null);
|
||||
}
|
||||
@Override
|
||||
protected void onPostExecute(final long[][] result) {
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
if (twitter == null) return;
|
||||
twitter.getReceivedDirectMessagesAsync(result[0], null, result[1]);
|
||||
twitter.getSentDirectMessagesAsync(result[0], null, null);
|
||||
}
|
||||
|
||||
}.execute();
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mListView.setFastScrollEnabled(mPreferences.getBoolean(KEY_FAST_SCROLL_THUMB, false));
|
||||
configBaseCardAdapter(getActivity(), mAdapter);
|
||||
mLoadMoreAutomatically = mPreferences.getBoolean(KEY_LOAD_MORE_AUTOMATICALLY, false);
|
||||
}
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mListView.setFastScrollEnabled(mPreferences.getBoolean(KEY_FAST_SCROLL_THUMB, false));
|
||||
configBaseCardAdapter(getActivity(), mAdapter);
|
||||
mLoadMoreAutomatically = mPreferences.getBoolean(KEY_LOAD_MORE_AUTOMATICALLY, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScroll(final AbsListView view, final int firstVisibleItem, final int visibleItemCount,
|
||||
final int totalItemCount) {
|
||||
super.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
|
||||
addReadPosition(firstVisibleItem);
|
||||
}
|
||||
@Override
|
||||
public void onScroll(final AbsListView view, final int firstVisibleItem, final int visibleItemCount,
|
||||
final int totalItemCount) {
|
||||
super.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
|
||||
addReadPosition(firstVisibleItem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrollStateChanged(final AbsListView view, final int scrollState) {
|
||||
switch (scrollState) {
|
||||
case SCROLL_STATE_FLING:
|
||||
case SCROLL_STATE_TOUCH_SCROLL: {
|
||||
break;
|
||||
}
|
||||
case SCROLL_STATE_IDLE: {
|
||||
for (int i = mListView.getFirstVisiblePosition(), j = mListView.getLastVisiblePosition(); i < j; i++) {
|
||||
mReadPositions.add(i);
|
||||
}
|
||||
removeUnreadCounts();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onScrollStateChanged(final AbsListView view, final int scrollState) {
|
||||
switch (scrollState) {
|
||||
case SCROLL_STATE_FLING:
|
||||
case SCROLL_STATE_TOUCH_SCROLL: {
|
||||
break;
|
||||
}
|
||||
case SCROLL_STATE_IDLE: {
|
||||
for (int i = mListView.getFirstVisiblePosition(), j = mListView.getLastVisiblePosition(); i < j; i++) {
|
||||
mReadPositions.add(i);
|
||||
}
|
||||
removeUnreadCounts();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
final ContentResolver resolver = getContentResolver();
|
||||
resolver.registerContentObserver(Accounts.CONTENT_URI, true, mReloadContentObserver);
|
||||
final IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(BROADCAST_TASK_STATE_CHANGED);
|
||||
registerReceiver(mStatusReceiver, filter);
|
||||
}
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
final ContentResolver resolver = getContentResolver();
|
||||
resolver.registerContentObserver(Accounts.CONTENT_URI, true, mReloadContentObserver);
|
||||
final IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(BROADCAST_TASK_STATE_CHANGED);
|
||||
registerReceiver(mStatusReceiver, filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
unregisterReceiver(mStatusReceiver);
|
||||
final ContentResolver resolver = getContentResolver();
|
||||
resolver.unregisterContentObserver(mReloadContentObserver);
|
||||
super.onStop();
|
||||
}
|
||||
@Override
|
||||
public void onStop() {
|
||||
unregisterReceiver(mStatusReceiver);
|
||||
final ContentResolver resolver = getContentResolver();
|
||||
resolver.unregisterContentObserver(mReloadContentObserver);
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean scrollToStart() {
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
final int tabPosition = getTabPosition();
|
||||
if (twitter != null && tabPosition >= 0) {
|
||||
twitter.clearUnreadCountAsync(tabPosition);
|
||||
}
|
||||
return super.scrollToStart();
|
||||
}
|
||||
@Override
|
||||
public boolean scrollToStart() {
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
final int tabPosition = getTabPosition();
|
||||
if (twitter != null && tabPosition >= 0) {
|
||||
twitter.clearUnreadCountAsync(tabPosition);
|
||||
}
|
||||
return super.scrollToStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUserVisibleHint(final boolean isVisibleToUser) {
|
||||
super.setUserVisibleHint(isVisibleToUser);
|
||||
if (isVisibleToUser) {
|
||||
updateRefreshState();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void setUserVisibleHint(final boolean isVisibleToUser) {
|
||||
super.setUserVisibleHint(isVisibleToUser);
|
||||
if (isVisibleToUser) {
|
||||
updateRefreshState();
|
||||
}
|
||||
}
|
||||
|
||||
protected long getAccountId() {
|
||||
final Bundle args = getArguments();
|
||||
return args != null ? args.getLong(EXTRA_ACCOUNT_ID, -1) : -1;
|
||||
}
|
||||
protected long getAccountId() {
|
||||
final Bundle args = getArguments();
|
||||
return args != null ? args.getLong(EXTRA_ACCOUNT_ID, -1) : -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onListTouched() {
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
if (twitter != null) {
|
||||
twitter.clearNotificationAsync(NOTIFICATION_ID_DIRECT_MESSAGES, getAccountId());
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected void onListTouched() {
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
if (twitter != null) {
|
||||
twitter.clearNotificationAsync(NOTIFICATION_ID_DIRECT_MESSAGES, getAccountId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onReachedBottom() {
|
||||
if (!mLoadMoreAutomatically) return;
|
||||
loadMoreMessages();
|
||||
}
|
||||
@Override
|
||||
protected void onReachedBottom() {
|
||||
if (!mLoadMoreAutomatically) return;
|
||||
loadMoreMessages();
|
||||
}
|
||||
|
||||
protected void updateRefreshState() {
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
if (twitter == null || !getUserVisibleHint()) return;
|
||||
setRefreshing(twitter.isReceivedDirectMessagesRefreshing() || twitter.isSentDirectMessagesRefreshing());
|
||||
}
|
||||
protected void updateRefreshState() {
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
if (twitter == null || !getUserVisibleHint()) return;
|
||||
setRefreshing(twitter.isReceivedDirectMessagesRefreshing() || twitter.isSentDirectMessagesRefreshing());
|
||||
}
|
||||
|
||||
private void addReadPosition(final int firstVisibleItem) {
|
||||
if (mFirstVisibleItem != firstVisibleItem) {
|
||||
mReadPositions.add(firstVisibleItem);
|
||||
}
|
||||
mFirstVisibleItem = firstVisibleItem;
|
||||
}
|
||||
private void addReadPosition(final int firstVisibleItem) {
|
||||
if (mFirstVisibleItem != firstVisibleItem) {
|
||||
mReadPositions.add(firstVisibleItem);
|
||||
}
|
||||
mFirstVisibleItem = firstVisibleItem;
|
||||
}
|
||||
|
||||
private void addUnreadCountsToRemove(final long account_id, final long id) {
|
||||
if (mUnreadCountsToRemove.containsKey(account_id)) {
|
||||
final Set<Long> counts = mUnreadCountsToRemove.get(account_id);
|
||||
counts.add(id);
|
||||
} else {
|
||||
final Set<Long> counts = new HashSet<Long>();
|
||||
counts.add(id);
|
||||
mUnreadCountsToRemove.put(account_id, counts);
|
||||
}
|
||||
}
|
||||
private void addUnreadCountsToRemove(final long account_id, final long id) {
|
||||
if (mUnreadCountsToRemove.containsKey(account_id)) {
|
||||
final Set<Long> counts = mUnreadCountsToRemove.get(account_id);
|
||||
counts.add(id);
|
||||
} else {
|
||||
final Set<Long> counts = new HashSet<Long>();
|
||||
counts.add(id);
|
||||
mUnreadCountsToRemove.put(account_id, counts);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadMoreMessages() {
|
||||
if (isRefreshing()) return;
|
||||
new AsyncTask<Void, Void, long[][]>() {
|
||||
private void loadMoreMessages() {
|
||||
if (isRefreshing()) return;
|
||||
new AsyncTask<Void, Void, long[][]>() {
|
||||
|
||||
@Override
|
||||
protected long[][] doInBackground(final Void... params) {
|
||||
final long[][] result = new long[3][];
|
||||
result[0] = getActivatedAccountIds(getActivity());
|
||||
result[1] = getOldestMessageIdsFromDatabase(getActivity(), DirectMessages.Inbox.CONTENT_URI);
|
||||
result[2] = getOldestMessageIdsFromDatabase(getActivity(), DirectMessages.Outbox.CONTENT_URI);
|
||||
return result;
|
||||
}
|
||||
@Override
|
||||
protected long[][] doInBackground(final Void... params) {
|
||||
final long[][] result = new long[3][];
|
||||
result[0] = getActivatedAccountIds(getActivity());
|
||||
result[1] = getOldestMessageIdsFromDatabase(getActivity(), DirectMessages.Inbox.CONTENT_URI);
|
||||
result[2] = getOldestMessageIdsFromDatabase(getActivity(), DirectMessages.Outbox.CONTENT_URI);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(final long[][] result) {
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
if (twitter == null) return;
|
||||
twitter.getReceivedDirectMessagesAsync(result[0], result[1], null);
|
||||
twitter.getSentDirectMessagesAsync(result[0], result[2], null);
|
||||
}
|
||||
@Override
|
||||
protected void onPostExecute(final long[][] result) {
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
if (twitter == null) return;
|
||||
twitter.getReceivedDirectMessagesAsync(result[0], result[1], null);
|
||||
twitter.getSentDirectMessagesAsync(result[0], result[2], null);
|
||||
}
|
||||
|
||||
}.execute();
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
private void removeUnreadCounts() {
|
||||
if (mRemoveUnreadCountsTask != null && mRemoveUnreadCountsTask.getStatus() == AsyncTask.Status.RUNNING) return;
|
||||
mRemoveUnreadCountsTask = new RemoveUnreadCountsTask(mReadPositions, this);
|
||||
mRemoveUnreadCountsTask.execute();
|
||||
}
|
||||
private void removeUnreadCounts() {
|
||||
if (mRemoveUnreadCountsTask != null && mRemoveUnreadCountsTask.getStatus() == AsyncTask.Status.RUNNING)
|
||||
return;
|
||||
mRemoveUnreadCountsTask = new RemoveUnreadCountsTask(mReadPositions, this);
|
||||
mRemoveUnreadCountsTask.execute();
|
||||
}
|
||||
|
||||
static class RemoveUnreadCountsTask extends AsyncTask<Void, Void, Void> {
|
||||
private final Set<Integer> read_positions;
|
||||
private final DirectMessageConversationEntriesAdapter adapter;
|
||||
private final DirectMessagesFragment fragment;
|
||||
static class RemoveUnreadCountsTask extends AsyncTask<Void, Void, Void> {
|
||||
private final Set<Integer> read_positions;
|
||||
private final DirectMessageConversationEntriesAdapter adapter;
|
||||
private final DirectMessagesFragment fragment;
|
||||
|
||||
RemoveUnreadCountsTask(final Set<Integer> read_positions, final DirectMessagesFragment fragment) {
|
||||
this.read_positions = Collections.synchronizedSet(new HashSet<Integer>(read_positions));
|
||||
this.fragment = fragment;
|
||||
adapter = fragment.getListAdapter();
|
||||
}
|
||||
RemoveUnreadCountsTask(final Set<Integer> read_positions, final DirectMessagesFragment fragment) {
|
||||
this.read_positions = Collections.synchronizedSet(new HashSet<Integer>(read_positions));
|
||||
this.fragment = fragment;
|
||||
adapter = fragment.getListAdapter();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(final Void... params) {
|
||||
for (final int pos : read_positions) {
|
||||
final long id = adapter.getConversationId(pos), account_id = adapter.getAccountId(pos);
|
||||
fragment.addUnreadCountsToRemove(account_id, id);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
protected Void doInBackground(final Void... params) {
|
||||
for (final int pos : read_positions) {
|
||||
final long id = adapter.getConversationId(pos), account_id = adapter.getAccountId(pos);
|
||||
fragment.addUnreadCountsToRemove(account_id, id);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(final Void result) {
|
||||
final AsyncTwitterWrapper twitter = fragment.getTwitterWrapper();
|
||||
if (twitter != null) {
|
||||
twitter.removeUnreadCountsAsync(fragment.getTabPosition(), fragment.getUnreadCountsToRemove());
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected void onPostExecute(final Void result) {
|
||||
final AsyncTwitterWrapper twitter = fragment.getTwitterWrapper();
|
||||
if (twitter != null) {
|
||||
twitter.removeUnreadCountsAsync(fragment.getTabPosition(), fragment.getUnreadCountsToRemove());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,98 +1,51 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* 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.fragment.support;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.content.CursorLoader;
|
||||
import android.support.v4.content.Loader;
|
||||
|
||||
import org.mariotaku.twidere.adapter.CursorStatusesListAdapter;
|
||||
import org.mariotaku.twidere.provider.TweetStore.Statuses;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
|
||||
public class HomeTimelineFragment extends CursorStatusesListFragment {
|
||||
|
||||
private final BroadcastReceiver mStatusReceiver = new BroadcastReceiver() {
|
||||
|
||||
@Override
|
||||
public void onReceive(final Context context, final Intent intent) {
|
||||
if (getActivity() == null || !isAdded() || isDetached()) return;
|
||||
final String action = intent.getAction();
|
||||
if (BROADCAST_HOME_TIMELINE_REFRESHED.equals(action)) {
|
||||
setRefreshComplete();
|
||||
} else if (BROADCAST_TASK_STATE_CHANGED.equals(action)) {
|
||||
updateRefreshState();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/12/3.
|
||||
*/
|
||||
public class HomeTimelineFragment extends CursorStatusesFragment {
|
||||
@Override
|
||||
public int getStatuses(final long[] accountIds, final long[] maxIds, final long[] sinceIds) {
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
if (twitter == null) return 0;
|
||||
if (maxIds == null) return twitter.refreshAll(accountIds);
|
||||
return twitter.getHomeTimelineAsync(accountIds, maxIds, sinceIds);
|
||||
public int getStatuses(long[] accountIds, long[] maxIds, long[] sinceIds) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
final IntentFilter filter = new IntentFilter(BROADCAST_HOME_TIMELINE_REFRESHED);
|
||||
filter.addAction(BROADCAST_TASK_STATE_CHANGED);
|
||||
registerReceiver(mStatusReceiver, filter);
|
||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||
final Context context = getActivity();
|
||||
final Uri uri = Statuses.CONTENT_URI;
|
||||
final SharedPreferences preferences = getSharedPreferences();
|
||||
final boolean sortById = preferences.getBoolean(KEY_SORT_TIMELINE_BY_ID, false);
|
||||
final String sortOrder = sortById ? Statuses.SORT_ORDER_STATUS_ID_DESC : Statuses.SORT_ORDER_TIMESTAMP_DESC;
|
||||
return new CursorLoader(context, uri, CursorStatusesListAdapter.CURSOR_COLS, null, null, sortOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
unregisterReceiver(mStatusReceiver);
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Uri getContentUri() {
|
||||
return Statuses.CONTENT_URI;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getNotificationType() {
|
||||
return NOTIFICATION_ID_HOME_TIMELINE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getPositionKey() {
|
||||
return "home_timeline" + getTabPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isFiltersEnabled() {
|
||||
final SharedPreferences pref = getSharedPreferences();
|
||||
return pref != null && pref.getBoolean(KEY_FILTERS_IN_HOME_TIMELINE, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateRefreshState() {
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
if (twitter == null || !getUserVisibleHint() || getActivity() == null) return;
|
||||
setRefreshing(twitter.isHomeTimelineRefreshing());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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.fragment.support;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
|
||||
import org.mariotaku.twidere.provider.TweetStore.Statuses;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
|
||||
public class HomeTimelineListFragment extends CursorStatusesListFragment {
|
||||
|
||||
private final BroadcastReceiver mStatusReceiver = new BroadcastReceiver() {
|
||||
|
||||
@Override
|
||||
public void onReceive(final Context context, final Intent intent) {
|
||||
if (getActivity() == null || !isAdded() || isDetached()) return;
|
||||
final String action = intent.getAction();
|
||||
if (BROADCAST_HOME_TIMELINE_REFRESHED.equals(action)) {
|
||||
setRefreshComplete();
|
||||
} else if (BROADCAST_TASK_STATE_CHANGED.equals(action)) {
|
||||
updateRefreshState();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public int getStatuses(final long[] accountIds, final long[] maxIds, final long[] sinceIds) {
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
if (twitter == null) return 0;
|
||||
if (maxIds == null) return twitter.refreshAll(accountIds);
|
||||
return twitter.getHomeTimelineAsync(accountIds, maxIds, sinceIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
final IntentFilter filter = new IntentFilter(BROADCAST_HOME_TIMELINE_REFRESHED);
|
||||
filter.addAction(BROADCAST_TASK_STATE_CHANGED);
|
||||
registerReceiver(mStatusReceiver, filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
unregisterReceiver(mStatusReceiver);
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Uri getContentUri() {
|
||||
return Statuses.CONTENT_URI;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getNotificationType() {
|
||||
return NOTIFICATION_ID_HOME_TIMELINE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getPositionKey() {
|
||||
return "home_timeline" + getTabPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isFiltersEnabled() {
|
||||
final SharedPreferences pref = getSharedPreferences();
|
||||
return pref != null && pref.getBoolean(KEY_FILTERS_IN_HOME_TIMELINE, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateRefreshState() {
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
if (twitter == null || !getUserVisibleHint() || getActivity() == null) return;
|
||||
setRefreshing(twitter.isHomeTimelineRefreshing());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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.fragment.support;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
|
||||
import org.mariotaku.twidere.adapter.ParcelableStatusesAdapter;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/12/3.
|
||||
*/
|
||||
public abstract class ParcelableStatusesFragment extends AbsStatusesFragment<List<ParcelableStatus>> {
|
||||
|
||||
@Override
|
||||
protected ParcelableStatusesAdapter onCreateAdapter(final Context context, final boolean compact) {
|
||||
return new ParcelableStatusesAdapter(context, compact);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatuses(long[] accountIds, final long[] maxIds, final long[] sinceIds) {
|
||||
final Bundle args = new Bundle(getArguments());
|
||||
if (maxIds != null) {
|
||||
args.putLong(EXTRA_MAX_ID, maxIds[0]);
|
||||
}
|
||||
if (sinceIds != null) {
|
||||
args.putLong(EXTRA_SINCE_ID, sinceIds[0]);
|
||||
}
|
||||
getLoaderManager().restartLoader(0, args, this);
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
@ -208,8 +208,8 @@ public abstract class ParcelableStatusesListFragment extends BaseStatusesListFra
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ParcelableStatusesListAdapter newAdapterInstance(final boolean compact, final boolean plain) {
|
||||
return new ParcelableStatusesListAdapter(getActivity(), compact, plain);
|
||||
protected ParcelableStatusesListAdapter newAdapterInstance(final boolean compact) {
|
||||
return new ParcelableStatusesListAdapter(getActivity(), compact);
|
||||
}
|
||||
|
||||
protected abstract Loader<List<ParcelableStatus>> newLoaderInstance(Context context, Bundle args);
|
||||
|
@ -43,6 +43,7 @@ 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.support.v4.view.ViewCompat;
|
||||
import android.text.Html;
|
||||
import android.text.SpannableString;
|
||||
import android.text.TextUtils;
|
||||
@ -140,6 +141,8 @@ import static org.mariotaku.twidere.util.Utils.startStatusShareChooser;
|
||||
public class StatusFragment extends ParcelableStatusesListFragment implements OnClickListener,
|
||||
OnMediaClickListener, OnSharedPreferenceChangeListener, ActionMode.Callback {
|
||||
|
||||
public static final String TRANSITION_NAME_CARD = "card";
|
||||
|
||||
private static final int LOADER_ID_STATUS = 1;
|
||||
private static final int LOADER_ID_FOLLOW = 2;
|
||||
private static final int LOADER_ID_LOCATION = 3;
|
||||
@ -614,7 +617,7 @@ public class StatusFragment extends ParcelableStatusesListFragment implements On
|
||||
mLoadImagesIndicator = mHeaderView.findViewById(R.id.load_images);
|
||||
mRetryButton = (Button) view.findViewById(R.id.retry);
|
||||
final View cardView = mHeaderView.findViewById(R.id.card);
|
||||
ThemeUtils.applyThemeAlphaToDrawable(cardView.getContext(), cardView.getBackground());
|
||||
ViewCompat.setTransitionName(cardView, TRANSITION_NAME_CARD);
|
||||
return view;
|
||||
}
|
||||
|
||||
|
@ -1,118 +1,51 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* 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.fragment.support;
|
||||
|
||||
import static org.mariotaku.twidere.util.Utils.getAccountId;
|
||||
import static org.mariotaku.twidere.util.Utils.isSameAccount;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.content.Loader;
|
||||
|
||||
import org.mariotaku.twidere.adapter.iface.IStatusesListAdapter;
|
||||
import org.mariotaku.twidere.loader.support.UserFavoritesLoader;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserFavoritesFragment extends ParcelableStatusesListFragment {
|
||||
/**
|
||||
* Created by mariotaku on 14/12/2.
|
||||
*/
|
||||
public class UserFavoritesFragment extends ParcelableStatusesFragment {
|
||||
|
||||
private long mUserId;
|
||||
private String mUserScreenName;
|
||||
|
||||
private final BroadcastReceiver mStateReceiver = new BroadcastReceiver() {
|
||||
|
||||
@Override
|
||||
public void onReceive(final Context context, final Intent intent) {
|
||||
if (getActivity() == null || !isAdded() || isDetached()) return;
|
||||
final String action = intent.getAction();
|
||||
if (BROADCAST_FAVORITE_CHANGED.equals(action)) {
|
||||
final ParcelableStatus status = intent.getParcelableExtra(EXTRA_STATUS);
|
||||
if (status == null) return;
|
||||
if ((isSameAccount(context, status.account_id, mUserId) || isSameAccount(context, status.account_id,
|
||||
mUserScreenName)) && status.id > 0 && !intent.getBooleanExtra(EXTRA_FAVORITED, true)) {
|
||||
deleteStatus(status.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@Override
|
||||
public Loader<List<ParcelableStatus>> newLoaderInstance(final Context context, final Bundle args) {
|
||||
if (args == null) return null;
|
||||
final long account_id = args.getLong(EXTRA_ACCOUNT_ID);
|
||||
final long user_id = args.getLong(EXTRA_USER_ID, -1);
|
||||
final long max_id = args.getLong(EXTRA_MAX_ID, -1);
|
||||
final long since_id = args.getLong(EXTRA_SINCE_ID, -1);
|
||||
final String screen_name = args.getString(EXTRA_SCREEN_NAME);
|
||||
final int tab_position = args.getInt(EXTRA_TAB_POSITION, -1);
|
||||
mUserId = user_id;
|
||||
mUserScreenName = screen_name;
|
||||
return new UserFavoritesLoader(getActivity(), account_id, user_id, screen_name, max_id, since_id, getData(),
|
||||
getSavedStatusesFileArgs(), tab_position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
final Bundle args = getArguments();
|
||||
final long account_id = args != null ? args.getLong(EXTRA_ACCOUNT_ID, -1) : -1;
|
||||
final long user_id = args != null ? args.getLong(EXTRA_USER_ID, -1) : -1;
|
||||
final String screen_name = args != null ? args.getString(EXTRA_SCREEN_NAME) : null;
|
||||
final boolean is_my_timeline = user_id > 0 ? account_id == user_id : account_id == getAccountId(getActivity(),
|
||||
screen_name);
|
||||
final IStatusesListAdapter<List<ParcelableStatus>> adapter = getListAdapter();
|
||||
adapter.setFavoritesHightlightDisabled(is_my_timeline);
|
||||
adapter.setFiltersEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
final IntentFilter filter = new IntentFilter(BROADCAST_FAVORITE_CHANGED);
|
||||
registerReceiver(mStateReceiver, filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
unregisterReceiver(mStateReceiver);
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] getSavedStatusesFileArgs() {
|
||||
final Bundle args = getArguments();
|
||||
if (args == null) return null;
|
||||
final long account_id = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
final long user_id = args.getLong(EXTRA_USER_ID, -1);
|
||||
final String screen_name = args.getString(EXTRA_SCREEN_NAME);
|
||||
return new String[] { AUTHORITY_USER_FAVORITES, "account" + account_id, "user" + user_id, "name" + screen_name };
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldShowAccountColor() {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public Loader<List<ParcelableStatus>> onCreateLoader(int id, Bundle args) {
|
||||
setRefreshing(true);
|
||||
final List<ParcelableStatus> data = getAdapterData();
|
||||
final Context context = getActivity();
|
||||
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
final long maxId = args.getLong(EXTRA_MAX_ID, -1);
|
||||
final long sinceId = args.getLong(EXTRA_SINCE_ID, -1);
|
||||
final long userId = args.getLong(EXTRA_USER_ID, -1);
|
||||
final String screenName = args.getString(EXTRA_SCREEN_NAME);
|
||||
final int tabPosition = args.getInt(EXTRA_TAB_POSITION, -1);
|
||||
return new UserFavoritesLoader(context, accountId, userId, screenName, maxId, sinceId, data,
|
||||
null, tabPosition);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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.fragment.support;
|
||||
|
||||
import static org.mariotaku.twidere.util.Utils.getAccountId;
|
||||
import static org.mariotaku.twidere.util.Utils.isSameAccount;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.content.Loader;
|
||||
|
||||
import org.mariotaku.twidere.adapter.iface.IStatusesListAdapter;
|
||||
import org.mariotaku.twidere.loader.support.UserFavoritesLoader;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserFavoritesFragmentOld extends ParcelableStatusesListFragment {
|
||||
|
||||
private long mUserId;
|
||||
private String mUserScreenName;
|
||||
|
||||
private final BroadcastReceiver mStateReceiver = new BroadcastReceiver() {
|
||||
|
||||
@Override
|
||||
public void onReceive(final Context context, final Intent intent) {
|
||||
if (getActivity() == null || !isAdded() || isDetached()) return;
|
||||
final String action = intent.getAction();
|
||||
if (BROADCAST_FAVORITE_CHANGED.equals(action)) {
|
||||
final ParcelableStatus status = intent.getParcelableExtra(EXTRA_STATUS);
|
||||
if (status == null) return;
|
||||
if ((isSameAccount(context, status.account_id, mUserId) || isSameAccount(context, status.account_id,
|
||||
mUserScreenName)) && status.id > 0 && !intent.getBooleanExtra(EXTRA_FAVORITED, true)) {
|
||||
deleteStatus(status.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@Override
|
||||
public Loader<List<ParcelableStatus>> newLoaderInstance(final Context context, final Bundle args) {
|
||||
if (args == null) return null;
|
||||
final long account_id = args.getLong(EXTRA_ACCOUNT_ID);
|
||||
final long user_id = args.getLong(EXTRA_USER_ID, -1);
|
||||
final long max_id = args.getLong(EXTRA_MAX_ID, -1);
|
||||
final long since_id = args.getLong(EXTRA_SINCE_ID, -1);
|
||||
final String screen_name = args.getString(EXTRA_SCREEN_NAME);
|
||||
final int tab_position = args.getInt(EXTRA_TAB_POSITION, -1);
|
||||
mUserId = user_id;
|
||||
mUserScreenName = screen_name;
|
||||
return new UserFavoritesLoader(getActivity(), account_id, user_id, screen_name, max_id, since_id, getData(),
|
||||
getSavedStatusesFileArgs(), tab_position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
final Bundle args = getArguments();
|
||||
final long account_id = args != null ? args.getLong(EXTRA_ACCOUNT_ID, -1) : -1;
|
||||
final long user_id = args != null ? args.getLong(EXTRA_USER_ID, -1) : -1;
|
||||
final String screen_name = args != null ? args.getString(EXTRA_SCREEN_NAME) : null;
|
||||
final boolean is_my_timeline = user_id > 0 ? account_id == user_id : account_id == getAccountId(getActivity(),
|
||||
screen_name);
|
||||
final IStatusesListAdapter<List<ParcelableStatus>> adapter = getListAdapter();
|
||||
adapter.setFavoritesHightlightDisabled(is_my_timeline);
|
||||
adapter.setFiltersEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
final IntentFilter filter = new IntentFilter(BROADCAST_FAVORITE_CHANGED);
|
||||
registerReceiver(mStateReceiver, filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
unregisterReceiver(mStateReceiver);
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] getSavedStatusesFileArgs() {
|
||||
final Bundle args = getArguments();
|
||||
if (args == null) return null;
|
||||
final long account_id = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
final long user_id = args.getLong(EXTRA_USER_ID, -1);
|
||||
final String screen_name = args.getString(EXTRA_SCREEN_NAME);
|
||||
return new String[] { AUTHORITY_USER_FAVORITES, "account" + account_id, "user" + user_id, "name" + screen_name };
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldShowAccountColor() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -108,11 +108,11 @@ import org.mariotaku.twidere.util.TwidereLinkify.OnLinkClickListener;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.util.menu.TwidereMenuInfo;
|
||||
import org.mariotaku.twidere.view.CircularImageView;
|
||||
import org.mariotaku.twidere.view.ColorLabelLinearLayout;
|
||||
import org.mariotaku.twidere.view.HeaderDrawerLayout;
|
||||
import org.mariotaku.twidere.view.HeaderDrawerLayout.DrawerCallback;
|
||||
import org.mariotaku.twidere.view.ProfileBannerImageView;
|
||||
import org.mariotaku.twidere.view.TintedStatusFrameLayout;
|
||||
import org.mariotaku.twidere.view.iface.IColorLabelView;
|
||||
import org.mariotaku.twidere.view.iface.IExtendedView.OnSizeChangedListener;
|
||||
|
||||
import java.util.Locale;
|
||||
@ -171,10 +171,9 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
private View mDescriptionContainer, mLocationContainer, mURLContainer, mListedContainer, mFollowersContainer,
|
||||
mFriendsContainer;
|
||||
private Button mRetryButton;
|
||||
private ColorLabelLinearLayout mProfileNameContainer;
|
||||
private IColorLabelView mProfileNameContainer;
|
||||
private View mProgressContainer, mErrorRetryContainer;
|
||||
private View mFollowingYouIndicator;
|
||||
private View mMainContent;
|
||||
private View mCardContent;
|
||||
private View mProfileBannerSpace;
|
||||
private TintedStatusFrameLayout mTintedStatusContent;
|
||||
private HeaderDrawerLayout mHeaderDrawerLayout;
|
||||
@ -182,6 +181,8 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
private PagerSlidingTabStrip mPagerIndicator;
|
||||
private CardView mCardView;
|
||||
private View mUuckyFooter;
|
||||
private View mProfileBannerContainer;
|
||||
private Button mFollowButton;
|
||||
|
||||
private SupportTabsAdapter mPagerAdapter;
|
||||
|
||||
@ -233,8 +234,12 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
|
||||
@Override
|
||||
public Loader<SingleResponse<ParcelableUser>> onCreateLoader(final int id, final Bundle args) {
|
||||
if (mUser == null) {
|
||||
mMainContent.setVisibility(View.VISIBLE);
|
||||
final boolean omitIntentExtra = args.getBoolean(EXTRA_OMIT_INTENT_EXTRA, true);
|
||||
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
final long userId = args.getLong(EXTRA_USER_ID, -1);
|
||||
final String screenName = args.getString(EXTRA_SCREEN_NAME);
|
||||
if (mUser == null && (!omitIntentExtra || !args.containsKey(EXTRA_USER))) {
|
||||
mCardContent.setVisibility(View.GONE);
|
||||
mErrorRetryContainer.setVisibility(View.GONE);
|
||||
mProgressContainer.setVisibility(View.VISIBLE);
|
||||
mErrorMessageView.setText(null);
|
||||
@ -243,10 +248,6 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
}
|
||||
setProgressBarIndeterminateVisibility(true);
|
||||
final ParcelableUser user = mUser;
|
||||
final boolean omitIntentExtra = args.getBoolean(EXTRA_OMIT_INTENT_EXTRA, true);
|
||||
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
final long userId = args.getLong(EXTRA_USER_ID, -1);
|
||||
final String screenName = args.getString(EXTRA_SCREEN_NAME);
|
||||
return new ParcelableUserLoader(getActivity(), accountId, userId, screenName, getArguments(),
|
||||
omitIntentExtra, user == null || !user.is_cache && userId != user.id);
|
||||
}
|
||||
@ -262,7 +263,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
if (getActivity() == null) return;
|
||||
if (data.getData() != null && data.getData().id > 0) {
|
||||
final ParcelableUser user = data.getData();
|
||||
mMainContent.setVisibility(View.VISIBLE);
|
||||
mCardContent.setVisibility(View.VISIBLE);
|
||||
mErrorRetryContainer.setVisibility(View.GONE);
|
||||
mProgressContainer.setVisibility(View.GONE);
|
||||
setListShown(true);
|
||||
@ -276,7 +277,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
getLoaderManager().restartLoader(LOADER_ID_USER, args, this);
|
||||
}
|
||||
} else if (mUser != null && mUser.is_cache) {
|
||||
mMainContent.setVisibility(View.VISIBLE);
|
||||
mCardContent.setVisibility(View.VISIBLE);
|
||||
mErrorRetryContainer.setVisibility(View.GONE);
|
||||
mProgressContainer.setVisibility(View.GONE);
|
||||
setListShown(true);
|
||||
@ -286,7 +287,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
mErrorMessageView.setText(getErrorMessage(getActivity(), data.getException()));
|
||||
mErrorMessageView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
mMainContent.setVisibility(View.GONE);
|
||||
mCardContent.setVisibility(View.GONE);
|
||||
mErrorRetryContainer.setVisibility(View.VISIBLE);
|
||||
mProgressContainer.setVisibility(View.GONE);
|
||||
}
|
||||
@ -299,6 +300,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
@Override
|
||||
public Loader<SingleResponse<Relationship>> onCreateLoader(final int id, final Bundle args) {
|
||||
invalidateOptionsMenu();
|
||||
mFollowButton.setVisibility(View.GONE);
|
||||
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
final long userId = args.getLong(EXTRA_USER_ID, -1);
|
||||
return new FriendshipLoader(getActivity(), accountId, userId);
|
||||
@ -317,10 +319,18 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
final Relationship relationship = mRelationship = data.getData();
|
||||
if (user == null) return;
|
||||
invalidateOptionsMenu();
|
||||
if (relationship != null) {
|
||||
final boolean isMyself = user.account_id == user.id;
|
||||
final boolean isFollowingYou = relationship.isTargetFollowingSource();
|
||||
mFollowingYouIndicator.setVisibility(!isMyself && isFollowingYou ? View.VISIBLE : View.GONE);
|
||||
final boolean isMyself = user.account_id == user.id;
|
||||
if (isMyself) {
|
||||
mFollowButton.setText(R.string.edit);
|
||||
mFollowButton.setVisibility(View.VISIBLE);
|
||||
} else if (relationship != null) {
|
||||
if (relationship.isSourceBlockingTarget()) {
|
||||
mFollowButton.setText(R.string.unblock);
|
||||
} else if (relationship.isSourceFollowingTarget()) {
|
||||
mFollowButton.setText(R.string.unfollow);
|
||||
} else {
|
||||
mFollowButton.setText(R.string.follow);
|
||||
}
|
||||
final ContentResolver resolver = getContentResolver();
|
||||
final String where = Where.equals(CachedUsers.USER_ID, user.id).getSQL();
|
||||
resolver.delete(CachedUsers.CONTENT_URI, where, null);
|
||||
@ -332,8 +342,11 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
resolver.insert(CachedUsers.CONTENT_URI, cachedValues);
|
||||
}
|
||||
}
|
||||
mFollowButton.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mFollowingYouIndicator.setVisibility(View.GONE);
|
||||
mFollowButton.setText(null);
|
||||
mFollowButton.setVisibility(View.GONE);
|
||||
// mFollowingYouIndicator.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -348,6 +361,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
lm.destroyLoader(LOADER_ID_USER);
|
||||
lm.destroyLoader(LOADER_ID_FRIENDSHIP);
|
||||
final boolean userIsMe = user.account_id == user.id;
|
||||
mCardContent.setVisibility(View.VISIBLE);
|
||||
mErrorRetryContainer.setVisibility(View.GONE);
|
||||
mProgressContainer.setVisibility(View.GONE);
|
||||
mUser = user;
|
||||
@ -466,6 +480,14 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldLayoutHeaderBottom() {
|
||||
final HeaderDrawerLayout drawer = mHeaderDrawerLayout;
|
||||
final CardView card = mCardView;
|
||||
if (drawer == null || card == null) return false;
|
||||
return card.getTop() + drawer.getHeaderTop() - drawer.getPaddingTop() <= 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment getCurrentVisibleFragment() {
|
||||
return mCurrentVisibleFragment;
|
||||
@ -497,7 +519,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
lm.destroyLoader(LOADER_ID_USER);
|
||||
lm.destroyLoader(LOADER_ID_FRIENDSHIP);
|
||||
if (!isMyAccount(getActivity(), accountId)) {
|
||||
mMainContent.setVisibility(View.GONE);
|
||||
mCardContent.setVisibility(View.GONE);
|
||||
mErrorRetryContainer.setVisibility(View.GONE);
|
||||
return;
|
||||
}
|
||||
@ -513,7 +535,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
lm.restartLoader(LOADER_ID_USER, args, mUserInfoLoaderCallbacks);
|
||||
}
|
||||
if (accountId == -1 || userId == -1 && screenName == null) {
|
||||
mMainContent.setVisibility(View.GONE);
|
||||
mCardContent.setVisibility(View.GONE);
|
||||
mErrorRetryContainer.setVisibility(View.GONE);
|
||||
return;
|
||||
}
|
||||
@ -598,6 +620,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
|
||||
mPagerAdapter = new SupportTabsAdapter(activity, getChildFragmentManager());
|
||||
|
||||
mViewPager.setOffscreenPageLimit(3);
|
||||
mViewPager.setAdapter(mPagerAdapter);
|
||||
mPagerIndicator.setViewPager(mViewPager);
|
||||
|
||||
@ -766,7 +789,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
public void onGenerated(Palette palette) {
|
||||
final ParcelableUser user = mUser;
|
||||
if (user == null) return;
|
||||
final int color = palette.getVibrantColor(0);
|
||||
final int color = palette.getDarkVibrantColor(user.link_color);
|
||||
setupUserColorActionBar(color);
|
||||
}
|
||||
});
|
||||
@ -804,17 +827,17 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
|
||||
@Override
|
||||
public void onViewCreated(final View view, final Bundle savedInstanceState) {
|
||||
final Context context = view.getContext();
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
mMainContent = view.findViewById(R.id.details_container);
|
||||
mHeaderDrawerLayout = (HeaderDrawerLayout) view.findViewById(R.id.user_profile_drawer);
|
||||
mErrorRetryContainer = view.findViewById(R.id.error_retry_container);
|
||||
mProgressContainer = view.findViewById(R.id.progress_container);
|
||||
mRetryButton = (Button) view.findViewById(R.id.retry);
|
||||
mErrorMessageView = (TextView) view.findViewById(R.id.error_message);
|
||||
mProfileBannerView = (ProfileBannerImageView) view.findViewById(R.id.profile_banner);
|
||||
final View headerView = mHeaderDrawerLayout.getHeader();
|
||||
final View contentView = mHeaderDrawerLayout.getContent();
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
mCardContent = headerView.findViewById(R.id.card_content);
|
||||
mErrorRetryContainer = headerView.findViewById(R.id.error_retry_container);
|
||||
mProgressContainer = headerView.findViewById(R.id.progress_container);
|
||||
mRetryButton = (Button) headerView.findViewById(R.id.retry);
|
||||
mErrorMessageView = (TextView) headerView.findViewById(R.id.error_message);
|
||||
mProfileBannerView = (ProfileBannerImageView) view.findViewById(R.id.profile_banner);
|
||||
mProfileBannerContainer = view.findViewById(R.id.profile_banner_container);
|
||||
mCardView = (CardView) headerView.findViewById(R.id.card);
|
||||
mNameView = (TextView) headerView.findViewById(R.id.name);
|
||||
mScreenNameView = (TextView) headerView.findViewById(R.id.screen_name);
|
||||
@ -828,37 +851,24 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
mFollowersCount = (TextView) headerView.findViewById(R.id.followers_count);
|
||||
mFriendsContainer = headerView.findViewById(R.id.friends_container);
|
||||
mFriendsCount = (TextView) headerView.findViewById(R.id.friends_count);
|
||||
mProfileNameContainer = (ColorLabelLinearLayout) headerView.findViewById(R.id.profile_name_container);
|
||||
mProfileNameContainer = (IColorLabelView) headerView.findViewById(R.id.profile_name_container);
|
||||
mProfileImageView = (CircularImageView) headerView.findViewById(R.id.profile_image);
|
||||
mProfileTypeView = (ImageView) headerView.findViewById(R.id.profile_type);
|
||||
mDescriptionContainer = headerView.findViewById(R.id.description_container);
|
||||
mLocationContainer = headerView.findViewById(R.id.location_container);
|
||||
mURLContainer = headerView.findViewById(R.id.url_container);
|
||||
mFollowingYouIndicator = headerView.findViewById(R.id.following_you_indicator);
|
||||
mProfileBannerSpace = headerView.findViewById(R.id.profile_banner_space);
|
||||
mViewPager = (ViewPager) contentView.findViewById(R.id.view_pager);
|
||||
mPagerIndicator = (PagerSlidingTabStrip) contentView.findViewById(R.id.view_pager_tabs);
|
||||
mFollowButton = (Button) headerView.findViewById(R.id.follow);
|
||||
mUuckyFooter = headerView.findViewById(R.id.uucky_footer);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fitSystemWindows(Rect insets) {
|
||||
super.fitSystemWindows(insets);
|
||||
final View view = getView();
|
||||
if (view != null) {
|
||||
final View progress = view.findViewById(R.id.progress_container);
|
||||
progress.setPadding(insets.left, insets.top, insets.right, insets.bottom);
|
||||
}
|
||||
mErrorRetryContainer.setPadding(insets.left, insets.top, insets.right, insets.bottom);
|
||||
mHeaderDrawerLayout.setPadding(insets.left, insets.top, insets.right, insets.bottom);
|
||||
mHeaderDrawerLayout.setClipToPadding(ThemeUtils.isTransparentBackground(getActivity()));
|
||||
final int bannerHeight = mProfileBannerView.getHeight();
|
||||
if (bannerHeight != 0) {
|
||||
final ViewGroup.LayoutParams params = mProfileBannerSpace.getLayoutParams();
|
||||
params.height = bannerHeight - insets.top;
|
||||
mProfileBannerSpace.setLayoutParams(params);
|
||||
mProfileBannerSpace.requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
public void setListShown(boolean shown) {
|
||||
@ -1147,13 +1157,13 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
|
||||
private void updateScrollOffset(int offset) {
|
||||
final View space = mProfileBannerSpace;
|
||||
if (space == null) return;
|
||||
final ProfileBannerImageView profileBannerView = mProfileBannerView;
|
||||
final View profileBannerContainer = mProfileBannerContainer;
|
||||
final int spaceHeight = space.getHeight();
|
||||
final float factor = MathUtils.clamp(offset / (float) spaceHeight, 0, 1);
|
||||
final ProfileBannerImageView profileBannerView = mProfileBannerView;
|
||||
profileBannerView.setAlpha(1.0f - factor / 8f);
|
||||
profileBannerView.setTranslationY(Math.min(offset, spaceHeight) / -2);
|
||||
profileBannerView.setBottomClip(Math.min(offset, spaceHeight));
|
||||
profileBannerContainer.setTranslationY(-offset);
|
||||
profileBannerView.setTranslationY(Math.min(offset, spaceHeight) / 2);
|
||||
|
||||
if (mActionBarBackground != null && mTintedStatusContent != null) {
|
||||
mActionBarBackground.setFactor(factor);
|
||||
|
@ -451,6 +451,11 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldLayoutHeaderBottom() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canScroll(float dy) {
|
||||
return false;
|
||||
|
@ -15,7 +15,6 @@ import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
@ -25,6 +24,8 @@ import org.mariotaku.twidere.model.ParcelableMedia;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
||||
import org.mariotaku.twidere.util.ImageLoadingHandler;
|
||||
import org.mariotaku.twidere.util.SimpleDrawerCallback;
|
||||
import org.mariotaku.twidere.view.HeaderDrawerLayout.DrawerCallback;
|
||||
import org.mariotaku.twidere.view.MediaSizeImageView;
|
||||
|
||||
import java.util.List;
|
||||
@ -33,12 +34,50 @@ import java.util.List;
|
||||
* Created by mariotaku on 14/11/5.
|
||||
*/
|
||||
public class UserMediaTimelineFragment extends BaseSupportFragment
|
||||
implements LoaderCallbacks<List<ParcelableStatus>> {
|
||||
implements LoaderCallbacks<List<ParcelableStatus>>, DrawerCallback {
|
||||
|
||||
private View mProgressContainer;
|
||||
private RecyclerView mRecyclerView;
|
||||
private ProgressBar mProgress;
|
||||
|
||||
private MediaTimelineAdapter mAdapter;
|
||||
|
||||
@Override
|
||||
public void fling(float velocity) {
|
||||
mDrawerCallback.fling(velocity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scrollBy(float dy) {
|
||||
mDrawerCallback.scrollBy(dy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldLayoutHeaderBottom() {
|
||||
return mDrawerCallback.shouldLayoutHeaderBottom();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canScroll(float dy) {
|
||||
return mDrawerCallback.canScroll(dy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isScrollContent(float x, float y) {
|
||||
return mDrawerCallback.isScrollContent(x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelTouch() {
|
||||
mDrawerCallback.cancelTouch();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void topChanged(int offset) {
|
||||
mDrawerCallback.topChanged(offset);
|
||||
}
|
||||
|
||||
private SimpleDrawerCallback mDrawerCallback;
|
||||
|
||||
private OnScrollListener mOnScrollListener = new OnScrollListener() {
|
||||
@Override
|
||||
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
||||
@ -49,10 +88,11 @@ public class UserMediaTimelineFragment extends BaseSupportFragment
|
||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
final View view = getView();
|
||||
assert view != null;
|
||||
if (view == null) throw new AssertionError();
|
||||
final Context context = view.getContext();
|
||||
mAdapter = new MediaTimelineAdapter(context);
|
||||
final StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
|
||||
mDrawerCallback = new SimpleDrawerCallback(mRecyclerView);
|
||||
mRecyclerView.setLayoutManager(layoutManager);
|
||||
mRecyclerView.setAdapter(mAdapter);
|
||||
mRecyclerView.setOnScrollListener(mOnScrollListener);
|
||||
@ -62,7 +102,7 @@ public class UserMediaTimelineFragment extends BaseSupportFragment
|
||||
|
||||
public void setListShown(boolean shown) {
|
||||
mRecyclerView.setVisibility(shown ? View.VISIBLE : View.GONE);
|
||||
mProgress.setVisibility(shown ? View.GONE : View.VISIBLE);
|
||||
mProgressContainer.setVisibility(shown ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
|
||||
public int getStatuses(final long maxId, final long sinceId) {
|
||||
@ -76,8 +116,8 @@ public class UserMediaTimelineFragment extends BaseSupportFragment
|
||||
@Override
|
||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
mProgressContainer = view.findViewById(R.id.progress_container);
|
||||
mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
|
||||
mProgress = (ProgressBar) view.findViewById(R.id.progress);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,123 +1,42 @@
|
||||
/*
|
||||
* 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.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;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.support.v4.widget.SwipeRefreshLayout;
|
||||
import android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener;
|
||||
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;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.ParcelableStatusesAdapter;
|
||||
import org.mariotaku.twidere.adapter.decorator.DividerItemDecoration;
|
||||
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.HeaderDrawerLayout.DrawerCallback;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/11/5.
|
||||
* Created by mariotaku on 14/12/2.
|
||||
*/
|
||||
public class UserTimelineFragment extends BaseSupportFragment
|
||||
implements LoaderCallbacks<List<ParcelableStatus>>, OnRefreshListener, DrawerCallback {
|
||||
|
||||
private SwipeRefreshLayout mSwipeRefreshLayout;
|
||||
private RecyclerView mRecyclerView;
|
||||
private ProgressBar mProgressBar;
|
||||
|
||||
private ParcelableStatusesAdapter mAdapter;
|
||||
private OnScrollListener mOnScrollListener = new OnScrollListener() {
|
||||
@Override
|
||||
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
|
||||
super.onScrollStateChanged(recyclerView, newState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
||||
final LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
|
||||
final LoaderManager lm = getLoaderManager();
|
||||
if (lm.hasRunningLoaders()) return;
|
||||
if (layoutManager.findLastVisibleItemPosition() == mAdapter.getItemCount() - 1) {
|
||||
getStatuses(mAdapter.getStatus(mAdapter.getStatusCount() - 1).id, 0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
final View view = getView();
|
||||
assert view != null;
|
||||
final Context context = view.getContext();
|
||||
final boolean compact = Utils.isCompactCards(context);
|
||||
mSwipeRefreshLayout.setOnRefreshListener(this);
|
||||
mSwipeRefreshLayout.setColorSchemeColors(ThemeUtils.getUserAccentColor(context));
|
||||
mAdapter = new ParcelableStatusesAdapter(context, compact);
|
||||
final LinearLayoutManager layoutManager = new LinearLayoutManager(context);
|
||||
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
|
||||
mRecyclerView.setLayoutManager(layoutManager);
|
||||
if (compact) {
|
||||
mRecyclerView.addItemDecoration(new DividerItemDecoration(context, layoutManager.getOrientation()));
|
||||
}
|
||||
mRecyclerView.setAdapter(mAdapter);
|
||||
mRecyclerView.setOnScrollListener(mOnScrollListener);
|
||||
getLoaderManager().initLoader(0, getArguments(), this);
|
||||
setListShown(false);
|
||||
}
|
||||
|
||||
private void setListShown(boolean shown) {
|
||||
mProgressBar.setVisibility(shown ? View.GONE : View.VISIBLE);
|
||||
mSwipeRefreshLayout.setVisibility(shown ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
|
||||
public int getStatuses(final long maxId, final long sinceId) {
|
||||
final Bundle args = new Bundle(getArguments());
|
||||
args.putLong(EXTRA_MAX_ID, maxId);
|
||||
args.putLong(EXTRA_SINCE_ID, sinceId);
|
||||
getLoaderManager().restartLoader(0, args, this);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_layout);
|
||||
mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
|
||||
mProgressBar = (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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.fragment_recycler_view, container, false);
|
||||
}
|
||||
public class UserTimelineFragment extends ParcelableStatusesFragment {
|
||||
|
||||
@Override
|
||||
public Loader<List<ParcelableStatus>> onCreateLoader(int id, Bundle args) {
|
||||
// mSwipeRefreshLayout.setRefreshing(true);
|
||||
final List<ParcelableStatus> data = mAdapter.getData();
|
||||
setRefreshing(true);
|
||||
final List<ParcelableStatus> data = getAdapterData();
|
||||
final Context context = getActivity();
|
||||
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
final long maxId = args.getLong(EXTRA_MAX_ID, -1);
|
||||
@ -129,57 +48,4 @@ public class UserTimelineFragment extends BaseSupportFragment
|
||||
null, tabPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(Loader<List<ParcelableStatus>> loader, List<ParcelableStatus> data) {
|
||||
mSwipeRefreshLayout.setRefreshing(false);
|
||||
mAdapter.setData(data);
|
||||
setListShown(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<List<ParcelableStatus>> loader) {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onRefresh() {
|
||||
if (mAdapter.getStatusCount() > 0) {
|
||||
getStatuses(0, mAdapter.getStatus(0).id);
|
||||
} else {
|
||||
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) {
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -7,24 +7,65 @@ import android.graphics.drawable.Drawable;
|
||||
|
||||
public class EmptyDrawable extends Drawable {
|
||||
|
||||
@Override
|
||||
public void draw(final Canvas canvas) {
|
||||
private final int mIntrinsicWidth, mIntrinsicHeight, mMinimumWidth, mMinimumHeight;
|
||||
|
||||
}
|
||||
@Override
|
||||
public int getMinimumHeight() {
|
||||
return mMinimumHeight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity() {
|
||||
return PixelFormat.TRANSPARENT;
|
||||
}
|
||||
@Override
|
||||
public int getMinimumWidth() {
|
||||
return mMinimumWidth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(final int alpha) {
|
||||
@Override
|
||||
public int getIntrinsicHeight() {
|
||||
return mIntrinsicHeight;
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public int getIntrinsicWidth() {
|
||||
return mIntrinsicWidth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(final ColorFilter cf) {
|
||||
|
||||
}
|
||||
public EmptyDrawable() {
|
||||
this(0, 0, -1, -1);
|
||||
}
|
||||
|
||||
public EmptyDrawable(int minimumWidth, int minimumHeight, int intrinsicWidth, int intrinsicHeight) {
|
||||
mMinimumWidth = minimumWidth;
|
||||
mMinimumHeight = minimumHeight;
|
||||
mIntrinsicWidth = intrinsicWidth;
|
||||
mIntrinsicHeight = intrinsicHeight;
|
||||
}
|
||||
|
||||
public EmptyDrawable(Drawable drawableToCopySize) {
|
||||
mMinimumWidth = drawableToCopySize.getMinimumWidth();
|
||||
mMinimumHeight = drawableToCopySize.getMinimumHeight();
|
||||
mIntrinsicWidth = drawableToCopySize.getIntrinsicWidth();
|
||||
mIntrinsicHeight = drawableToCopySize.getIntrinsicHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(final Canvas canvas) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity() {
|
||||
return PixelFormat.TRANSPARENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(final int alpha) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(final ColorFilter cf) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -27,149 +27,150 @@ import org.mariotaku.twidere.fragment.support.ActivitiesAboutMeFragment;
|
||||
import org.mariotaku.twidere.fragment.support.ActivitiesByFriendsFragment;
|
||||
import org.mariotaku.twidere.fragment.support.DirectMessagesFragment;
|
||||
import org.mariotaku.twidere.fragment.support.HomeTimelineFragment;
|
||||
import org.mariotaku.twidere.fragment.support.HomeTimelineListFragment;
|
||||
import org.mariotaku.twidere.fragment.support.MentionsTimelineFragment;
|
||||
import org.mariotaku.twidere.fragment.support.SearchStatusesFragment;
|
||||
import org.mariotaku.twidere.fragment.support.TrendsSuggectionsFragment;
|
||||
import org.mariotaku.twidere.fragment.support.UserFavoritesFragment;
|
||||
import org.mariotaku.twidere.fragment.support.UserListTimelineFragment;
|
||||
import org.mariotaku.twidere.fragment.support.UserTimelineFragmentOld;
|
||||
import org.mariotaku.twidere.fragment.support.UserTimelineFragment;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public enum CustomTabConfiguration2 implements Constants {
|
||||
|
||||
HOME_TIMELINE(HomeTimelineFragment.class, R.string.home, R.drawable.ic_action_home,
|
||||
CustomTabConfiguration.ACCOUNT_OPTIONAL, CustomTabConfiguration.FIELD_TYPE_NONE, 0, false),
|
||||
HOME_TIMELINE(HomeTimelineFragment.class, R.string.home, R.drawable.ic_action_home,
|
||||
CustomTabConfiguration.ACCOUNT_OPTIONAL, CustomTabConfiguration.FIELD_TYPE_NONE, 0, false),
|
||||
|
||||
MENTIONS_TIMELINE(MentionsTimelineFragment.class, R.string.mentions, R.drawable.ic_action_at,
|
||||
CustomTabConfiguration.ACCOUNT_OPTIONAL, CustomTabConfiguration.FIELD_TYPE_NONE, 1, false),
|
||||
MENTIONS_TIMELINE(MentionsTimelineFragment.class, R.string.mentions, R.drawable.ic_action_at,
|
||||
CustomTabConfiguration.ACCOUNT_OPTIONAL, CustomTabConfiguration.FIELD_TYPE_NONE, 1, false),
|
||||
|
||||
DIRECT_MESSAGES(DirectMessagesFragment.class, R.string.direct_messages, R.drawable.ic_action_message,
|
||||
CustomTabConfiguration.ACCOUNT_OPTIONAL, CustomTabConfiguration.FIELD_TYPE_NONE, 2, false),
|
||||
DIRECT_MESSAGES(DirectMessagesFragment.class, R.string.direct_messages, R.drawable.ic_action_message,
|
||||
CustomTabConfiguration.ACCOUNT_OPTIONAL, CustomTabConfiguration.FIELD_TYPE_NONE, 2, false),
|
||||
|
||||
TRENDS_SUGGESTIONS(TrendsSuggectionsFragment.class, R.string.trends, R.drawable.ic_action_hashtag,
|
||||
CustomTabConfiguration.ACCOUNT_NONE, CustomTabConfiguration.FIELD_TYPE_NONE, 3, true),
|
||||
TRENDS_SUGGESTIONS(TrendsSuggectionsFragment.class, R.string.trends, R.drawable.ic_action_hashtag,
|
||||
CustomTabConfiguration.ACCOUNT_NONE, CustomTabConfiguration.FIELD_TYPE_NONE, 3, true),
|
||||
|
||||
FAVORITES(UserFavoritesFragment.class, R.string.favorites, R.drawable.ic_action_star,
|
||||
CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_USER, 4),
|
||||
FAVORITES(UserFavoritesFragment.class, R.string.favorites, R.drawable.ic_action_star,
|
||||
CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_USER, 4),
|
||||
|
||||
USER_TIMELINE(UserTimelineFragmentOld.class, R.string.users_statuses, R.drawable.ic_action_quote,
|
||||
CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_USER, 5),
|
||||
USER_TIMELINE(UserTimelineFragment.class, R.string.users_statuses, R.drawable.ic_action_quote,
|
||||
CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_USER, 5),
|
||||
|
||||
SEARCH_STATUSES(SearchStatusesFragment.class, R.string.search_statuses, R.drawable.ic_action_search,
|
||||
CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_TEXT, R.string.query,
|
||||
EXTRA_QUERY, 6),
|
||||
SEARCH_STATUSES(SearchStatusesFragment.class, R.string.search_statuses, R.drawable.ic_action_search,
|
||||
CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_TEXT, R.string.query,
|
||||
EXTRA_QUERY, 6),
|
||||
|
||||
LIST_TIMELINE(UserListTimelineFragment.class, R.string.list_timeline, R.drawable.ic_action_list,
|
||||
CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_USER_LIST, 7),
|
||||
LIST_TIMELINE(UserListTimelineFragment.class, R.string.list_timeline, R.drawable.ic_action_list,
|
||||
CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_USER_LIST, 7),
|
||||
|
||||
ACTIVITIES_ABOUT_ME(ActivitiesAboutMeFragment.class, R.string.activities_about_me,
|
||||
R.drawable.ic_action_user, CustomTabConfiguration.ACCOUNT_OPTIONAL,
|
||||
CustomTabConfiguration.FIELD_TYPE_NONE, 8),
|
||||
ACTIVITIES_ABOUT_ME(ActivitiesAboutMeFragment.class, R.string.activities_about_me,
|
||||
R.drawable.ic_action_user, CustomTabConfiguration.ACCOUNT_OPTIONAL,
|
||||
CustomTabConfiguration.FIELD_TYPE_NONE, 8),
|
||||
|
||||
ACTIVITIES_BY_FRIENDS(ActivitiesByFriendsFragment.class, R.string.activities_by_friends,
|
||||
R.drawable.ic_action_accounts, CustomTabConfiguration.ACCOUNT_REQUIRED,
|
||||
CustomTabConfiguration.FIELD_TYPE_NONE, 9);
|
||||
ACTIVITIES_BY_FRIENDS(ActivitiesByFriendsFragment.class, R.string.activities_by_friends,
|
||||
R.drawable.ic_action_accounts, CustomTabConfiguration.ACCOUNT_REQUIRED,
|
||||
CustomTabConfiguration.FIELD_TYPE_NONE, 9);
|
||||
|
||||
public static final int FIELD_TYPE_NONE = 0;
|
||||
public static final int FIELD_TYPE_USER = 1;
|
||||
public static final int FIELD_TYPE_USER_LIST = 2;
|
||||
public static final int FIELD_TYPE_TEXT = 3;
|
||||
public static final int FIELD_TYPE_NONE = 0;
|
||||
public static final int FIELD_TYPE_USER = 1;
|
||||
public static final int FIELD_TYPE_USER_LIST = 2;
|
||||
public static final int FIELD_TYPE_TEXT = 3;
|
||||
|
||||
public static final int ACCOUNT_NONE = 0;
|
||||
public static final int ACCOUNT_REQUIRED = 1;
|
||||
public static final int ACCOUNT_OPTIONAL = 2;
|
||||
public static final int ACCOUNT_NONE = 0;
|
||||
public static final int ACCOUNT_REQUIRED = 1;
|
||||
public static final int ACCOUNT_OPTIONAL = 2;
|
||||
|
||||
private final int title, icon, secondaryFieldType, secondaryFieldTitle, sortPosition, accountRequirement;
|
||||
private final Class<? extends Fragment> cls;
|
||||
private final String secondaryFieldTextKey;
|
||||
private final boolean singleTab;
|
||||
private final int title, icon, secondaryFieldType, secondaryFieldTitle, sortPosition, accountRequirement;
|
||||
private final Class<? extends Fragment> cls;
|
||||
private final String secondaryFieldTextKey;
|
||||
private final boolean singleTab;
|
||||
|
||||
CustomTabConfiguration2(final Class<? extends Fragment> cls, final int title, final int icon,
|
||||
final int accountRequirement, final int secondaryFieldType, final int sortPosition) {
|
||||
this(cls, title, icon, accountRequirement, secondaryFieldType, 0, EXTRA_TEXT, sortPosition, false);
|
||||
}
|
||||
CustomTabConfiguration2(final Class<? extends Fragment> cls, final int title, final int icon,
|
||||
final int accountRequirement, final int secondaryFieldType, final int sortPosition) {
|
||||
this(cls, title, icon, accountRequirement, secondaryFieldType, 0, EXTRA_TEXT, sortPosition, false);
|
||||
}
|
||||
|
||||
CustomTabConfiguration2(final Class<? extends Fragment> cls, final int title, final int icon,
|
||||
final int accountRequirement, final int secondaryFieldType, final int sortPosition, final boolean singleTab) {
|
||||
this(cls, title, icon, accountRequirement, secondaryFieldType, 0, EXTRA_TEXT, sortPosition, singleTab);
|
||||
}
|
||||
CustomTabConfiguration2(final Class<? extends Fragment> cls, final int title, final int icon,
|
||||
final int accountRequirement, final int secondaryFieldType, final int sortPosition, final boolean singleTab) {
|
||||
this(cls, title, icon, accountRequirement, secondaryFieldType, 0, EXTRA_TEXT, sortPosition, singleTab);
|
||||
}
|
||||
|
||||
CustomTabConfiguration2(final Class<? extends Fragment> cls, final int title, final int icon,
|
||||
final int accountRequirement, final int secondaryFieldType, final int secondaryFieldTitle,
|
||||
final String secondaryFieldTextKey, final int sortPosition) {
|
||||
this(cls, title, icon, accountRequirement, secondaryFieldType, 0, secondaryFieldTextKey, sortPosition, false);
|
||||
}
|
||||
CustomTabConfiguration2(final Class<? extends Fragment> cls, final int title, final int icon,
|
||||
final int accountRequirement, final int secondaryFieldType, final int secondaryFieldTitle,
|
||||
final String secondaryFieldTextKey, final int sortPosition) {
|
||||
this(cls, title, icon, accountRequirement, secondaryFieldType, 0, secondaryFieldTextKey, sortPosition, false);
|
||||
}
|
||||
|
||||
CustomTabConfiguration2(final Class<? extends Fragment> cls, final int title, final int icon,
|
||||
final int accountRequirement, final int secondaryFieldType, final int secondaryFieldTitle,
|
||||
final String secondaryFieldTextKey, final int sortPosition, final boolean singleTab) {
|
||||
this.cls = cls;
|
||||
this.title = title;
|
||||
this.icon = icon;
|
||||
this.sortPosition = sortPosition;
|
||||
this.accountRequirement = accountRequirement;
|
||||
this.secondaryFieldType = secondaryFieldType;
|
||||
this.secondaryFieldTitle = secondaryFieldTitle;
|
||||
this.secondaryFieldTextKey = secondaryFieldTextKey;
|
||||
this.singleTab = singleTab;
|
||||
}
|
||||
CustomTabConfiguration2(final Class<? extends Fragment> cls, final int title, final int icon,
|
||||
final int accountRequirement, final int secondaryFieldType, final int secondaryFieldTitle,
|
||||
final String secondaryFieldTextKey, final int sortPosition, final boolean singleTab) {
|
||||
this.cls = cls;
|
||||
this.title = title;
|
||||
this.icon = icon;
|
||||
this.sortPosition = sortPosition;
|
||||
this.accountRequirement = accountRequirement;
|
||||
this.secondaryFieldType = secondaryFieldType;
|
||||
this.secondaryFieldTitle = secondaryFieldTitle;
|
||||
this.secondaryFieldTextKey = secondaryFieldTextKey;
|
||||
this.singleTab = singleTab;
|
||||
}
|
||||
|
||||
public int getAccountRequirement() {
|
||||
return accountRequirement;
|
||||
}
|
||||
public int getAccountRequirement() {
|
||||
return accountRequirement;
|
||||
}
|
||||
|
||||
public int getDefaultIcon() {
|
||||
return icon;
|
||||
}
|
||||
public int getDefaultIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
public int getDefaultTitle() {
|
||||
return title;
|
||||
}
|
||||
public int getDefaultTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public Class<? extends Fragment> getFragmentClass() {
|
||||
return cls;
|
||||
}
|
||||
public Class<? extends Fragment> getFragmentClass() {
|
||||
return cls;
|
||||
}
|
||||
|
||||
public String getSecondaryFieldTextKey() {
|
||||
return secondaryFieldTextKey;
|
||||
}
|
||||
public String getSecondaryFieldTextKey() {
|
||||
return secondaryFieldTextKey;
|
||||
}
|
||||
|
||||
public int getSecondaryFieldTitle() {
|
||||
return secondaryFieldTitle;
|
||||
}
|
||||
public int getSecondaryFieldTitle() {
|
||||
return secondaryFieldTitle;
|
||||
}
|
||||
|
||||
public int getSecondaryFieldType() {
|
||||
return secondaryFieldType;
|
||||
}
|
||||
public int getSecondaryFieldType() {
|
||||
return secondaryFieldType;
|
||||
}
|
||||
|
||||
public int getSortPosition() {
|
||||
return sortPosition;
|
||||
}
|
||||
public int getSortPosition() {
|
||||
return sortPosition;
|
||||
}
|
||||
|
||||
public boolean isSingleTab() {
|
||||
return singleTab;
|
||||
}
|
||||
public boolean isSingleTab() {
|
||||
return singleTab;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CustomTabConfiguration{title=" + title + ", icon=" + icon + ", secondaryFieldType="
|
||||
+ secondaryFieldType + ", secondaryFieldTitle=" + secondaryFieldTitle + ", sortPosition="
|
||||
+ sortPosition + ", accountRequirement=" + accountRequirement + ", cls=" + cls
|
||||
+ ", secondaryFieldTextKey=" + secondaryFieldTextKey + ", singleTab=" + singleTab + "}";
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CustomTabConfiguration{title=" + title + ", icon=" + icon + ", secondaryFieldType="
|
||||
+ secondaryFieldType + ", secondaryFieldTitle=" + secondaryFieldTitle + ", sortPosition="
|
||||
+ sortPosition + ", accountRequirement=" + accountRequirement + ", cls=" + cls
|
||||
+ ", secondaryFieldTextKey=" + secondaryFieldTextKey + ", singleTab=" + singleTab + "}";
|
||||
}
|
||||
|
||||
public static class CustomTabConfigurationComparator implements Comparator<Entry<String, CustomTabConfiguration2>> {
|
||||
public static class CustomTabConfigurationComparator implements Comparator<Entry<String, CustomTabConfiguration2>> {
|
||||
|
||||
public static final CustomTabConfigurationComparator SINGLETON = new CustomTabConfigurationComparator();
|
||||
public static final CustomTabConfigurationComparator SINGLETON = new CustomTabConfigurationComparator();
|
||||
|
||||
@Override
|
||||
public int compare(final Entry<String, CustomTabConfiguration2> lhs,
|
||||
final Entry<String, CustomTabConfiguration2> rhs) {
|
||||
return lhs.getValue().getSortPosition() - rhs.getValue().getSortPosition();
|
||||
}
|
||||
@Override
|
||||
public int compare(final Entry<String, CustomTabConfiguration2> lhs,
|
||||
final Entry<String, CustomTabConfiguration2> rhs) {
|
||||
return lhs.getValue().getSortPosition() - rhs.getValue().getSortPosition();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -30,8 +30,6 @@ import org.mariotaku.twidere.provider.TweetStore.CachedUsers;
|
||||
import org.mariotaku.twidere.provider.TweetStore.DirectMessages.ConversationEntries;
|
||||
import org.mariotaku.twidere.util.ParseUtils;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import twitter4j.URLEntity;
|
||||
import twitter4j.User;
|
||||
|
||||
@ -74,6 +72,8 @@ public class ParcelableUser implements TwidereParcelable, Comparable<ParcelableU
|
||||
|
||||
public final int followers_count, friends_count, statuses_count, favorites_count, listed_count;
|
||||
|
||||
public final int background_color, link_color, text_color;
|
||||
|
||||
public final boolean is_cache;
|
||||
|
||||
public ParcelableUser(final long account_id, final long id, final String name,
|
||||
@ -102,6 +102,9 @@ public class ParcelableUser implements TwidereParcelable, Comparable<ParcelableU
|
||||
statuses_count = 0;
|
||||
favorites_count = 0;
|
||||
listed_count = 0;
|
||||
background_color = 0;
|
||||
link_color = 0;
|
||||
text_color = 0;
|
||||
is_cache = true;
|
||||
}
|
||||
|
||||
@ -140,6 +143,9 @@ public class ParcelableUser implements TwidereParcelable, Comparable<ParcelableU
|
||||
is_cache = true;
|
||||
description_unescaped = toPlainText(description_html);
|
||||
is_following = cursor.getInt(cursor.getColumnIndex(CachedUsers.IS_FOLLOWING)) == 1;
|
||||
background_color = cursor.getInt(cursor.getColumnIndex(CachedUsers.BACKGROUND_COLOR));
|
||||
link_color = cursor.getInt(cursor.getColumnIndex(CachedUsers.LINK_COLOR));
|
||||
text_color = cursor.getInt(cursor.getColumnIndex(CachedUsers.TEXT_COLOR));
|
||||
}
|
||||
|
||||
public ParcelableUser(final JSONParcel in) {
|
||||
@ -152,6 +158,9 @@ public class ParcelableUser implements TwidereParcelable, Comparable<ParcelableU
|
||||
name = in.readString("name");
|
||||
screen_name = in.readString("screen_name");
|
||||
description_plain = in.readString("description_plain");
|
||||
description_html = in.readString("description_html");
|
||||
description_expanded = in.readString("description_expanded");
|
||||
description_unescaped = in.readString("description_unescaped");
|
||||
location = in.readString("location");
|
||||
profile_image_url = in.readString("profile_image_url");
|
||||
profile_banner_url = in.readString("profile_banner_url");
|
||||
@ -163,11 +172,11 @@ public class ParcelableUser implements TwidereParcelable, Comparable<ParcelableU
|
||||
favorites_count = in.readInt("favorites_count");
|
||||
listed_count = in.readInt("listed_count");
|
||||
is_cache = in.readBoolean("is_cache");
|
||||
description_html = in.readString("description_html");
|
||||
description_expanded = in.readString("description_expanded");
|
||||
url_expanded = in.readString("url_expanded");
|
||||
is_following = in.readBoolean("is_following");
|
||||
description_unescaped = in.readString("description_unescaped");
|
||||
background_color = in.readInt("background_color");
|
||||
link_color = in.readInt("link_color");
|
||||
text_color = in.readInt("text_color");
|
||||
}
|
||||
|
||||
public ParcelableUser(final Parcel in) {
|
||||
@ -180,6 +189,9 @@ public class ParcelableUser implements TwidereParcelable, Comparable<ParcelableU
|
||||
name = in.readString();
|
||||
screen_name = in.readString();
|
||||
description_plain = in.readString();
|
||||
description_html = in.readString();
|
||||
description_expanded = in.readString();
|
||||
description_unescaped = in.readString();
|
||||
location = in.readString();
|
||||
profile_image_url = in.readString();
|
||||
profile_banner_url = in.readString();
|
||||
@ -191,11 +203,11 @@ public class ParcelableUser implements TwidereParcelable, Comparable<ParcelableU
|
||||
favorites_count = in.readInt();
|
||||
listed_count = in.readInt();
|
||||
is_cache = in.readInt() == 1;
|
||||
description_html = in.readString();
|
||||
description_expanded = in.readString();
|
||||
url_expanded = in.readString();
|
||||
is_following = in.readInt() == 1;
|
||||
description_unescaped = in.readString();
|
||||
background_color = in.readInt();
|
||||
link_color = in.readInt();
|
||||
text_color = in.readInt();
|
||||
}
|
||||
|
||||
public ParcelableUser(final User user, final long account_id) {
|
||||
@ -207,7 +219,7 @@ public class ParcelableUser implements TwidereParcelable, Comparable<ParcelableU
|
||||
this.account_id = account_id;
|
||||
final URLEntity[] urls_url_entities = user.getURLEntities();
|
||||
id = user.getId();
|
||||
created_at = getTime(user.getCreatedAt());
|
||||
created_at = user.getCreatedAt().getTime();
|
||||
is_protected = user.isProtected();
|
||||
is_verified = user.isVerified();
|
||||
name = user.getName();
|
||||
@ -215,6 +227,7 @@ public class ParcelableUser implements TwidereParcelable, Comparable<ParcelableU
|
||||
description_plain = user.getDescription();
|
||||
description_html = formatUserDescription(user);
|
||||
description_expanded = formatExpandedUserDescription(user);
|
||||
description_unescaped = toPlainText(description_html);
|
||||
location = user.getLocation();
|
||||
profile_image_url = ParseUtils.parseString(user.getProfileImageUrlHttps());
|
||||
profile_banner_url = user.getProfileBannerImageUrl();
|
||||
@ -229,7 +242,9 @@ public class ParcelableUser implements TwidereParcelable, Comparable<ParcelableU
|
||||
listed_count = user.getListedCount();
|
||||
is_cache = false;
|
||||
is_following = user.isFollowing();
|
||||
description_unescaped = toPlainText(description_html);
|
||||
background_color = ParseUtils.parseColor(user.getProfileBackgroundColor(), 0);
|
||||
link_color = ParseUtils.parseColor(user.getProfileLinkColor(), 0);
|
||||
text_color = ParseUtils.parseColor(user.getProfileTextColor(), 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -290,6 +305,9 @@ public class ParcelableUser implements TwidereParcelable, Comparable<ParcelableU
|
||||
out.writeString("name", name);
|
||||
out.writeString("screen_name", screen_name);
|
||||
out.writeString("description_plain", description_plain);
|
||||
out.writeString("description_html", description_html);
|
||||
out.writeString("description_expanded", description_expanded);
|
||||
out.writeString("description_unescaped", description_unescaped);
|
||||
out.writeString("location", location);
|
||||
out.writeString("profile_image_url", profile_image_url);
|
||||
out.writeString("profile_banner_url", profile_banner_url);
|
||||
@ -301,11 +319,11 @@ public class ParcelableUser implements TwidereParcelable, Comparable<ParcelableU
|
||||
out.writeInt("favorites_count", favorites_count);
|
||||
out.writeInt("listed_count", listed_count);
|
||||
out.writeBoolean("is_cache", is_cache);
|
||||
out.writeString("description_html", description_html);
|
||||
out.writeString("description_expanded", description_expanded);
|
||||
out.writeString("url_expanded", url_expanded);
|
||||
out.writeBoolean("is_following", is_following);
|
||||
out.writeString("description_unescaped", description_unescaped);
|
||||
out.writeInt("background_color", background_color);
|
||||
out.writeInt("link_color", link_color);
|
||||
out.writeInt("text_color", text_color);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -319,6 +337,9 @@ public class ParcelableUser implements TwidereParcelable, Comparable<ParcelableU
|
||||
out.writeString(name);
|
||||
out.writeString(screen_name);
|
||||
out.writeString(description_plain);
|
||||
out.writeString(description_html);
|
||||
out.writeString(description_expanded);
|
||||
out.writeString(description_unescaped);
|
||||
out.writeString(location);
|
||||
out.writeString(profile_image_url);
|
||||
out.writeString(profile_banner_url);
|
||||
@ -330,11 +351,11 @@ public class ParcelableUser implements TwidereParcelable, Comparable<ParcelableU
|
||||
out.writeInt(favorites_count);
|
||||
out.writeInt(listed_count);
|
||||
out.writeInt(is_cache ? 1 : 0);
|
||||
out.writeString(description_html);
|
||||
out.writeString(description_expanded);
|
||||
out.writeString(url_expanded);
|
||||
out.writeInt(is_following ? 1 : 0);
|
||||
out.writeString(description_unescaped);
|
||||
out.writeInt(background_color);
|
||||
out.writeInt(link_color);
|
||||
out.writeInt(text_color);
|
||||
}
|
||||
|
||||
public static ContentValues makeCachedUserContentValues(final ParcelableUser user) {
|
||||
@ -360,10 +381,10 @@ public class ParcelableUser implements TwidereParcelable, Comparable<ParcelableU
|
||||
values.put(CachedUsers.URL_EXPANDED, user.url_expanded);
|
||||
values.put(CachedUsers.PROFILE_BANNER_URL, user.profile_banner_url);
|
||||
values.put(CachedUsers.IS_FOLLOWING, user.is_following);
|
||||
values.put(CachedUsers.BACKGROUND_COLOR, user.background_color);
|
||||
values.put(CachedUsers.LINK_COLOR, user.link_color);
|
||||
values.put(CachedUsers.TEXT_COLOR, user.text_color);
|
||||
return values;
|
||||
}
|
||||
|
||||
private static long getTime(final Date date) {
|
||||
return date != null ? date.getTime() : 0;
|
||||
}
|
||||
}
|
||||
|
@ -241,6 +241,12 @@ public interface TweetStore {
|
||||
|
||||
public static final String LISTED_COUNT = "listed_count";
|
||||
|
||||
public static final String BACKGROUND_COLOR = "background_color";
|
||||
|
||||
public static final String LINK_COLOR = "link_color";
|
||||
|
||||
public static final String TEXT_COLOR = "text_color";
|
||||
|
||||
/**
|
||||
* User's screen name of the status.<br>
|
||||
* Type: TEXT
|
||||
@ -254,13 +260,15 @@ public interface TweetStore {
|
||||
public static final String PROFILE_IMAGE_URL = "profile_image_url";
|
||||
|
||||
public static final String[] COLUMNS = new String[]{_ID, USER_ID, CREATED_AT, NAME, SCREEN_NAME,
|
||||
DESCRIPTION_PLAIN, LOCATION, URL, PROFILE_IMAGE_URL, PROFILE_BANNER_URL, IS_PROTECTED, IS_VERIFIED,
|
||||
IS_FOLLOWING, FOLLOWERS_COUNT, FRIENDS_COUNT, STATUSES_COUNT, FAVORITES_COUNT, LISTED_COUNT, DESCRIPTION_HTML,
|
||||
DESCRIPTION_EXPANDED, URL_EXPANDED};
|
||||
DESCRIPTION_PLAIN, LOCATION, URL, PROFILE_IMAGE_URL, PROFILE_BANNER_URL, IS_PROTECTED,
|
||||
IS_VERIFIED, IS_FOLLOWING, FOLLOWERS_COUNT, FRIENDS_COUNT, STATUSES_COUNT, FAVORITES_COUNT,
|
||||
LISTED_COUNT, DESCRIPTION_HTML, DESCRIPTION_EXPANDED, URL_EXPANDED, BACKGROUND_COLOR,
|
||||
LINK_COLOR, TEXT_COLOR};
|
||||
|
||||
public static final String[] TYPES = new String[]{TYPE_PRIMARY_KEY, TYPE_INT_UNIQUE, TYPE_INT, TYPE_TEXT,
|
||||
TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_BOOLEAN, TYPE_BOOLEAN,
|
||||
TYPE_BOOLEAN, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT};
|
||||
public static final String[] TYPES = new String[]{TYPE_PRIMARY_KEY, TYPE_INT_UNIQUE, TYPE_INT,
|
||||
TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_BOOLEAN,
|
||||
TYPE_BOOLEAN, TYPE_BOOLEAN, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_TEXT,
|
||||
TYPE_TEXT, TYPE_TEXT, TYPE_INT, TYPE_INT, TYPE_INT};
|
||||
|
||||
}
|
||||
|
||||
|
@ -131,6 +131,7 @@ public final class ContentValuesCreator implements TwidereConstants {
|
||||
values.put(CachedUsers.NAME, user.getName());
|
||||
values.put(CachedUsers.SCREEN_NAME, user.getScreenName());
|
||||
values.put(CachedUsers.PROFILE_IMAGE_URL, profile_image_url);
|
||||
values.put(CachedUsers.PROFILE_BANNER_URL, user.getProfileBannerImageUrl());
|
||||
values.put(CachedUsers.CREATED_AT, user.getCreatedAt().getTime());
|
||||
values.put(CachedUsers.IS_PROTECTED, user.isProtected());
|
||||
values.put(CachedUsers.IS_VERIFIED, user.isVerified());
|
||||
@ -145,10 +146,12 @@ public final class ContentValuesCreator implements TwidereConstants {
|
||||
values.put(CachedUsers.DESCRIPTION_HTML, Utils.formatUserDescription(user));
|
||||
values.put(CachedUsers.DESCRIPTION_EXPANDED, Utils.formatExpandedUserDescription(user));
|
||||
values.put(CachedUsers.URL, url);
|
||||
values.put(CachedUsers.URL_EXPANDED,
|
||||
url != null && urls != null && urls.length > 0 ? ParseUtils.parseString(urls[0].getExpandedURL())
|
||||
: null);
|
||||
values.put(CachedUsers.PROFILE_BANNER_URL, user.getProfileBannerImageUrl());
|
||||
if (url != null && urls != null && urls.length > 0) {
|
||||
values.put(CachedUsers.URL_EXPANDED, ParseUtils.parseString(urls[0].getExpandedURL()));
|
||||
}
|
||||
values.put(CachedUsers.BACKGROUND_COLOR, ParseUtils.parseColor(user.getProfileBackgroundColor(), 0));
|
||||
values.put(CachedUsers.LINK_COLOR, ParseUtils.parseColor(user.getProfileLinkColor(), 0));
|
||||
values.put(CachedUsers.TEXT_COLOR, ParseUtils.parseColor(user.getProfileTextColor(), 0));
|
||||
return values;
|
||||
}
|
||||
|
||||
|
@ -19,8 +19,6 @@
|
||||
|
||||
package org.mariotaku.twidere.util;
|
||||
|
||||
import static org.mariotaku.twidere.util.CompareUtils.classEquals;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
@ -38,6 +36,7 @@ import org.mariotaku.twidere.fragment.support.ActivitiesAboutMeFragment;
|
||||
import org.mariotaku.twidere.fragment.support.ActivitiesByFriendsFragment;
|
||||
import org.mariotaku.twidere.fragment.support.DirectMessagesFragment;
|
||||
import org.mariotaku.twidere.fragment.support.HomeTimelineFragment;
|
||||
import org.mariotaku.twidere.fragment.support.HomeTimelineListFragment;
|
||||
import org.mariotaku.twidere.fragment.support.InvalidTabFragment;
|
||||
import org.mariotaku.twidere.fragment.support.MentionsTimelineFragment;
|
||||
import org.mariotaku.twidere.fragment.support.RetweetsOfMeFragment;
|
||||
@ -46,7 +45,7 @@ import org.mariotaku.twidere.fragment.support.StaggeredHomeTimelineFragment;
|
||||
import org.mariotaku.twidere.fragment.support.TrendsSuggectionsFragment;
|
||||
import org.mariotaku.twidere.fragment.support.UserFavoritesFragment;
|
||||
import org.mariotaku.twidere.fragment.support.UserListTimelineFragment;
|
||||
import org.mariotaku.twidere.fragment.support.UserTimelineFragmentOld;
|
||||
import org.mariotaku.twidere.fragment.support.UserTimelineFragment;
|
||||
import org.mariotaku.twidere.model.CustomTabConfiguration;
|
||||
import org.mariotaku.twidere.model.CustomTabConfiguration.ExtraConfiguration;
|
||||
import org.mariotaku.twidere.model.SupportTabSpec;
|
||||
@ -59,280 +58,282 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import static org.mariotaku.twidere.util.CompareUtils.classEquals;
|
||||
|
||||
public class CustomTabUtils implements Constants {
|
||||
private static final HashMap<String, CustomTabConfiguration> CUSTOM_TABS_CONFIGURATION_MAP = new HashMap<String, CustomTabConfiguration>();
|
||||
private static final HashMap<String, Integer> CUSTOM_TABS_ICON_NAME_MAP = new HashMap<String, Integer>();
|
||||
private static final HashMap<String, CustomTabConfiguration> CUSTOM_TABS_CONFIGURATION_MAP = new HashMap<String, CustomTabConfiguration>();
|
||||
private static final HashMap<String, Integer> CUSTOM_TABS_ICON_NAME_MAP = new HashMap<String, Integer>();
|
||||
|
||||
static {
|
||||
CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_HOME_TIMELINE, new CustomTabConfiguration(
|
||||
HomeTimelineFragment.class, R.string.home, R.drawable.ic_action_home,
|
||||
CustomTabConfiguration.ACCOUNT_OPTIONAL, CustomTabConfiguration.FIELD_TYPE_NONE, 0, false));
|
||||
CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_MENTIONS_TIMELINE, new CustomTabConfiguration(
|
||||
MentionsTimelineFragment.class, R.string.mentions, R.drawable.ic_action_at,
|
||||
CustomTabConfiguration.ACCOUNT_OPTIONAL, CustomTabConfiguration.FIELD_TYPE_NONE, 1, false,
|
||||
ExtraConfiguration.newBoolean(EXTRA_MY_FOLLOWING_ONLY, R.string.following_only, false)));
|
||||
CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_DIRECT_MESSAGES, new CustomTabConfiguration(
|
||||
DirectMessagesFragment.class, R.string.direct_messages, R.drawable.ic_action_message,
|
||||
CustomTabConfiguration.ACCOUNT_OPTIONAL, CustomTabConfiguration.FIELD_TYPE_NONE, 2, false));
|
||||
CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_TRENDS_SUGGESTIONS, new CustomTabConfiguration(
|
||||
TrendsSuggectionsFragment.class, R.string.trends, R.drawable.ic_action_hashtag,
|
||||
CustomTabConfiguration.ACCOUNT_NONE, CustomTabConfiguration.FIELD_TYPE_NONE, 3, true));
|
||||
CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_FAVORITES, new CustomTabConfiguration(UserFavoritesFragment.class,
|
||||
R.string.favorites, R.drawable.ic_action_star, CustomTabConfiguration.ACCOUNT_REQUIRED,
|
||||
CustomTabConfiguration.FIELD_TYPE_USER, 4));
|
||||
CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_USER_TIMELINE, new CustomTabConfiguration(
|
||||
UserTimelineFragmentOld.class, R.string.users_statuses, R.drawable.ic_action_quote,
|
||||
CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_USER, 5));
|
||||
CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_SEARCH_STATUSES, new CustomTabConfiguration(
|
||||
SearchStatusesFragment.class, R.string.search_statuses, R.drawable.ic_action_search,
|
||||
CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_TEXT, R.string.query,
|
||||
EXTRA_QUERY, 6));
|
||||
CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_LIST_TIMELINE, new CustomTabConfiguration(
|
||||
UserListTimelineFragment.class, R.string.list_timeline, R.drawable.ic_action_list,
|
||||
CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_USER_LIST, 7));
|
||||
CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_ACTIVITIES_ABOUT_ME, new CustomTabConfiguration(
|
||||
ActivitiesAboutMeFragment.class, R.string.activities_about_me, R.drawable.ic_action_user,
|
||||
CustomTabConfiguration.ACCOUNT_OPTIONAL, CustomTabConfiguration.FIELD_TYPE_NONE, 8));
|
||||
CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_ACTIVITIES_BY_FRIENDS, new CustomTabConfiguration(
|
||||
ActivitiesByFriendsFragment.class, R.string.activities_by_friends,
|
||||
R.drawable.ic_action_accounts, CustomTabConfiguration.ACCOUNT_REQUIRED,
|
||||
CustomTabConfiguration.FIELD_TYPE_NONE, 9));
|
||||
CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_RETWEETS_OF_ME, new CustomTabConfiguration(
|
||||
RetweetsOfMeFragment.class, R.string.retweets_of_me, R.drawable.ic_action_retweet,
|
||||
CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_NONE, 10));
|
||||
if (Utils.hasStaggeredTimeline()) {
|
||||
CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_STAGGERED_HOME_TIMELINE, new CustomTabConfiguration(
|
||||
StaggeredHomeTimelineFragment.class, R.string.staggered_home_timeline,
|
||||
R.drawable.ic_action_view_quilt, CustomTabConfiguration.ACCOUNT_OPTIONAL,
|
||||
CustomTabConfiguration.FIELD_TYPE_NONE, 11, false));
|
||||
}
|
||||
static {
|
||||
CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_HOME_TIMELINE, new CustomTabConfiguration(
|
||||
HomeTimelineFragment.class, R.string.home, R.drawable.ic_action_home,
|
||||
CustomTabConfiguration.ACCOUNT_OPTIONAL, CustomTabConfiguration.FIELD_TYPE_NONE, 0, false));
|
||||
CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_MENTIONS_TIMELINE, new CustomTabConfiguration(
|
||||
MentionsTimelineFragment.class, R.string.mentions, R.drawable.ic_action_at,
|
||||
CustomTabConfiguration.ACCOUNT_OPTIONAL, CustomTabConfiguration.FIELD_TYPE_NONE, 1, false,
|
||||
ExtraConfiguration.newBoolean(EXTRA_MY_FOLLOWING_ONLY, R.string.following_only, false)));
|
||||
CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_DIRECT_MESSAGES, new CustomTabConfiguration(
|
||||
DirectMessagesFragment.class, R.string.direct_messages, R.drawable.ic_action_message,
|
||||
CustomTabConfiguration.ACCOUNT_OPTIONAL, CustomTabConfiguration.FIELD_TYPE_NONE, 2, false));
|
||||
CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_TRENDS_SUGGESTIONS, new CustomTabConfiguration(
|
||||
TrendsSuggectionsFragment.class, R.string.trends, R.drawable.ic_action_hashtag,
|
||||
CustomTabConfiguration.ACCOUNT_NONE, CustomTabConfiguration.FIELD_TYPE_NONE, 3, true));
|
||||
CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_FAVORITES, new CustomTabConfiguration(UserFavoritesFragment.class,
|
||||
R.string.favorites, R.drawable.ic_action_star, CustomTabConfiguration.ACCOUNT_REQUIRED,
|
||||
CustomTabConfiguration.FIELD_TYPE_USER, 4));
|
||||
CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_USER_TIMELINE, new CustomTabConfiguration(
|
||||
UserTimelineFragment.class, R.string.users_statuses, R.drawable.ic_action_quote,
|
||||
CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_USER, 5));
|
||||
CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_SEARCH_STATUSES, new CustomTabConfiguration(
|
||||
SearchStatusesFragment.class, R.string.search_statuses, R.drawable.ic_action_search,
|
||||
CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_TEXT, R.string.query,
|
||||
EXTRA_QUERY, 6));
|
||||
CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_LIST_TIMELINE, new CustomTabConfiguration(
|
||||
UserListTimelineFragment.class, R.string.list_timeline, R.drawable.ic_action_list,
|
||||
CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_USER_LIST, 7));
|
||||
CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_ACTIVITIES_ABOUT_ME, new CustomTabConfiguration(
|
||||
ActivitiesAboutMeFragment.class, R.string.activities_about_me, R.drawable.ic_action_user,
|
||||
CustomTabConfiguration.ACCOUNT_OPTIONAL, CustomTabConfiguration.FIELD_TYPE_NONE, 8));
|
||||
CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_ACTIVITIES_BY_FRIENDS, new CustomTabConfiguration(
|
||||
ActivitiesByFriendsFragment.class, R.string.activities_by_friends,
|
||||
R.drawable.ic_action_accounts, CustomTabConfiguration.ACCOUNT_REQUIRED,
|
||||
CustomTabConfiguration.FIELD_TYPE_NONE, 9));
|
||||
CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_RETWEETS_OF_ME, new CustomTabConfiguration(
|
||||
RetweetsOfMeFragment.class, R.string.retweets_of_me, R.drawable.ic_action_retweet,
|
||||
CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_NONE, 10));
|
||||
if (Utils.hasStaggeredTimeline()) {
|
||||
CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_STAGGERED_HOME_TIMELINE, new CustomTabConfiguration(
|
||||
StaggeredHomeTimelineFragment.class, R.string.staggered_home_timeline,
|
||||
R.drawable.ic_action_view_quilt, CustomTabConfiguration.ACCOUNT_OPTIONAL,
|
||||
CustomTabConfiguration.FIELD_TYPE_NONE, 11, false));
|
||||
}
|
||||
|
||||
CUSTOM_TABS_ICON_NAME_MAP.put("accounts", R.drawable.ic_action_accounts);
|
||||
CUSTOM_TABS_ICON_NAME_MAP.put("hashtag", R.drawable.ic_action_hashtag);
|
||||
CUSTOM_TABS_ICON_NAME_MAP.put("heart", R.drawable.ic_action_heart);
|
||||
CUSTOM_TABS_ICON_NAME_MAP.put("home", R.drawable.ic_action_home);
|
||||
CUSTOM_TABS_ICON_NAME_MAP.put("list", R.drawable.ic_action_list);
|
||||
CUSTOM_TABS_ICON_NAME_MAP.put("mention", R.drawable.ic_action_at);
|
||||
CUSTOM_TABS_ICON_NAME_MAP.put("message", R.drawable.ic_action_message);
|
||||
CUSTOM_TABS_ICON_NAME_MAP.put("quote", R.drawable.ic_action_quote);
|
||||
CUSTOM_TABS_ICON_NAME_MAP.put("search", R.drawable.ic_action_search);
|
||||
CUSTOM_TABS_ICON_NAME_MAP.put("staggered", R.drawable.ic_action_view_quilt);
|
||||
CUSTOM_TABS_ICON_NAME_MAP.put("star", R.drawable.ic_action_star);
|
||||
CUSTOM_TABS_ICON_NAME_MAP.put("trends", R.drawable.ic_action_trends);
|
||||
CUSTOM_TABS_ICON_NAME_MAP.put("twidere", R.drawable.ic_action_twidere);
|
||||
CUSTOM_TABS_ICON_NAME_MAP.put("twitter", R.drawable.ic_action_twitter);
|
||||
CUSTOM_TABS_ICON_NAME_MAP.put("user", R.drawable.ic_action_user);
|
||||
}
|
||||
CUSTOM_TABS_ICON_NAME_MAP.put("accounts", R.drawable.ic_action_accounts);
|
||||
CUSTOM_TABS_ICON_NAME_MAP.put("hashtag", R.drawable.ic_action_hashtag);
|
||||
CUSTOM_TABS_ICON_NAME_MAP.put("heart", R.drawable.ic_action_heart);
|
||||
CUSTOM_TABS_ICON_NAME_MAP.put("home", R.drawable.ic_action_home);
|
||||
CUSTOM_TABS_ICON_NAME_MAP.put("list", R.drawable.ic_action_list);
|
||||
CUSTOM_TABS_ICON_NAME_MAP.put("mention", R.drawable.ic_action_at);
|
||||
CUSTOM_TABS_ICON_NAME_MAP.put("message", R.drawable.ic_action_message);
|
||||
CUSTOM_TABS_ICON_NAME_MAP.put("quote", R.drawable.ic_action_quote);
|
||||
CUSTOM_TABS_ICON_NAME_MAP.put("search", R.drawable.ic_action_search);
|
||||
CUSTOM_TABS_ICON_NAME_MAP.put("staggered", R.drawable.ic_action_view_quilt);
|
||||
CUSTOM_TABS_ICON_NAME_MAP.put("star", R.drawable.ic_action_star);
|
||||
CUSTOM_TABS_ICON_NAME_MAP.put("trends", R.drawable.ic_action_trends);
|
||||
CUSTOM_TABS_ICON_NAME_MAP.put("twidere", R.drawable.ic_action_twidere);
|
||||
CUSTOM_TABS_ICON_NAME_MAP.put("twitter", R.drawable.ic_action_twitter);
|
||||
CUSTOM_TABS_ICON_NAME_MAP.put("user", R.drawable.ic_action_user);
|
||||
}
|
||||
|
||||
public static String findTabIconKey(final int iconRes) {
|
||||
for (final Entry<String, Integer> entry : getIconMap().entrySet()) {
|
||||
if (entry.getValue() == iconRes) return entry.getKey();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public static String findTabIconKey(final int iconRes) {
|
||||
for (final Entry<String, Integer> entry : getIconMap().entrySet()) {
|
||||
if (entry.getValue() == iconRes) return entry.getKey();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String findTabType(final Class<? extends Fragment> cls) {
|
||||
for (final Entry<String, CustomTabConfiguration> entry : getConfiguraionMap().entrySet()) {
|
||||
if (classEquals(cls, entry.getValue().getFragmentClass())) return entry.getKey();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public static String findTabType(final Class<? extends Fragment> cls) {
|
||||
for (final Entry<String, CustomTabConfiguration> entry : getConfiguraionMap().entrySet()) {
|
||||
if (classEquals(cls, entry.getValue().getFragmentClass())) return entry.getKey();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static SupportTabSpec getAddedTabAt(final Context context, final int position) {
|
||||
if (context == null || position < 0) return null;
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
final Cursor cur = resolver.query(Tabs.CONTENT_URI, Tabs.COLUMNS, Tabs.POSITION + " = " + position, null,
|
||||
Tabs.DEFAULT_SORT_ORDER);
|
||||
final int idxName = cur.getColumnIndex(Tabs.NAME), idxIcon = cur.getColumnIndex(Tabs.ICON), idxType = cur
|
||||
.getColumnIndex(Tabs.TYPE), idxArguments = cur.getColumnIndex(Tabs.ARGUMENTS), idxExtras = cur
|
||||
.getColumnIndex(Tabs.EXTRAS);
|
||||
try {
|
||||
if (cur.getCount() == 0) return null;
|
||||
cur.moveToFirst();
|
||||
final String type = cur.getString(idxType);
|
||||
final CustomTabConfiguration conf = getTabConfiguration(type);
|
||||
if (conf == null) return null;
|
||||
final String icon_type = cur.getString(idxIcon);
|
||||
final String name = cur.getString(idxName);
|
||||
final Bundle args = ParseUtils.jsonToBundle(cur.getString(idxArguments));
|
||||
args.putInt(EXTRA_TAB_POSITION, position);
|
||||
args.putBundle(EXTRA_EXTRAS, ParseUtils.jsonToBundle(cur.getString(idxExtras)));
|
||||
final Class<? extends Fragment> fragment = conf.getFragmentClass();
|
||||
return new SupportTabSpec(name != null ? name : getTabTypeName(context, type), getTabIconObject(icon_type),
|
||||
type, fragment, args, position);
|
||||
} finally {
|
||||
cur.close();
|
||||
}
|
||||
}
|
||||
public static SupportTabSpec getAddedTabAt(final Context context, final int position) {
|
||||
if (context == null || position < 0) return null;
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
final Cursor cur = resolver.query(Tabs.CONTENT_URI, Tabs.COLUMNS, Tabs.POSITION + " = " + position, null,
|
||||
Tabs.DEFAULT_SORT_ORDER);
|
||||
final int idxName = cur.getColumnIndex(Tabs.NAME), idxIcon = cur.getColumnIndex(Tabs.ICON), idxType = cur
|
||||
.getColumnIndex(Tabs.TYPE), idxArguments = cur.getColumnIndex(Tabs.ARGUMENTS), idxExtras = cur
|
||||
.getColumnIndex(Tabs.EXTRAS);
|
||||
try {
|
||||
if (cur.getCount() == 0) return null;
|
||||
cur.moveToFirst();
|
||||
final String type = cur.getString(idxType);
|
||||
final CustomTabConfiguration conf = getTabConfiguration(type);
|
||||
if (conf == null) return null;
|
||||
final String icon_type = cur.getString(idxIcon);
|
||||
final String name = cur.getString(idxName);
|
||||
final Bundle args = ParseUtils.jsonToBundle(cur.getString(idxArguments));
|
||||
args.putInt(EXTRA_TAB_POSITION, position);
|
||||
args.putBundle(EXTRA_EXTRAS, ParseUtils.jsonToBundle(cur.getString(idxExtras)));
|
||||
final Class<? extends Fragment> fragment = conf.getFragmentClass();
|
||||
return new SupportTabSpec(name != null ? name : getTabTypeName(context, type), getTabIconObject(icon_type),
|
||||
type, fragment, args, position);
|
||||
} finally {
|
||||
cur.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static CustomTabConfiguration getAddedTabConfigurationAt(final Context context, final int position) {
|
||||
if (context == null || position < 0) return null;
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
final Cursor cur = resolver.query(Tabs.CONTENT_URI, Tabs.COLUMNS, Tabs.POSITION + " = " + position, null,
|
||||
Tabs.DEFAULT_SORT_ORDER);
|
||||
final int idxType = cur.getColumnIndex(Tabs.TYPE);
|
||||
try {
|
||||
if (cur.getCount() == 0) return null;
|
||||
cur.moveToFirst();
|
||||
final String type = cur.getString(idxType);
|
||||
return getTabConfiguration(type);
|
||||
} finally {
|
||||
cur.close();
|
||||
}
|
||||
}
|
||||
public static CustomTabConfiguration getAddedTabConfigurationAt(final Context context, final int position) {
|
||||
if (context == null || position < 0) return null;
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
final Cursor cur = resolver.query(Tabs.CONTENT_URI, Tabs.COLUMNS, Tabs.POSITION + " = " + position, null,
|
||||
Tabs.DEFAULT_SORT_ORDER);
|
||||
final int idxType = cur.getColumnIndex(Tabs.TYPE);
|
||||
try {
|
||||
if (cur.getCount() == 0) return null;
|
||||
cur.moveToFirst();
|
||||
final String type = cur.getString(idxType);
|
||||
return getTabConfiguration(type);
|
||||
} finally {
|
||||
cur.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static int getAddedTabPosition(final Context context, final String type) {
|
||||
if (context == null || type == null) return -1;
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
final String where = Tabs.TYPE + " = ?";
|
||||
final Cursor cur = resolver.query(Tabs.CONTENT_URI, new String[] { Tabs.POSITION }, where,
|
||||
new String[] { type }, Tabs.DEFAULT_SORT_ORDER);
|
||||
if (cur == null) return -1;
|
||||
final int position;
|
||||
if (cur.getCount() > 0) {
|
||||
cur.moveToFirst();
|
||||
position = cur.getInt(cur.getColumnIndex(Tabs.POSITION));
|
||||
} else {
|
||||
position = -1;
|
||||
}
|
||||
cur.close();
|
||||
return position;
|
||||
}
|
||||
public static int getAddedTabPosition(final Context context, final String type) {
|
||||
if (context == null || type == null) return -1;
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
final String where = Tabs.TYPE + " = ?";
|
||||
final Cursor cur = resolver.query(Tabs.CONTENT_URI, new String[]{Tabs.POSITION}, where,
|
||||
new String[]{type}, Tabs.DEFAULT_SORT_ORDER);
|
||||
if (cur == null) return -1;
|
||||
final int position;
|
||||
if (cur.getCount() > 0) {
|
||||
cur.moveToFirst();
|
||||
position = cur.getInt(cur.getColumnIndex(Tabs.POSITION));
|
||||
} else {
|
||||
position = -1;
|
||||
}
|
||||
cur.close();
|
||||
return position;
|
||||
}
|
||||
|
||||
public static String getAddedTabTypeAt(final Context context, final int position) {
|
||||
if (context == null || position < 0) return null;
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
final Cursor cur = resolver.query(Tabs.CONTENT_URI, Tabs.COLUMNS, Tabs.POSITION + " = " + position, null,
|
||||
Tabs.DEFAULT_SORT_ORDER);
|
||||
final int idx_type = cur.getColumnIndex(Tabs.TYPE);
|
||||
try {
|
||||
if (cur.getCount() == 0) return null;
|
||||
cur.moveToFirst();
|
||||
return cur.getString(idx_type);
|
||||
} finally {
|
||||
cur.close();
|
||||
}
|
||||
}
|
||||
public static String getAddedTabTypeAt(final Context context, final int position) {
|
||||
if (context == null || position < 0) return null;
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
final Cursor cur = resolver.query(Tabs.CONTENT_URI, Tabs.COLUMNS, Tabs.POSITION + " = " + position, null,
|
||||
Tabs.DEFAULT_SORT_ORDER);
|
||||
final int idx_type = cur.getColumnIndex(Tabs.TYPE);
|
||||
try {
|
||||
if (cur.getCount() == 0) return null;
|
||||
cur.moveToFirst();
|
||||
return cur.getString(idx_type);
|
||||
} finally {
|
||||
cur.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static HashMap<String, CustomTabConfiguration> getConfiguraionMap() {
|
||||
return new HashMap<String, CustomTabConfiguration>(CUSTOM_TABS_CONFIGURATION_MAP);
|
||||
}
|
||||
public static HashMap<String, CustomTabConfiguration> getConfiguraionMap() {
|
||||
return new HashMap<String, CustomTabConfiguration>(CUSTOM_TABS_CONFIGURATION_MAP);
|
||||
}
|
||||
|
||||
public static List<SupportTabSpec> getHomeTabs(final Context context) {
|
||||
if (context == null) return Collections.emptyList();
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
final Cursor cur = resolver.query(Tabs.CONTENT_URI, Tabs.COLUMNS, null, null, Tabs.DEFAULT_SORT_ORDER);
|
||||
if (cur == null) return Collections.emptyList();
|
||||
final ArrayList<SupportTabSpec> tabs = new ArrayList<SupportTabSpec>();
|
||||
cur.moveToFirst();
|
||||
final int idxName = cur.getColumnIndex(Tabs.NAME), idxIcon = cur.getColumnIndex(Tabs.ICON), idxType = cur
|
||||
.getColumnIndex(Tabs.TYPE), idxArguments = cur.getColumnIndex(Tabs.ARGUMENTS), idxExtras = cur
|
||||
.getColumnIndex(Tabs.EXTRAS), idxPosition = cur.getColumnIndex(Tabs.POSITION);
|
||||
while (!cur.isAfterLast()) {
|
||||
final String type = cur.getString(idxType);
|
||||
final int position = cur.getInt(idxPosition);
|
||||
final String iconType = cur.getString(idxIcon);
|
||||
final String name = cur.getString(idxName);
|
||||
final Bundle args = ParseUtils.jsonToBundle(cur.getString(idxArguments));
|
||||
args.putInt(EXTRA_TAB_POSITION, position);
|
||||
args.putBundle(EXTRA_EXTRAS, ParseUtils.jsonToBundle(cur.getString(idxExtras)));
|
||||
final CustomTabConfiguration conf = getTabConfiguration(type);
|
||||
final Class<? extends Fragment> cls = conf != null ? conf.getFragmentClass() : InvalidTabFragment.class;
|
||||
tabs.add(new SupportTabSpec(name != null ? name : getTabTypeName(context, type),
|
||||
getTabIconObject(iconType), type, cls, args, position));
|
||||
cur.moveToNext();
|
||||
}
|
||||
cur.close();
|
||||
Collections.sort(tabs);
|
||||
return tabs;
|
||||
}
|
||||
public static List<SupportTabSpec> getHomeTabs(final Context context) {
|
||||
if (context == null) return Collections.emptyList();
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
final Cursor cur = resolver.query(Tabs.CONTENT_URI, Tabs.COLUMNS, null, null, Tabs.DEFAULT_SORT_ORDER);
|
||||
if (cur == null) return Collections.emptyList();
|
||||
final ArrayList<SupportTabSpec> tabs = new ArrayList<SupportTabSpec>();
|
||||
cur.moveToFirst();
|
||||
final int idxName = cur.getColumnIndex(Tabs.NAME), idxIcon = cur.getColumnIndex(Tabs.ICON), idxType = cur
|
||||
.getColumnIndex(Tabs.TYPE), idxArguments = cur.getColumnIndex(Tabs.ARGUMENTS), idxExtras = cur
|
||||
.getColumnIndex(Tabs.EXTRAS), idxPosition = cur.getColumnIndex(Tabs.POSITION);
|
||||
while (!cur.isAfterLast()) {
|
||||
final String type = cur.getString(idxType);
|
||||
final int position = cur.getInt(idxPosition);
|
||||
final String iconType = cur.getString(idxIcon);
|
||||
final String name = cur.getString(idxName);
|
||||
final Bundle args = ParseUtils.jsonToBundle(cur.getString(idxArguments));
|
||||
args.putInt(EXTRA_TAB_POSITION, position);
|
||||
args.putBundle(EXTRA_EXTRAS, ParseUtils.jsonToBundle(cur.getString(idxExtras)));
|
||||
final CustomTabConfiguration conf = getTabConfiguration(type);
|
||||
final Class<? extends Fragment> cls = conf != null ? conf.getFragmentClass() : InvalidTabFragment.class;
|
||||
tabs.add(new SupportTabSpec(name != null ? name : getTabTypeName(context, type),
|
||||
getTabIconObject(iconType), type, cls, args, position));
|
||||
cur.moveToNext();
|
||||
}
|
||||
cur.close();
|
||||
Collections.sort(tabs);
|
||||
return tabs;
|
||||
}
|
||||
|
||||
public static HashMap<String, Integer> getIconMap() {
|
||||
return new HashMap<String, Integer>(CUSTOM_TABS_ICON_NAME_MAP);
|
||||
}
|
||||
public static HashMap<String, Integer> getIconMap() {
|
||||
return new HashMap<String, Integer>(CUSTOM_TABS_ICON_NAME_MAP);
|
||||
}
|
||||
|
||||
public static CustomTabConfiguration getTabConfiguration(final String key) {
|
||||
if (key == null) return null;
|
||||
return CUSTOM_TABS_CONFIGURATION_MAP.get(key);
|
||||
}
|
||||
public static CustomTabConfiguration getTabConfiguration(final String key) {
|
||||
if (key == null) return null;
|
||||
return CUSTOM_TABS_CONFIGURATION_MAP.get(key);
|
||||
}
|
||||
|
||||
public static Drawable getTabIconDrawable(final Context context, final Object iconObj) {
|
||||
return getTabIconDrawable(context.getResources(), iconObj);
|
||||
}
|
||||
public static Drawable getTabIconDrawable(final Context context, final Object iconObj) {
|
||||
return getTabIconDrawable(context.getResources(), iconObj);
|
||||
}
|
||||
|
||||
public static Drawable getTabIconDrawable(final Resources res, final Object iconObj) {
|
||||
if (res == null) return null;
|
||||
if (iconObj instanceof Integer) {
|
||||
try {
|
||||
return res.getDrawable((Integer) iconObj);
|
||||
} catch (final Resources.NotFoundException e) {
|
||||
// Ignore.
|
||||
}
|
||||
} else if (iconObj instanceof Bitmap)
|
||||
return new BitmapDrawable(res, (Bitmap) iconObj);
|
||||
else if (iconObj instanceof Drawable)
|
||||
return (Drawable) iconObj;
|
||||
else if (iconObj instanceof File) {
|
||||
final Bitmap b = getTabIconFromFile((File) iconObj, res);
|
||||
if (b != null) return new BitmapDrawable(res, b);
|
||||
}
|
||||
return res.getDrawable(R.drawable.ic_action_list);
|
||||
}
|
||||
public static Drawable getTabIconDrawable(final Resources res, final Object iconObj) {
|
||||
if (res == null) return null;
|
||||
if (iconObj instanceof Integer) {
|
||||
try {
|
||||
return res.getDrawable((Integer) iconObj);
|
||||
} catch (final Resources.NotFoundException e) {
|
||||
// Ignore.
|
||||
}
|
||||
} else if (iconObj instanceof Bitmap)
|
||||
return new BitmapDrawable(res, (Bitmap) iconObj);
|
||||
else if (iconObj instanceof Drawable)
|
||||
return (Drawable) iconObj;
|
||||
else if (iconObj instanceof File) {
|
||||
final Bitmap b = getTabIconFromFile((File) iconObj, res);
|
||||
if (b != null) return new BitmapDrawable(res, b);
|
||||
}
|
||||
return res.getDrawable(R.drawable.ic_action_list);
|
||||
}
|
||||
|
||||
public static Bitmap getTabIconFromFile(final File file, final Resources res) {
|
||||
if (file == null || !file.exists()) return null;
|
||||
final String path = file.getPath();
|
||||
final BitmapFactory.Options o = new BitmapFactory.Options();
|
||||
o.inJustDecodeBounds = true;
|
||||
BitmapFactory.decodeFile(path, o);
|
||||
if (o.outHeight <= 0 || o.outWidth <= 0) return null;
|
||||
o.inSampleSize = (int) (Math.max(o.outWidth, o.outHeight) / (48 * res.getDisplayMetrics().density));
|
||||
o.inJustDecodeBounds = false;
|
||||
return BitmapFactory.decodeFile(path, o);
|
||||
}
|
||||
public static Bitmap getTabIconFromFile(final File file, final Resources res) {
|
||||
if (file == null || !file.exists()) return null;
|
||||
final String path = file.getPath();
|
||||
final BitmapFactory.Options o = new BitmapFactory.Options();
|
||||
o.inJustDecodeBounds = true;
|
||||
BitmapFactory.decodeFile(path, o);
|
||||
if (o.outHeight <= 0 || o.outWidth <= 0) return null;
|
||||
o.inSampleSize = (int) (Math.max(o.outWidth, o.outHeight) / (48 * res.getDisplayMetrics().density));
|
||||
o.inJustDecodeBounds = false;
|
||||
return BitmapFactory.decodeFile(path, o);
|
||||
}
|
||||
|
||||
public static Object getTabIconObject(final String type) {
|
||||
if (type == null) return R.drawable.ic_action_list;
|
||||
final Integer value = CUSTOM_TABS_ICON_NAME_MAP.get(type);
|
||||
if (value != null)
|
||||
return value;
|
||||
else if (type.contains("/")) {
|
||||
try {
|
||||
final File file = new File(type);
|
||||
if (file.exists()) return file;
|
||||
} catch (final Exception e) {
|
||||
return R.drawable.ic_action_list;
|
||||
}
|
||||
}
|
||||
return R.drawable.ic_action_list;
|
||||
}
|
||||
public static Object getTabIconObject(final String type) {
|
||||
if (type == null) return R.drawable.ic_action_list;
|
||||
final Integer value = CUSTOM_TABS_ICON_NAME_MAP.get(type);
|
||||
if (value != null)
|
||||
return value;
|
||||
else if (type.contains("/")) {
|
||||
try {
|
||||
final File file = new File(type);
|
||||
if (file.exists()) return file;
|
||||
} catch (final Exception e) {
|
||||
return R.drawable.ic_action_list;
|
||||
}
|
||||
}
|
||||
return R.drawable.ic_action_list;
|
||||
}
|
||||
|
||||
public static String getTabTypeName(final Context context, final String type) {
|
||||
if (context == null) return null;
|
||||
final CustomTabConfiguration conf = getTabConfiguration(type);
|
||||
final Integer res_id = conf != null ? conf.getDefaultTitle() : null;
|
||||
return res_id != null ? context.getString(res_id) : null;
|
||||
}
|
||||
public static String getTabTypeName(final Context context, final String type) {
|
||||
if (context == null) return null;
|
||||
final CustomTabConfiguration conf = getTabConfiguration(type);
|
||||
final Integer res_id = conf != null ? conf.getDefaultTitle() : null;
|
||||
return res_id != null ? context.getString(res_id) : null;
|
||||
}
|
||||
|
||||
public static boolean isSingleTab(final String type) {
|
||||
if (type == null) return false;
|
||||
final CustomTabConfiguration conf = getTabConfiguration(type);
|
||||
return conf != null && conf.isSingleTab();
|
||||
}
|
||||
public static boolean isSingleTab(final String type) {
|
||||
if (type == null) return false;
|
||||
final CustomTabConfiguration conf = getTabConfiguration(type);
|
||||
return conf != null && conf.isSingleTab();
|
||||
}
|
||||
|
||||
public static boolean isTabAdded(final Context context, final String type) {
|
||||
if (context == null || type == null) return false;
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
final String where = Tabs.TYPE + " = ?";
|
||||
final Cursor cur = resolver.query(Tabs.CONTENT_URI, new String[0], where, new String[] { type },
|
||||
Tabs.DEFAULT_SORT_ORDER);
|
||||
if (cur == null) return false;
|
||||
final boolean added = cur.getCount() > 0;
|
||||
cur.close();
|
||||
return added;
|
||||
}
|
||||
public static boolean isTabAdded(final Context context, final String type) {
|
||||
if (context == null || type == null) return false;
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
final String where = Tabs.TYPE + " = ?";
|
||||
final Cursor cur = resolver.query(Tabs.CONTENT_URI, new String[0], where, new String[]{type},
|
||||
Tabs.DEFAULT_SORT_ORDER);
|
||||
if (cur == null) return false;
|
||||
final boolean added = cur.getCount() > 0;
|
||||
cur.close();
|
||||
return added;
|
||||
}
|
||||
|
||||
public static boolean isTabTypeValid(final String type) {
|
||||
return type != null && CUSTOM_TABS_CONFIGURATION_MAP.containsKey(type);
|
||||
}
|
||||
public static boolean isTabTypeValid(final String type) {
|
||||
return type != null && CUSTOM_TABS_CONFIGURATION_MAP.containsKey(type);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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.util;
|
||||
|
||||
import android.os.SystemClock;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import org.mariotaku.twidere.view.HeaderDrawerLayout.DrawerCallback;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/12/2.
|
||||
*/
|
||||
public class SimpleDrawerCallback implements DrawerCallback {
|
||||
|
||||
private final RecyclerView mRecyclerView;
|
||||
|
||||
public SimpleDrawerCallback(RecyclerView recyclerView) {
|
||||
mRecyclerView = recyclerView;
|
||||
}
|
||||
|
||||
|
||||
@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 boolean shouldLayoutHeaderBottom() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void topChanged(int offset) {
|
||||
|
||||
}
|
||||
}
|
@ -2784,8 +2784,11 @@ public final class Utils implements Constants, TwitterConstants {
|
||||
}
|
||||
|
||||
public static boolean isMyRetweet(final ParcelableStatus status) {
|
||||
if (status == null) return false;
|
||||
return status.retweeted_by_id == status.account_id || status.my_retweet_id > 0;
|
||||
return status != null && isMyRetweet(status.account_id, status.retweeted_by_id, status.my_retweet_id);
|
||||
}
|
||||
|
||||
public static boolean isMyRetweet(final long account_id, final long retweeted_by_id, final long my_retweet_id) {
|
||||
return retweeted_by_id == account_id || my_retweet_id > 0;
|
||||
}
|
||||
|
||||
public static boolean isMyUserName(final Context context, final String screen_name) {
|
||||
@ -2852,11 +2855,6 @@ public final class Utils implements Constants, TwitterConstants {
|
||||
&& networkInfo.isConnected();
|
||||
}
|
||||
|
||||
public static boolean isPlainListStyle(final Context context) {
|
||||
final SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
||||
return prefs != null && prefs.getBoolean(KEY_PLAIN_LIST_STYLE, false);
|
||||
}
|
||||
|
||||
public static boolean isRedirected(final int code) {
|
||||
return code == 301 || code == 302 || code == 307;
|
||||
}
|
||||
@ -3027,7 +3025,7 @@ public final class Utils implements Constants, TwitterConstants {
|
||||
activity.startActivity(intent);
|
||||
}
|
||||
|
||||
public static void openStatus(final Context context, final ParcelableStatus status) {
|
||||
public static void openStatus(final Context context, final ParcelableStatus status, Bundle activityOptions) {
|
||||
if (context == null || status == null) return;
|
||||
final long account_id = status.account_id, status_id = status.id;
|
||||
final Bundle extras = new Bundle();
|
||||
@ -3040,7 +3038,11 @@ public final class Utils implements Constants, TwitterConstants {
|
||||
final Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
|
||||
intent.setExtrasClassLoader(context.getClassLoader());
|
||||
intent.putExtras(extras);
|
||||
context.startActivity(intent);
|
||||
if (context instanceof Activity) {
|
||||
ActivityCompat.startActivity((Activity) context, intent, activityOptions);
|
||||
} else {
|
||||
context.startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
||||
public static void openStatuses(final Activity activity, final List<ParcelableStatus> statuses) {
|
||||
@ -3999,7 +4001,7 @@ public final class Utils implements Constants, TwitterConstants {
|
||||
|
||||
@SafeVarargs
|
||||
public static Bundle makeSceneTransitionOption(final Activity activity,
|
||||
final Pair<View, String>... sharedElements) {
|
||||
final Pair<View, String>... sharedElements) {
|
||||
if (ThemeUtils.isTransparentBackground(activity)) return null;
|
||||
return ActivityOptionsCompat.makeSceneTransitionAnimation(activity, sharedElements).toBundle();
|
||||
}
|
||||
|
@ -80,79 +80,6 @@ public class HeaderDrawerLayout extends ViewGroup {
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
private void flingCallback(float velocity) {
|
||||
mDrawerCallback.fling(velocity);
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
|
||||
private void scrollByCallback(float dy) {
|
||||
setScrollingContentCallback(true);
|
||||
mDrawerCallback.scrollBy(dy);
|
||||
}
|
||||
|
||||
private boolean isScrollContentCallback(float x, float y) {
|
||||
return mDrawerCallback.isScrollContent(x, y);
|
||||
}
|
||||
|
||||
private void cancelTouchCallback() {
|
||||
mDrawerCallback.cancelTouch();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
if (getChildCount() != 1) {
|
||||
throw new IllegalArgumentException("Add subview by XML is not allowed.");
|
||||
}
|
||||
}
|
||||
|
||||
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()) {
|
||||
@ -188,41 +115,60 @@ public class HeaderDrawerLayout extends ViewGroup {
|
||||
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 top;
|
||||
if (i == 0) {
|
||||
if (shouldLayoutHeaderBottomCallback() && child.getHeight() != 0) {
|
||||
final int heightDelta = child.getMeasuredHeight() - child.getHeight();
|
||||
top = mHeaderOffset + getPaddingTop() - heightDelta;
|
||||
} else {
|
||||
top = mHeaderOffset + getPaddingTop();
|
||||
}
|
||||
} else {
|
||||
top = getChildAt(i - 1).getBottom();
|
||||
}
|
||||
final int bottom = top + child.getMeasuredHeight();
|
||||
child.layout(left, top, right, bottom);
|
||||
notifyOffsetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(@NonNull MotionEvent event) {
|
||||
mDragHelper.processTouchEvent(event);
|
||||
return true;
|
||||
}
|
||||
|
||||
public View getHeader() {
|
||||
return mContainer.getHeader();
|
||||
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);
|
||||
}
|
||||
|
||||
public View getContent() {
|
||||
return mContainer.getContent();
|
||||
}
|
||||
|
||||
private int getScrollRange() {
|
||||
return mContainer.getScrollRange();
|
||||
public View getHeader() {
|
||||
return mContainer.getHeader();
|
||||
}
|
||||
|
||||
@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 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();
|
||||
}
|
||||
@ -231,6 +177,82 @@ public class HeaderDrawerLayout extends ViewGroup {
|
||||
return mContainer.getHeaderTopMinimum();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(@NonNull MotionEvent event) {
|
||||
mDragHelper.processTouchEvent(event);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
if (getChildCount() != 1) {
|
||||
throw new IllegalArgumentException("Add subview by XML is not allowed.");
|
||||
}
|
||||
}
|
||||
|
||||
public void setDrawerCallback(DrawerCallback callback) {
|
||||
mDrawerCallback = callback;
|
||||
}
|
||||
|
||||
private boolean canScrollCallback(float dy) {
|
||||
return mDrawerCallback.canScroll(dy);
|
||||
}
|
||||
|
||||
private void cancelTouchCallback() {
|
||||
mDrawerCallback.cancelTouch();
|
||||
}
|
||||
|
||||
private void flingCallback(float velocity) {
|
||||
mDrawerCallback.fling(velocity);
|
||||
}
|
||||
|
||||
private float getDragTouchSlop() {
|
||||
return mDragHelper.getTouchSlop();
|
||||
}
|
||||
|
||||
private int getScrollRange() {
|
||||
return mContainer.getScrollRange();
|
||||
}
|
||||
|
||||
private boolean isScrollContentCallback(float x, float y) {
|
||||
return mDrawerCallback.isScrollContent(x, y);
|
||||
}
|
||||
|
||||
private boolean isScrollingContentCallback() {
|
||||
return mScrollingContentCallback;
|
||||
}
|
||||
|
||||
private void setScrollingContentCallback(boolean scrolling) {
|
||||
mScrollingContentCallback = scrolling;
|
||||
}
|
||||
|
||||
private boolean isScrollingHeaderByHelper() {
|
||||
return mDragCallback.isScrollingHeaderByHelper();
|
||||
}
|
||||
|
||||
private boolean isTouchingScrollableContent() {
|
||||
return mTouchingScrollableContent;
|
||||
}
|
||||
|
||||
private boolean isUsingDragHelper() {
|
||||
return mUsingDragHelper;
|
||||
}
|
||||
|
||||
private boolean isValidScroll(float direction, float other) {
|
||||
return Math.abs(direction) > getDragTouchSlop() && Math.abs(direction) > Math.abs(other);
|
||||
}
|
||||
|
||||
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 void notifyOffsetChanged() {
|
||||
final int top = getHeaderTop();
|
||||
mHeaderOffset = top - getPaddingTop();
|
||||
mDrawerCallback.topChanged(top);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
final View child = getChildAt(0);
|
||||
@ -242,47 +264,41 @@ public class HeaderDrawerLayout extends ViewGroup {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
|
||||
private boolean isTouchingScrollableContent() {
|
||||
return mTouchingScrollableContent;
|
||||
private void offsetHeaderBy(int dy) {
|
||||
final int prevTop = mContainer.getTop();
|
||||
final int clampedDy = MathUtils.clamp(prevTop + dy, getHeaderTopMinimum(), getHeaderTopMaximum()) - prevTop;
|
||||
mContainer.offsetTopAndBottom(clampedDy);
|
||||
}
|
||||
|
||||
private void notifyOffsetChanged() {
|
||||
final int top = getHeaderTop();
|
||||
mHeaderOffset = top - getPaddingTop();
|
||||
mDrawerCallback.topChanged(top);
|
||||
private void scrollByCallback(float dy) {
|
||||
setScrollingContentCallback(true);
|
||||
mDrawerCallback.scrollBy(dy);
|
||||
}
|
||||
|
||||
private float getDragTouchSlop() {
|
||||
return mDragHelper.getTouchSlop();
|
||||
private void setScrollingHeaderByGesture(boolean scrolling) {
|
||||
mScrollingHeaderByGesture = scrolling;
|
||||
}
|
||||
|
||||
private boolean isValidScroll(float direction, float other) {
|
||||
return Math.abs(direction) > getDragTouchSlop() && Math.abs(direction) > Math.abs(other);
|
||||
private boolean shouldLayoutHeaderBottomCallback() {
|
||||
return mDrawerCallback.shouldLayoutHeaderBottom();
|
||||
}
|
||||
|
||||
private boolean isScrollingHeaderByHelper() {
|
||||
return mDragCallback.isScrollingHeaderByHelper();
|
||||
}
|
||||
|
||||
private boolean isScrollingContentCallback() {
|
||||
return mScrollingContentCallback;
|
||||
}
|
||||
|
||||
private void setScrollingContentCallback(boolean scrolling) {
|
||||
mScrollingContentCallback = scrolling;
|
||||
private void updateViewOffset() {
|
||||
}
|
||||
|
||||
public static interface DrawerCallback {
|
||||
|
||||
void fling(float velocity);
|
||||
|
||||
void scrollBy(float dy);
|
||||
|
||||
boolean canScroll(float dy);
|
||||
|
||||
void cancelTouch();
|
||||
|
||||
void fling(float velocity);
|
||||
|
||||
boolean isScrollContent(float x, float y);
|
||||
|
||||
void cancelTouch();
|
||||
void scrollBy(float dy);
|
||||
|
||||
boolean shouldLayoutHeaderBottom();
|
||||
|
||||
void topChanged(int offset);
|
||||
}
|
||||
@ -369,12 +385,12 @@ public class HeaderDrawerLayout extends ViewGroup {
|
||||
mScrollingHeaderByHelper = false;
|
||||
return current;
|
||||
}
|
||||
if (dy > 0 && mDrawer.canScrollCallback(-dy)) {
|
||||
if (dy > 0 && mDrawer.canScrollCallback(-dy) && mDrawer.isTouchingScrollableContent()) {
|
||||
if (!mDrawer.isUsingDragHelper()) {
|
||||
// Scrolling up while list still has space to scroll, so make header still
|
||||
mScrollingHeaderByHelper = false;
|
||||
return current;
|
||||
} else if (mDrawer.isTouchingScrollableContent()) {
|
||||
} else {
|
||||
mDrawer.scrollByCallback(-dy);
|
||||
mScrollingHeaderByHelper = false;
|
||||
return current;
|
||||
@ -428,16 +444,24 @@ public class HeaderDrawerLayout extends ViewGroup {
|
||||
@Override
|
||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
|
||||
final int top = mDrawer.getHeaderTop(), min = mDrawer.getHeaderTopMinimum();
|
||||
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 && top <= min && mDrawer.isScrollingContentCallback()) {
|
||||
// Fling up when showing full content, so we fling list up here
|
||||
if (Math.abs(velocityY) > Math.abs(velocityX)) {
|
||||
mDrawer.flingCallback(-velocityY);
|
||||
final boolean showingFullContent = top <= min, flingUp = velocityY < 0;
|
||||
final boolean verticalFling = Math.abs(velocityY) > Math.abs(velocityX);
|
||||
if (!verticalFling) return true;
|
||||
if (showingFullContent) {
|
||||
if (flingUp) {
|
||||
// Fling list up when showing full content
|
||||
if (mDrawer.isScrollingContentCallback()) {
|
||||
mDrawer.flingCallback(-velocityY);
|
||||
}
|
||||
} else {
|
||||
// Fling down when list reached top and not dragging user ViewDragHelper,
|
||||
// so we fling header down here
|
||||
if (!mDrawer.canScrollCallback(1) && !mDrawer.isUsingDragHelper()) {
|
||||
mDrawer.flingHeader(velocityY);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Header still visible
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -464,22 +488,22 @@ public class HeaderDrawerLayout extends ViewGroup {
|
||||
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 View getHeader() {
|
||||
return mHeaderView;
|
||||
}
|
||||
|
||||
public int getHeaderTopMaximum() {
|
||||
return mParent.getPaddingTop();
|
||||
}
|
||||
|
||||
public int getHeaderTopMinimum() {
|
||||
return mParent.getPaddingTop() - mHeaderView.getHeight();
|
||||
}
|
||||
|
||||
public int getScrollRange() {
|
||||
return getHeaderTopMaximum() - getHeaderTopMinimum();
|
||||
}
|
||||
|
@ -19,20 +19,10 @@
|
||||
|
||||
package org.mariotaku.twidere.view;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Outline;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffXfermode;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewOutlineProvider;
|
||||
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.view.iface.IExtendedView;
|
||||
@ -42,9 +32,6 @@ public class ProfileBannerImageView extends ForegroundImageView implements IExte
|
||||
private OnSizeChangedListener mOnSizeChangedListener;
|
||||
private TouchInterceptor mTouchInterceptor;
|
||||
|
||||
private final Paint mClipPaint = new Paint();
|
||||
private int mBottomClip;
|
||||
|
||||
public ProfileBannerImageView(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
@ -57,18 +44,6 @@ public class ProfileBannerImageView extends ForegroundImageView implements IExte
|
||||
super(context, attrs, defStyle);
|
||||
if (isInEditMode()) return;
|
||||
setScaleType(ScaleType.CENTER_CROP);
|
||||
mClipPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||
ViewCompat.setLayerType(this, ViewCompat.LAYER_TYPE_SOFTWARE, null);
|
||||
} else {
|
||||
setOutlineProvider(new CropOutlineProvider(this));
|
||||
setClipToOutline(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasOverlappingRendering() {
|
||||
return Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -114,38 +89,4 @@ public class ProfileBannerImageView extends ForegroundImageView implements IExte
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispatchDraw(final Canvas canvas) {
|
||||
super.dispatchDraw(canvas);
|
||||
if (mBottomClip != 0 && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||
canvas.drawRect(getLeft(), getBottom() - mBottomClip - getTranslationY(), getRight(), getBottom(), mClipPaint);
|
||||
}
|
||||
}
|
||||
|
||||
public void setBottomClip(int bottom) {
|
||||
mBottomClip = bottom;
|
||||
invalidate();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
invalidateOutline();
|
||||
}
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
private static class CropOutlineProvider extends ViewOutlineProvider {
|
||||
|
||||
private final ProfileBannerImageView mImageView;
|
||||
|
||||
CropOutlineProvider(ProfileBannerImageView imageView) {
|
||||
mImageView = imageView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getOutline(View view, Outline outline) {
|
||||
final int left = view.getLeft();
|
||||
final int top = view.getTop();
|
||||
final int right = view.getRight();
|
||||
final int bottom = Math.round(view.getBottom() - mImageView.mBottomClip - view.getTranslationY());
|
||||
outline.setRect(left, top, right, bottom);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ public class TintedStatusFrameLayout extends FrameLayout {
|
||||
if (context instanceof FitSystemWindowsCallback) {
|
||||
((FitSystemWindowsCallback) context).fitSystemWindows(insets);
|
||||
}
|
||||
return false;
|
||||
return super.fitSystemWindows(insets);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -99,7 +99,7 @@ public class TintedStatusFrameLayout extends FrameLayout {
|
||||
canvas.drawRect(0, 0, canvas.getWidth(), mStatusBarHeight, mDrawColor ? mColorPaint : mBlackPaint);
|
||||
}
|
||||
|
||||
protected void setStatusBarHeight(int height) {
|
||||
public void setStatusBarHeight(int height) {
|
||||
mStatusBarHeight = height;
|
||||
invalidate();
|
||||
}
|
||||
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.holder;
|
||||
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
|
||||
import org.mariotaku.twidere.adapter.iface.IGapSupportedAdapter;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/12/3.
|
||||
*/
|
||||
public class GapViewHolder extends RecyclerView.ViewHolder implements OnClickListener {
|
||||
|
||||
private final IGapSupportedAdapter adapter;
|
||||
|
||||
public GapViewHolder(IGapSupportedAdapter adapter, View itemView) {
|
||||
super(itemView);
|
||||
this.adapter = adapter;
|
||||
itemView.setOnClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
adapter.onGapClick(this, getPosition());
|
||||
}
|
||||
}
|
@ -2,8 +2,8 @@ package org.mariotaku.twidere.view.holder;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.database.Cursor;
|
||||
import android.support.v7.widget.CardView;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
@ -13,10 +13,11 @@ import android.widget.TextView;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.iface.IStatusesAdapter;
|
||||
import org.mariotaku.twidere.constant.IntentConstants;
|
||||
import org.mariotaku.twidere.fragment.support.StatusMenuDialogFragment;
|
||||
import org.mariotaku.twidere.model.ParcelableMedia;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus.CursorIndices;
|
||||
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
||||
import org.mariotaku.twidere.util.UserColorNicknameUtils;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.view.CircularImageView;
|
||||
import org.mariotaku.twidere.view.ShortTimeView;
|
||||
@ -28,9 +29,9 @@ import static org.mariotaku.twidere.util.Utils.getUserTypeIconRes;
|
||||
/**
|
||||
* Created by mariotaku on 14/11/19.
|
||||
*/
|
||||
public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClickListener {
|
||||
public class StatusViewHolder<Data> extends RecyclerView.ViewHolder implements OnClickListener {
|
||||
|
||||
private final IStatusesAdapter adapter;
|
||||
private final IStatusesAdapter<Data> adapter;
|
||||
|
||||
private final ImageView retweetProfileImageView;
|
||||
private final CircularImageView profileImageView;
|
||||
@ -43,7 +44,7 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
|
||||
private final View mediaPreviewContainer;
|
||||
private final TextView replyCountView, retweetCountView, favoriteCountView;
|
||||
|
||||
public StatusViewHolder(IStatusesAdapter adapter, View itemView) {
|
||||
public StatusViewHolder(IStatusesAdapter<Data> adapter, View itemView) {
|
||||
super(itemView);
|
||||
this.adapter = adapter;
|
||||
itemView.findViewById(R.id.item_content).setOnClickListener(this);
|
||||
@ -63,8 +64,8 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
|
||||
replyCountView = (TextView) itemView.findViewById(R.id.reply_count);
|
||||
retweetCountView = (TextView) itemView.findViewById(R.id.retweet_count);
|
||||
favoriteCountView = (TextView) itemView.findViewById(R.id.favorite_count);
|
||||
//TODO
|
||||
// profileImageView.setSelectorColor(ThemeUtils.getUserHighlightColor(itemView.getContext()));
|
||||
//TODO
|
||||
// profileImageView.setSelectorColor(ThemeUtils.getUserHighlightColor(itemView.getContext()));
|
||||
|
||||
itemView.setOnClickListener(this);
|
||||
profileImageView.setOnClickListener(this);
|
||||
@ -90,12 +91,10 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
|
||||
replyRetweetView.setText(context.getString(R.string.name_retweeted, status.retweeted_by_name));
|
||||
}
|
||||
replyRetweetView.setVisibility(View.VISIBLE);
|
||||
// replyRetweetView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_action_retweet, 0, 0, 0);
|
||||
retweetProfileImageView.setVisibility(View.GONE);
|
||||
} else if (status.in_reply_to_status_id > 0 && status.in_reply_to_user_id > 0) {
|
||||
replyRetweetView.setText(context.getString(R.string.in_reply_to_name, status.in_reply_to_name));
|
||||
replyRetweetView.setVisibility(View.VISIBLE);
|
||||
// replyRetweetView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_action_reply, 0, 0, 0);
|
||||
retweetProfileImageView.setVisibility(View.GONE);
|
||||
} else {
|
||||
replyRetweetView.setText(null);
|
||||
@ -117,8 +116,8 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
|
||||
screenNameView.setText("@" + status.user_screen_name);
|
||||
timeView.setTime(status.timestamp);
|
||||
|
||||
// final int userColor = UserColorNicknameUtils.getUserColor(context, status.user_id);
|
||||
// profileImageView.setBorderColor(userColor);
|
||||
final int userColor = UserColorNicknameUtils.getUserColor(context, status.user_id);
|
||||
profileImageView.setBorderColor(userColor);
|
||||
|
||||
loader.displayProfileImage(profileImageView, status.user_profile_image_url);
|
||||
|
||||
@ -160,28 +159,141 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
|
||||
favoriteCountView.setActivated(status.is_favorite);
|
||||
}
|
||||
|
||||
|
||||
public void displayStatus(Cursor cursor, CursorIndices indices) {
|
||||
final ImageLoaderWrapper loader = adapter.getImageLoader();
|
||||
final Context context = adapter.getContext();
|
||||
|
||||
final int reply_count = cursor.getInt(indices.reply_count);
|
||||
final int retweet_count = cursor.getInt(indices.retweet_count);
|
||||
final int favorite_count = cursor.getInt(indices.favorite_count);
|
||||
|
||||
final long account_id = cursor.getLong(indices.account_id);
|
||||
final long timestamp = cursor.getLong(indices.status_timestamp);
|
||||
final long user_id = cursor.getLong(indices.user_id);
|
||||
final long retweet_id = cursor.getLong(indices.retweet_id);
|
||||
final long my_retweet_id = cursor.getLong(indices.my_retweet_id);
|
||||
final long retweeted_by_id = cursor.getLong(indices.retweeted_by_user_id);
|
||||
final long in_reply_to_status_id = cursor.getLong(indices.in_reply_to_status_id);
|
||||
final long in_reply_to_user_id = cursor.getLong(indices.in_reply_to_user_id);
|
||||
|
||||
final boolean user_is_protected = cursor.getInt(indices.is_protected) == 1;
|
||||
|
||||
final String user_name = cursor.getString(indices.user_name);
|
||||
final String user_screen_name = cursor.getString(indices.user_screen_name);
|
||||
final String user_profile_image_url = cursor.getString(indices.user_profile_image_url);
|
||||
final String retweeted_by_name = cursor.getString(indices.retweeted_by_user_name);
|
||||
final String in_reply_to_name = cursor.getString(indices.in_reply_to_user_name);
|
||||
|
||||
final ParcelableMedia[] media = ParcelableMedia.fromJSONString(cursor.getString(indices.media));
|
||||
|
||||
if (retweet_id > 0) {
|
||||
if (retweet_count == 2) {
|
||||
replyRetweetView.setText(context.getString(R.string.name_and_another_retweeted,
|
||||
retweeted_by_name));
|
||||
} else if (retweet_count > 2) {
|
||||
replyRetweetView.setText(context.getString(R.string.name_and_count_retweeted,
|
||||
retweeted_by_name, retweet_count - 1));
|
||||
} else {
|
||||
replyRetweetView.setText(context.getString(R.string.name_retweeted, retweeted_by_name));
|
||||
}
|
||||
replyRetweetView.setVisibility(View.VISIBLE);
|
||||
retweetProfileImageView.setVisibility(View.GONE);
|
||||
} else if (in_reply_to_status_id > 0 && in_reply_to_user_id > 0) {
|
||||
replyRetweetView.setText(context.getString(R.string.in_reply_to_name, in_reply_to_name));
|
||||
replyRetweetView.setVisibility(View.VISIBLE);
|
||||
retweetProfileImageView.setVisibility(View.GONE);
|
||||
} else {
|
||||
replyRetweetView.setText(null);
|
||||
replyRetweetView.setVisibility(View.GONE);
|
||||
replyRetweetView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
|
||||
retweetProfileImageView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
final int typeIconRes = getUserTypeIconRes(cursor.getInt(indices.is_verified) == 1,
|
||||
user_is_protected);
|
||||
if (typeIconRes != 0) {
|
||||
profileTypeView.setImageResource(typeIconRes);
|
||||
profileTypeView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
profileTypeView.setImageDrawable(null);
|
||||
profileTypeView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
nameView.setText(user_name);
|
||||
screenNameView.setText("@" + user_screen_name);
|
||||
timeView.setTime(timestamp);
|
||||
|
||||
final int userColor = UserColorNicknameUtils.getUserColor(context, user_id);
|
||||
profileImageView.setBorderColor(userColor);
|
||||
|
||||
loader.displayProfileImage(profileImageView, user_profile_image_url);
|
||||
|
||||
if (media != null && media.length > 0) {
|
||||
final String text_plain = cursor.getString(indices.text_plain);
|
||||
final String text_unescaped = cursor.getString(indices.text_unescaped);
|
||||
final ParcelableMedia firstMedia = media[0];
|
||||
if (text_plain.codePointCount(0, text_plain.length()) == firstMedia.end) {
|
||||
textView.setText(text_unescaped.substring(0, firstMedia.start));
|
||||
} else {
|
||||
textView.setText(text_unescaped);
|
||||
}
|
||||
loader.displayPreviewImageWithCredentials(mediaPreviewView, firstMedia.media_url,
|
||||
account_id, adapter.getImageLoadingHandler());
|
||||
mediaPreviewContainer.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
final String text_unescaped = cursor.getString(indices.text_unescaped);
|
||||
loader.cancelDisplayTask(mediaPreviewView);
|
||||
textView.setText(text_unescaped);
|
||||
mediaPreviewContainer.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (reply_count > 0) {
|
||||
replyCountView.setText(Utils.getLocalizedNumber(Locale.getDefault(), reply_count));
|
||||
} else {
|
||||
replyCountView.setText(null);
|
||||
}
|
||||
if (retweet_count > 0) {
|
||||
retweetCountView.setText(Utils.getLocalizedNumber(Locale.getDefault(), retweet_count));
|
||||
} else {
|
||||
retweetCountView.setText(null);
|
||||
}
|
||||
if (favorite_count > 0) {
|
||||
favoriteCountView.setText(Utils.getLocalizedNumber(Locale.getDefault(), favorite_count));
|
||||
} else {
|
||||
favoriteCountView.setText(null);
|
||||
}
|
||||
|
||||
retweetCountView.setEnabled(!user_is_protected);
|
||||
retweetCountView.setActivated(Utils.isMyRetweet(account_id, retweeted_by_id, my_retweet_id));
|
||||
favoriteCountView.setActivated(cursor.getInt(indices.is_favorite) == 1);
|
||||
}
|
||||
|
||||
public CardView getCardView() {
|
||||
return (CardView) itemView.findViewById(R.id.card);
|
||||
}
|
||||
|
||||
public CircularImageView getProfileImageView() {
|
||||
return profileImageView;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
final Context context = itemView.getContext();
|
||||
final ParcelableStatus status = adapter.getStatus(getPosition());
|
||||
final int position = getPosition();
|
||||
final ParcelableStatus status = adapter.getStatus(position);
|
||||
switch (v.getId()) {
|
||||
case R.id.item_content: {
|
||||
Utils.openStatus(context, status);
|
||||
adapter.onStatusClick(this, position);
|
||||
break;
|
||||
}
|
||||
case R.id.menu: {
|
||||
if (context instanceof FragmentActivity) {
|
||||
final Bundle args = new Bundle();
|
||||
args.putParcelable(IntentConstants.EXTRA_STATUS, status);
|
||||
final StatusMenuDialogFragment f = new StatusMenuDialogFragment();
|
||||
f.setArguments(args);
|
||||
f.show(((FragmentActivity) context).getSupportFragmentManager(), "status_menu");
|
||||
}
|
||||
adapter.onItemMenuClick(this, position);
|
||||
break;
|
||||
}
|
||||
case R.id.profile_image: {
|
||||
Utils.openUserProfile(context, status.account_id, status.user_id,
|
||||
status.user_screen_name, null);
|
||||
adapter.onUserProfileClick(this, position);
|
||||
break;
|
||||
}
|
||||
case R.id.reply_count: {
|
||||
|
@ -7,6 +7,7 @@
|
||||
android:layout_margin="@dimen/element_spacing_small"
|
||||
android:clickable="true"
|
||||
android:foreground="?android:selectableItemBackground"
|
||||
app:cardBackgroundColor="?cardItemBackgroundColor"
|
||||
app:cardCornerRadius="2dp"
|
||||
app:cardElevation="2dp">
|
||||
|
||||
|
31
twidere/src/main/res/layout/card_item_gap.xml
Normal file
31
twidere/src/main/res/layout/card_item_gap.xml
Normal file
@ -0,0 +1,31 @@
|
||||
<?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/>.
|
||||
-->
|
||||
|
||||
<TextView
|
||||
android:id="@+id/gap_indicator"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/element_size_normal"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:gravity="center"
|
||||
android:text="@string/load_more"
|
||||
android:textAppearance="?android:textAppearanceMedium"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textStyle="bold"/>
|
@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.v7.widget.CardView
|
||||
android:id="@+id/card"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -21,10 +21,5 @@
|
||||
|
||||
</android.support.v4.widget.SwipeRefreshLayout>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progress"
|
||||
style="?android:progressBarStyleLarge"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"/>
|
||||
<include layout="@layout/layout_content_fragment_common"/>
|
||||
</FrameLayout>
|
@ -30,13 +30,18 @@
|
||||
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"
|
||||
<FrameLayout
|
||||
android:id="@+id/profile_banner_container"
|
||||
android:layout_gravity="top"
|
||||
android:scaleType="centerCrop"/>
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<org.mariotaku.twidere.view.ProfileBannerImageView
|
||||
android:id="@+id/profile_banner"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:scaleType="centerCrop"/>
|
||||
</FrameLayout>
|
||||
|
||||
<org.mariotaku.twidere.view.HeaderDrawerLayout
|
||||
android:id="@+id/user_profile_drawer"
|
||||
@ -46,6 +51,4 @@
|
||||
app:headerLayout="@layout/header_user"/>
|
||||
</org.mariotaku.twidere.view.ExtendedFrameLayout>
|
||||
|
||||
<include layout="@layout/layout_content_fragment_common"/>
|
||||
|
||||
</FrameLayout>
|
@ -5,7 +5,7 @@
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/profile_banner"
|
||||
android:id="@+id/account_profile_banner"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignBottom="@id/profile_container"
|
||||
@ -35,7 +35,7 @@
|
||||
android:layout_marginTop="@dimen/element_spacing_mlarge"/>
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/account_selector"
|
||||
android:id="@+id/other_accounts_list"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignBottom="@id/profile_image"
|
||||
|
@ -6,6 +6,7 @@
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<android.support.v7.widget.CardView
|
||||
android:id="@+id/card"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/element_spacing_normal"
|
||||
@ -14,7 +15,6 @@
|
||||
app:cardElevation="@dimen/elevation_card">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/card"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
@ -48,8 +48,8 @@
|
||||
android:layout_height="@dimen/element_size_mlarge"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:contentDescription="@string/profile_image"
|
||||
android:layout_margin="@dimen/padding_profile_image_detail_page"
|
||||
android:contentDescription="@string/profile_image"
|
||||
android:scaleType="centerCrop"
|
||||
app:border="true"
|
||||
app:borderWidth="1dp"/>
|
||||
|
@ -43,7 +43,7 @@
|
||||
android:layout_alignRight="@id/profile_image"
|
||||
android:scaleType="fitCenter"/>
|
||||
|
||||
<org.mariotaku.twidere.view.ColorLabelLinearLayout
|
||||
<org.mariotaku.twidere.view.ColorLabelRelativeLayout
|
||||
android:id="@+id/profile_name_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@ -55,40 +55,37 @@
|
||||
android:padding="@dimen/element_spacing_small"
|
||||
app:ignorePadding="true">
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:id="@+id/name"
|
||||
android:layout_width="match_parent"
|
||||
<Button
|
||||
android:id="@+id/follow"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:text="@string/name"
|
||||
android:textAppearance="?android:textAppearanceMedium"/>
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerInParent="true"
|
||||
android:minWidth="48dp"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_toLeftOf="@id/follow"
|
||||
android:orientation="vertical">
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:id="@+id/name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:textAppearanceMedium"/>
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:id="@+id/screen_name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:singleLine="true"
|
||||
android:text="@string/screen_name"
|
||||
android:textAppearance="?android:textAppearanceSmall"/>
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:id="@+id/following_you_indicator"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:singleLine="true"
|
||||
android:text="@string/following_you"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textColor="?android:textColorTertiary"
|
||||
android:visibility="gone"/>
|
||||
</LinearLayout>
|
||||
</org.mariotaku.twidere.view.ColorLabelLinearLayout>
|
||||
|
||||
</org.mariotaku.twidere.view.ColorLabelRelativeLayout>
|
||||
|
||||
<android.support.v7.widget.CardView
|
||||
android:id="@+id/card"
|
||||
@ -101,6 +98,7 @@
|
||||
app:cardElevation="@dimen/elevation_card">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/card_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
@ -304,6 +302,9 @@
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<include layout="@layout/layout_content_fragment_common"/>
|
||||
|
||||
</android.support.v7.widget.CardView>
|
||||
|
||||
<org.mariotaku.twidere.view.AssetFontTextView
|
||||
|
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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"/>
|
@ -23,7 +23,8 @@
|
||||
<FrameLayout
|
||||
android:id="@+id/progress_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="match_parent"
|
||||
android:padding="@dimen/element_spacing_large">
|
||||
|
||||
<ProgressBar
|
||||
style="?android:progressBarStyleLarge"
|
||||
@ -38,7 +39,7 @@
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp"
|
||||
android:padding="@dimen/element_spacing_large"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
|
@ -1,65 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2012 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
|
||||
<!-- Layout of a header item in PreferenceActivity. -->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:attr/activatedBackgroundIndicator"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="48dp"
|
||||
android:paddingEnd="?android:attr/scrollbarSize">
|
||||
|
||||
<ImageView
|
||||
android:id="@android:id/icon"
|
||||
android:layout_width="@dimen/header_icon_width"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginLeft="6dip"
|
||||
android:layout_marginRight="6dip"/>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="6dip"
|
||||
android:layout_marginEnd="6dip"
|
||||
android:layout_marginStart="2dip"
|
||||
android:layout_marginTop="6dip"
|
||||
android:layout_weight="1">
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="marquee"
|
||||
android:fadingEdge="horizontal"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"/>
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/summary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignStart="@android:id/summary"
|
||||
android:layout_below="@android:id/title"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="2"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"/>
|
||||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
@ -0,0 +1,43 @@
|
||||
<?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/>.
|
||||
-->
|
||||
|
||||
|
||||
<!-- Layout of a header item in PreferenceActivity. -->
|
||||
<android.support.v7.widget.CardView
|
||||
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"
|
||||
app:cardBackgroundColor="?android:colorBackground"
|
||||
app:cardCornerRadius="0dp"
|
||||
app:cardElevation="4dp">
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:padding="@dimen/element_spacing_normal"
|
||||
android:singleLine="true"
|
||||
android:textAllCaps="true"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textStyle="bold"/>
|
||||
|
||||
</android.support.v7.widget.CardView>
|
@ -0,0 +1,75 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2012 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
|
||||
<!-- Layout of a header item in PreferenceActivity. -->
|
||||
<android.support.v7.widget.CardView
|
||||
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"
|
||||
app:cardBackgroundColor="?android:colorBackground"
|
||||
app:cardCornerRadius="0dp"
|
||||
app:cardElevation="4dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="?android:listPreferredItemHeight"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@android:id/icon"
|
||||
android:layout_width="@dimen/header_icon_width"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginLeft="@dimen/element_spacing_large"
|
||||
android:layout_marginRight="@dimen/element_spacing_large"/>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="6dip"
|
||||
android:layout_marginEnd="6dip"
|
||||
android:layout_marginStart="2dip"
|
||||
android:layout_marginTop="6dip"
|
||||
android:layout_weight="1">
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="marquee"
|
||||
android:fadingEdge="horizontal"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"/>
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/summary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignStart="@android:id/summary"
|
||||
android:layout_below="@android:id/title"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="2"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"/>
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</android.support.v7.widget.CardView>
|
@ -0,0 +1,23 @@
|
||||
<?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/>.
|
||||
-->
|
||||
|
||||
<Space xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/element_spacing_normal"/>
|
28
twidere/src/main/res/transition/transition_status.xml
Normal file
28
twidere/src/main/res/transition/transition_status.xml
Normal file
@ -0,0 +1,28 @@
|
||||
<?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">
|
||||
<fade>
|
||||
<targets>
|
||||
<target android:targetId="@id/card"/>
|
||||
</targets>
|
||||
</fade>
|
||||
</transitionSet>
|
@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<style name="Widget.CardActionButton" parent="android:Widget.DeviceDefault.ImageButton">
|
||||
<style name="Widget.CardActionButton" parent="Widget.Base.ImageButton">
|
||||
<item name="android:background">?android:selectableItemBackgroundBorderless</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Light.CardActionButton" parent="android:Widget.DeviceDefault.ImageButton">
|
||||
<style name="Widget.Light.CardActionButton" parent="Widget.Base.ImageButton">
|
||||
<item name="android:background">?android:selectableItemBackgroundBorderless</item>
|
||||
</style>
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
<item name="borderWidth">2dp</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.ProfileType" parent="android:Widget.DeviceDefault">
|
||||
<style name="Widget.ProfileType" parent="Widget.Base">
|
||||
<item name="android:elevation">@dimen/elevation_card</item>
|
||||
<item name="android:outlineProvider">none</item>
|
||||
</style>
|
||||
|
47
twidere/src/main/res/values-v21/styles_base.xml
Normal file
47
twidere/src/main/res/values-v21/styles_base.xml
Normal file
@ -0,0 +1,47 @@
|
||||
<?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/>.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
|
||||
<style name="Widget.Base" parent="android:Widget.Material"/>
|
||||
|
||||
<style name="Widget.Base.ActionButton.Overflow" parent="android:Widget.Material.ActionButton.Overflow"/>
|
||||
|
||||
<style name="Widget.Base.ActionButton" parent="android:Widget.Material.ActionButton"/>
|
||||
|
||||
<style name="Widget.Base.Light.ActionButton.Overflow" parent="android:Widget.Material.Light.ActionButton.Overflow"/>
|
||||
|
||||
<style name="Widget.Base.Light.ActionButton" parent="android:Widget.Material.Light.ActionButton"/>
|
||||
|
||||
<style name="Widget.Base.Light" parent="android:Widget.Material.Light"/>
|
||||
|
||||
<style name="Widget.Base.Light.ImageButton" parent="android:Widget.Material.Light.ImageButton"/>
|
||||
|
||||
<style name="Widget.Base.ImageButton" parent="android:Widget.Material.ImageButton"/>
|
||||
|
||||
<style name="Widget.Base.ActionBar" parent="android:Widget.Material.ActionBar"/>
|
||||
|
||||
<style name="Widget.Base.ActionBar.Solid" parent="android:Widget.Material.ActionBar.Solid"/>
|
||||
|
||||
<style name="Widget.Base.Light.ActionBar.Solid" parent="android:Widget.Material.Light.ActionBar.Solid"/>
|
||||
|
||||
<style name="Widget.Base.Light.ActionBar.Solid.Inverse" parent="android:Widget.Holo.Light.ActionBar.Solid.Inverse"/>
|
||||
|
||||
</resources>
|
35
twidere/src/main/res/values-v21/themes_base.xml
Normal file
35
twidere/src/main/res/values-v21/themes_base.xml
Normal file
@ -0,0 +1,35 @@
|
||||
<?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/>.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
|
||||
<style name="Theme.Base" parent="android:Theme.Material"/>
|
||||
|
||||
<style name="Theme.Base.NoActionBar" parent="android:Theme.Material.NoActionBar"/>
|
||||
|
||||
<style name="Theme.Base.Dialog" parent="android:Theme.Material.Dialog"/>
|
||||
|
||||
<style name="Theme.Base.Light" parent="android:Theme.Material.Light"/>
|
||||
|
||||
<style name="Theme.Base.Light.DarkActionBar" parent="android:Theme.Material.Light.DarkActionBar"/>
|
||||
|
||||
<style name="Theme.Base.Light.Dialog" parent="android:Theme.Material.Light.Dialog"/>
|
||||
|
||||
</resources>
|
@ -678,5 +678,7 @@
|
||||
<string name="profile_banner">Profile banner</string>
|
||||
<string name="profile">Profile</string>
|
||||
<string name="listed">Listed</string>
|
||||
<string name="state_blocking">Blocking</string>
|
||||
<string name="load_more">Load more</string>
|
||||
|
||||
</resources>
|
@ -1,65 +1,65 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<style name="Widget.Twidere.ActionBar.Colored" parent="android:Widget.DeviceDefault.Light.ActionBar.Solid">
|
||||
<style name="Widget.Twidere.ActionBar.Colored" parent="Widget.Base.Light.ActionBar.Solid">
|
||||
<item name="android:background">@drawable/ab_twidere_solid_color_holo</item>
|
||||
<!--<item name="android:background">@android:color/transparent</item>-->
|
||||
</style>
|
||||
|
||||
<style name="Widget.Twidere.ActionBar.Colored.Inverse" parent="android:Widget.DeviceDefault.Light.ActionBar.Solid.Inverse">
|
||||
<style name="Widget.Twidere.ActionBar.Colored.Inverse" parent="Widget.Base.Light.ActionBar.Solid.Inverse">
|
||||
<item name="android:background">@drawable/ab_twidere_solid_color_holo</item>
|
||||
<!--<item name="android:background">@android:color/transparent</item>-->
|
||||
</style>
|
||||
|
||||
<style name="Widget.Twidere.ActionBar.Dark" parent="android:Widget.DeviceDefault.ActionBar.Solid">
|
||||
<style name="Widget.Twidere.ActionBar.Dark" parent="Widget.Base.ActionBar.Solid">
|
||||
<item name="android:background">@drawable/ab_twidere_solid_dark_holo</item>
|
||||
<!--<item name="android:background">@android:color/transparent</item>-->
|
||||
</style>
|
||||
|
||||
<style name="Widget.Twidere.ActionBar.Light" parent="android:Widget.DeviceDefault.Light.ActionBar.Solid">
|
||||
<style name="Widget.Twidere.ActionBar.Light" parent="Widget.Base.Light.ActionBar.Solid">
|
||||
<item name="android:background">@drawable/ab_twidere_solid_light_holo</item>
|
||||
<!--<item name="android:background">@android:color/transparent</item>-->
|
||||
</style>
|
||||
|
||||
<style name="Widget.Twidere.ActionBar.Light.DarkActionBar" parent="android:Widget.DeviceDefault.Light.ActionBar.Solid.Inverse">
|
||||
<style name="Widget.Twidere.ActionBar.Light.DarkActionBar" parent="Widget.Base.Light.ActionBar.Solid.Inverse">
|
||||
<item name="android:background">@drawable/ab_twidere_solid_dark_holo</item>
|
||||
<!--<item name="android:background">@android:color/transparent</item>-->
|
||||
</style>
|
||||
|
||||
<style name="Widget.Twidere.Viewer.ActionBar" parent="android:Widget.DeviceDefault.ActionBar">
|
||||
<style name="Widget.Twidere.Viewer.ActionBar" parent="Widget.Base.ActionBar">
|
||||
<item name="android:background">#80000000</item>
|
||||
<item name="android:backgroundSplit">#80000000</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Twidere.ImageButton.Borderless" parent="android:Widget.DeviceDefault.ImageButton">
|
||||
<style name="Widget.Twidere.ImageButton.Borderless" parent="Widget.Base.ImageButton">
|
||||
<item name="android:background">?android:attr/selectableItemBackground</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Twidere.Light.ImageButton.Borderless" parent="android:Widget.DeviceDefault.Light.ImageButton">
|
||||
<style name="Widget.Twidere.Light.ImageButton.Borderless" parent="Widget.Base.Light.ImageButton">
|
||||
<item name="android:background">?android:attr/selectableItemBackground</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Twidere.SelectableView" parent="android:Widget.DeviceDefault">
|
||||
<style name="Widget.Twidere.SelectableView" parent="Widget.Base">
|
||||
<item name="android:background">?android:attr/selectableItemBackground</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Twidere.Light.SelectableView" parent="android:Widget.DeviceDefault.Light">
|
||||
<style name="Widget.Twidere.Light.SelectableView" parent="Widget.Base.Light">
|
||||
<item name="android:background">?android:attr/selectableItemBackground</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Twidere.ActionButton.Colored" parent="android:Widget.DeviceDefault.Light.ActionButton">
|
||||
<style name="Widget.Twidere.ActionButton.Colored" parent="Widget.Base.Light.ActionButton">
|
||||
<item name="android:background">?android:actionBarItemBackground</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Twidere.ActionButton.Overflow.Colored" parent="android:Widget.DeviceDefault.Light.ActionButton.Overflow">
|
||||
<style name="Widget.Twidere.ActionButton.Overflow.Colored" parent="Widget.Base.Light.ActionButton.Overflow">
|
||||
<item name="android:background">?android:actionBarItemBackground</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Twidere.ActionButton.Colored.DarkActionBar" parent="android:Widget.DeviceDefault.ActionButton">
|
||||
<style name="Widget.Twidere.ActionButton.Colored.DarkActionBar" parent="Widget.Base.ActionButton">
|
||||
<item name="android:background">?android:actionBarItemBackground</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Twidere.ActionButton.Overflow.Colored.DarkActionBar" parent="android:Widget.DeviceDefault.ActionButton.Overflow">
|
||||
<style name="Widget.Twidere.ActionButton.Overflow.Colored.DarkActionBar" parent="Widget.Base.ActionButton.Overflow">
|
||||
<item name="android:background">?android:actionBarItemBackground</item>
|
||||
</style>
|
||||
|
||||
@ -118,7 +118,7 @@
|
||||
<item name="scrimAlpha">0.75</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.CardItemView" parent="android:Widget.DeviceDefault">
|
||||
<style name="Widget.CardItemView" parent="Widget.Base">
|
||||
<item name="cardBackground">?cardItemBackground</item>
|
||||
<item name="cardBackgroundAlpha">50%p</item>
|
||||
<item name="cardSelector">?android:selectableItemBackground</item>
|
||||
@ -130,7 +130,7 @@
|
||||
<item name="cardGapTextSize">18sp</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.CardItemView.Light" parent="android:Widget.DeviceDefault">
|
||||
<style name="Widget.CardItemView.Light" parent="Widget.Base">
|
||||
<item name="cardBackground">?cardItemBackground</item>
|
||||
<item name="cardBackgroundAlpha">50%p</item>
|
||||
<item name="cardSelector">?android:selectableItemBackground</item>
|
||||
@ -142,26 +142,26 @@
|
||||
<item name="cardGapTextSize">18sp</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.StaggeredGridView" parent="android:Widget.DeviceDefault">
|
||||
<style name="Widget.StaggeredGridView" parent="Widget.Base">
|
||||
<item name="column_count_portrait">@integer/staggered_grid_columns_port</item>
|
||||
<item name="column_count_landscape">@integer/staggered_grid_columns_land</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.CardActionButton" parent="android:Widget.DeviceDefault.ImageButton">
|
||||
<style name="Widget.CardActionButton" parent="Widget.Base.ImageButton">
|
||||
<item name="android:background">?android:selectableItemBackground</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Light.CardActionButton" parent="android:Widget.DeviceDefault.Light.ImageButton">
|
||||
<style name="Widget.Light.CardActionButton" parent="Widget.Base.Light.ImageButton">
|
||||
<item name="android:background">?android:selectableItemBackground</item>
|
||||
</style>
|
||||
|
||||
|
||||
<style name="Widget.ProfileImage" parent="android:Widget.DeviceDefault">
|
||||
<style name="Widget.ProfileImage" parent="Widget.Base">
|
||||
<item name="android:scaleType">centerCrop</item>
|
||||
<item name="borderWidth">1dp</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Light.ProfileImage" parent="android:Widget.DeviceDefault">
|
||||
<style name="Widget.Light.ProfileImage" parent="Widget.Base">
|
||||
<item name="android:scaleType">centerCrop</item>
|
||||
<item name="borderWidth">1dp</item>
|
||||
</style>
|
||||
@ -186,6 +186,6 @@
|
||||
<item name="borderWidth">2dp</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.ProfileType" parent="android:Widget.DeviceDefault">
|
||||
<style name="Widget.ProfileType" parent="Widget.Base">
|
||||
</style>
|
||||
</resources>
|
47
twidere/src/main/res/values/styles_base.xml
Normal file
47
twidere/src/main/res/values/styles_base.xml
Normal file
@ -0,0 +1,47 @@
|
||||
<?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/>.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
|
||||
<style name="Widget.Base" parent="android:Widget.Holo"/>
|
||||
|
||||
<style name="Widget.Base.ActionButton.Overflow" parent="android:Widget.Holo.ActionButton.Overflow"/>
|
||||
|
||||
<style name="Widget.Base.ActionButton" parent="android:Widget.Holo.ActionButton"/>
|
||||
|
||||
<style name="Widget.Base.Light.ActionButton.Overflow" parent="android:Widget.Holo.Light.ActionButton.Overflow"/>
|
||||
|
||||
<style name="Widget.Base.Light.ActionButton" parent="android:Widget.Holo.Light.ActionButton"/>
|
||||
|
||||
<style name="Widget.Base.Light" parent="android:Widget.Holo.Light"/>
|
||||
|
||||
<style name="Widget.Base.Light.ImageButton" parent="android:Widget.Holo.Light.ImageButton"/>
|
||||
|
||||
<style name="Widget.Base.ImageButton" parent="android:Widget.Holo.ImageButton"/>
|
||||
|
||||
<style name="Widget.Base.ActionBar" parent="android:Widget.Holo.ActionBar"/>
|
||||
|
||||
<style name="Widget.Base.ActionBar.Solid" parent="android:Widget.Holo.ActionBar.Solid"/>
|
||||
|
||||
<style name="Widget.Base.Light.ActionBar.Solid" parent="android:Widget.Holo.Light.ActionBar.Solid"/>
|
||||
|
||||
<style name="Widget.Base.Light.ActionBar.Solid.Inverse" parent="android:Widget.Holo.Light.ActionBar.Solid.Inverse"/>
|
||||
|
||||
</resources>
|
@ -7,16 +7,16 @@
|
||||
<item name="android:windowAnimationStyle">@android:style/Animation.Activity</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Blank" parent="android:Theme.DeviceDefault.NoActionBar">
|
||||
<style name="Theme.Blank" parent="Theme.Base.NoActionBar">
|
||||
|
||||
<!-- Window attributes -->
|
||||
<!--<item name="android:windowAnimationStyle">@style/Animation.Twidere.Activity</item>-->
|
||||
<item name="android:windowBackground">@android:color/black</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Blank.Dialog" parent="android:Theme.DeviceDefault.Dialog"/>
|
||||
<style name="Theme.Blank.Dialog" parent="Theme.Base.Dialog"/>
|
||||
|
||||
<style name="Theme.Twidere.Dark" parent="android:Theme.DeviceDefault">
|
||||
<style name="Theme.Twidere.Dark" parent="Theme.Base">
|
||||
|
||||
<!-- Colors -->
|
||||
<!--<item name="android:colorBackgroundCacheHint">@color/bg_color_dark</item>-->
|
||||
@ -64,7 +64,7 @@
|
||||
<item name="messageBubbleColor">@color/message_bubble_color_dark</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Twidere.Light" parent="android:Theme.DeviceDefault.Light.DarkActionBar">
|
||||
<style name="Theme.Twidere.Light" parent="Theme.Base.Light.DarkActionBar">
|
||||
|
||||
<!-- Colors -->
|
||||
<!--<item name="android:colorBackgroundCacheHint">@color/bg_color_light</item>-->
|
||||
@ -155,7 +155,7 @@
|
||||
<!--<item name="android:actionBarItemBackground">@drawable/list_selector_white</item>-->
|
||||
</style>
|
||||
|
||||
<style name="Theme.Twidere.Dark.Dialog" parent="android:Theme.DeviceDefault.Dialog">
|
||||
<style name="Theme.Twidere.Dark.Dialog" parent="Theme.Base.Dialog">
|
||||
|
||||
<!-- Custom view styles -->
|
||||
<item name="tabItemStyle">@style/Widget.TabPageIndicator.TabItem</item>
|
||||
@ -190,7 +190,7 @@
|
||||
<item name="messageBubbleColor">@color/message_bubble_color_dark</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Twidere.Light.Dialog" parent="android:Theme.DeviceDefault.Light.Dialog">
|
||||
<style name="Theme.Twidere.Light.Dialog" parent="Theme.Base.Light.Dialog">
|
||||
|
||||
<!-- Custom view styles -->
|
||||
<item name="tabItemStyle">@style/Widget.TabPageIndicator.TabItem</item>
|
||||
@ -251,7 +251,7 @@
|
||||
<item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Twidere.Viewer" parent="android:Theme.DeviceDefault">
|
||||
<style name="Theme.Twidere.Viewer" parent="Theme.Base">
|
||||
|
||||
<!-- Window attributes -->
|
||||
<item name="android:windowActionBarOverlay">true</item>
|
||||
@ -321,7 +321,7 @@
|
||||
<!-- Window attributes -->
|
||||
</style>
|
||||
|
||||
<style name="Theme.Twidere.Dark.NoDisplay" parent="android:Theme.DeviceDefault">
|
||||
<style name="Theme.Twidere.Dark.NoDisplay" parent="Theme.Base">
|
||||
<item name="android:windowBackground">@null</item>
|
||||
<item name="android:windowContentOverlay">@null</item>
|
||||
<item name="android:windowIsTranslucent">true</item>
|
||||
@ -330,7 +330,7 @@
|
||||
<item name="android:windowNoDisplay">true</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Twidere.Light.NoDisplay" parent="android:Theme.DeviceDefault.Light">
|
||||
<style name="Theme.Twidere.Light.NoDisplay" parent="Theme.Base.Light">
|
||||
<item name="android:windowBackground">@null</item>
|
||||
<item name="android:windowContentOverlay">@null</item>
|
||||
<item name="android:windowIsTranslucent">true</item>
|
||||
@ -339,16 +339,16 @@
|
||||
<item name="android:windowNoDisplay">true</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Test" parent="android:Theme.DeviceDefault">
|
||||
<style name="Theme.Test" parent="Theme.Base">
|
||||
<item name="android:windowActionBarOverlay">true</item>
|
||||
<item name="android:windowActionModeOverlay">true</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Nyan" parent="android:Theme.DeviceDefault.NoActionBar">
|
||||
<style name="Theme.Nyan" parent="Theme.Base.NoActionBar">
|
||||
<item name="android:windowBackground">@color/nyan_background</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Twidere.Settings.Dark" parent="android:Theme.DeviceDefault">
|
||||
<style name="Theme.Twidere.Settings.Dark" parent="Theme.Base">
|
||||
|
||||
<!-- Colors -->
|
||||
<item name="android:colorBackgroundCacheHint">@color/bg_color_dark</item>
|
||||
@ -393,7 +393,7 @@
|
||||
<item name="messageBubbleColor">@color/message_bubble_color_dark</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Twidere.Settings.Light" parent="android:Theme.DeviceDefault.Light">
|
||||
<style name="Theme.Twidere.Settings.Light" parent="Theme.Base.Light">
|
||||
|
||||
<!-- Colors -->
|
||||
<item name="android:colorBackgroundCacheHint">@color/bg_color_light</item>
|
||||
@ -434,7 +434,7 @@
|
||||
<item name="messageBubbleColor">@color/message_bubble_color_light</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Twidere.Settings.Light.DarkActionBar" parent="android:Theme.DeviceDefault.Light.DarkActionBar">
|
||||
<style name="Theme.Twidere.Settings.Light.DarkActionBar" parent="Theme.Base.Light.DarkActionBar">
|
||||
|
||||
<!-- Colors -->
|
||||
<!--<item name="android:colorBackgroundCacheHint">@color/bg_color_light</item>-->
|
||||
|
35
twidere/src/main/res/values/themes_base.xml
Normal file
35
twidere/src/main/res/values/themes_base.xml
Normal file
@ -0,0 +1,35 @@
|
||||
<?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/>.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
|
||||
<style name="Theme.Base" parent="android:Theme.Holo"/>
|
||||
|
||||
<style name="Theme.Base.NoActionBar" parent="android:Theme.Holo.NoActionBar"/>
|
||||
|
||||
<style name="Theme.Base.Dialog" parent="android:Theme.Holo.Dialog"/>
|
||||
|
||||
<style name="Theme.Base.Light" parent="android:Theme.Holo.Light"/>
|
||||
|
||||
<style name="Theme.Base.Light.DarkActionBar" parent="android:Theme.Holo.Light.DarkActionBar"/>
|
||||
|
||||
<style name="Theme.Base.Light.Dialog" parent="android:Theme.Holo.Light.Dialog"/>
|
||||
|
||||
</resources>
|
@ -1,99 +1,94 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/cards">
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/cards">
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="cat_card_preview"
|
||||
android:order="11"
|
||||
android:title="@string/preview">
|
||||
<org.mariotaku.twidere.preference.CardPreviewPreference android:key="card_preview"/>
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory
|
||||
android:key="cat_card_preview"
|
||||
android:order="11"
|
||||
android:title="@string/preview">
|
||||
<org.mariotaku.twidere.preference.CardPreviewPreference android:key="card_preview"/>
|
||||
</PreferenceCategory>
|
||||
|
||||
<org.mariotaku.twidere.preference.SeekBarDialogPreference
|
||||
android:defaultValue="@integer/default_text_size"
|
||||
android:key="text_size_int"
|
||||
android:order="21"
|
||||
android:summary="@string/text_size_summary"
|
||||
android:title="@string/text_size"
|
||||
app:max="24"
|
||||
app:min="12"
|
||||
app:progressTextSuffix="sp"/>
|
||||
<org.mariotaku.twidere.preference.SeekBarDialogPreference
|
||||
android:defaultValue="@integer/default_text_size"
|
||||
android:key="text_size_int"
|
||||
android:order="21"
|
||||
android:summary="@string/text_size_summary"
|
||||
android:title="@string/text_size"
|
||||
app:max="24"
|
||||
app:min="12"
|
||||
app:progressTextSuffix="sp"/>
|
||||
|
||||
<org.mariotaku.twidere.preference.AutoFixCheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
android:key="name_first"
|
||||
android:order="22"
|
||||
android:title="@string/name_first"/>
|
||||
<org.mariotaku.twidere.preference.AutoFixCheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:key="nickname_only"
|
||||
android:order="23"
|
||||
android:summary="@string/nickname_only_summary"
|
||||
android:title="@string/nickname_only"/>
|
||||
<org.mariotaku.twidere.preference.AutoFixCheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
android:key="display_profile_image"
|
||||
android:order="24"
|
||||
android:summary="@string/image_load_summary"
|
||||
android:title="@string/display_profile_image"/>
|
||||
<org.mariotaku.twidere.preference.AutoFixCheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:key="display_image_preview"
|
||||
android:order="25"
|
||||
android:summary="@string/image_load_summary"
|
||||
android:title="@string/display_image_preview"/>
|
||||
<org.mariotaku.twidere.preference.AutoFixCheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
android:key="name_first"
|
||||
android:order="22"
|
||||
android:title="@string/name_first"/>
|
||||
<org.mariotaku.twidere.preference.AutoFixCheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:key="nickname_only"
|
||||
android:order="23"
|
||||
android:summary="@string/nickname_only_summary"
|
||||
android:title="@string/nickname_only"/>
|
||||
<org.mariotaku.twidere.preference.AutoFixCheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
android:key="display_profile_image"
|
||||
android:order="24"
|
||||
android:summary="@string/image_load_summary"
|
||||
android:title="@string/display_profile_image"/>
|
||||
<org.mariotaku.twidere.preference.AutoFixCheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:key="display_image_preview"
|
||||
android:order="25"
|
||||
android:summary="@string/image_load_summary"
|
||||
android:title="@string/display_image_preview"/>
|
||||
|
||||
<org.mariotaku.twidere.preference.AutoFixListPreference
|
||||
android:defaultValue="CENTER_CROP"
|
||||
android:entries="@array/entries_image_preview_scale_type"
|
||||
android:entryValues="@array/values_image_preview_scale_type"
|
||||
android:key="image_preview_scale_type"
|
||||
android:order="26"
|
||||
android:summary="%s"
|
||||
android:title="@string/image_preview_scale_type"/>
|
||||
<org.mariotaku.twidere.preference.AutoFixListPreference
|
||||
android:defaultValue="CENTER_CROP"
|
||||
android:entries="@array/entries_image_preview_scale_type"
|
||||
android:entryValues="@array/values_image_preview_scale_type"
|
||||
android:key="image_preview_scale_type"
|
||||
android:order="26"
|
||||
android:summary="%s"
|
||||
android:title="@string/image_preview_scale_type"/>
|
||||
|
||||
<org.mariotaku.twidere.preference.LinkHighlightPreference
|
||||
android:defaultValue="none"
|
||||
android:key="link_highlight_option"
|
||||
android:order="27"
|
||||
android:title="@string/link_highlight_option"/>
|
||||
<org.mariotaku.twidere.preference.LinkHighlightPreference
|
||||
android:defaultValue="none"
|
||||
android:key="link_highlight_option"
|
||||
android:order="27"
|
||||
android:title="@string/link_highlight_option"/>
|
||||
|
||||
<org.mariotaku.twidere.preference.AutoInvalidateListPreference
|
||||
android:defaultValue="background"
|
||||
android:entries="@array/entries_card_highlight_option"
|
||||
android:entryValues="@array/values_card_highlight_option"
|
||||
android:key="card_highlight_option"
|
||||
android:order="28"
|
||||
android:summary="%s"
|
||||
android:title="@string/card_highlight_option"/>
|
||||
<org.mariotaku.twidere.preference.AutoInvalidateListPreference
|
||||
android:defaultValue="background"
|
||||
android:entries="@array/entries_card_highlight_option"
|
||||
android:entryValues="@array/values_card_highlight_option"
|
||||
android:key="card_highlight_option"
|
||||
android:order="28"
|
||||
android:summary="%s"
|
||||
android:title="@string/card_highlight_option"/>
|
||||
|
||||
<org.mariotaku.twidere.preference.AutoFixCheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
android:key="indicate_my_status"
|
||||
android:order="29"
|
||||
android:title="@string/indicate_your_status"/>
|
||||
<org.mariotaku.twidere.preference.AutoFixCheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:key="show_absolute_time"
|
||||
android:order="30"
|
||||
android:summary="@string/show_absolute_time_summary"
|
||||
android:title="@string/show_absolute_time"/>
|
||||
<org.mariotaku.twidere.preference.AutoFixCheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
android:key="card_animation"
|
||||
android:order="31"
|
||||
android:title="@string/card_animation"/>
|
||||
<org.mariotaku.twidere.preference.AutoFixCheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:key="compact_cards"
|
||||
android:order="32"
|
||||
android:summary="@string/compact_cards_summary"
|
||||
android:title="@string/compact_cards"/>
|
||||
<org.mariotaku.twidere.preference.AutoFixCheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:key="plain_list_style"
|
||||
android:order="33"
|
||||
android:title="@string/plain_list_style"/>
|
||||
<org.mariotaku.twidere.preference.AutoFixCheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
android:key="indicate_my_status"
|
||||
android:order="29"
|
||||
android:title="@string/indicate_your_status"/>
|
||||
<org.mariotaku.twidere.preference.AutoFixCheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:key="show_absolute_time"
|
||||
android:order="30"
|
||||
android:summary="@string/show_absolute_time_summary"
|
||||
android:title="@string/show_absolute_time"/>
|
||||
<org.mariotaku.twidere.preference.AutoFixCheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
android:key="card_animation"
|
||||
android:order="31"
|
||||
android:title="@string/card_animation"/>
|
||||
<org.mariotaku.twidere.preference.AutoFixCheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:key="compact_cards"
|
||||
android:order="32"
|
||||
android:summary="@string/compact_cards_summary"
|
||||
android:title="@string/compact_cards"/>
|
||||
|
||||
</PreferenceScreen>
|
Loading…
x
Reference in New Issue
Block a user