removed unused resource
improved favorite feature improving tab indicator
|
@ -92,7 +92,6 @@ dependencies {
|
|||
compile 'org.apache.httpcomponents:httpclient-android:4.3.5'
|
||||
compile 'org.apache.httpcomponents:httpmime:4.3.5'
|
||||
compile 'com.google.android.apps.dashclock:dashclock-api:2.0.0'
|
||||
compile 'com.astuetz:pagerslidingtabstrip:1.0.1'
|
||||
compile 'com.squareup:otto:1.3.5'
|
||||
googleCompile 'com.google.android.gms:play-services:6.5.87'
|
||||
fdroidCompile 'org.osmdroid:osmdroid-android:4.2'
|
||||
|
|
|
@ -532,13 +532,11 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
|
|||
mTabIndicator.setViewPager(mViewPager);
|
||||
mTabIndicator.setOnPageChangeListener(this);
|
||||
if (mTabDisplayOption != 0) {
|
||||
mTabIndicator.setDisplayLabel((mTabDisplayOption & VALUE_TAB_DIPLAY_OPTION_CODE_LABEL) != 0);
|
||||
mTabIndicator.setDisplayIcon((mTabDisplayOption & VALUE_TAB_DIPLAY_OPTION_CODE_ICON) != 0);
|
||||
mTabIndicator.setTabDisplayOption(mTabDisplayOption);
|
||||
} else {
|
||||
mTabIndicator.setDisplayLabel(false);
|
||||
mTabIndicator.setDisplayIcon(true);
|
||||
mTabIndicator.setTabDisplayOption(TabPagerIndicator.ICON);
|
||||
}
|
||||
// mTabIndicator.setDisplayBadge(mPreferences.getBoolean(KEY_UNREAD_COUNT, true));
|
||||
mTabIndicator.setDisplayBadge(mPreferences.getBoolean(KEY_UNREAD_COUNT, true));
|
||||
mActionsButton.setOnClickListener(this);
|
||||
mActionsButton.setOnLongClickListener(this);
|
||||
setTabPosition(initialTabPosition);
|
||||
|
|
|
@ -16,6 +16,7 @@ import org.mariotaku.twidere.adapter.iface.IStatusesAdapter;
|
|||
import org.mariotaku.twidere.app.TwidereApplication;
|
||||
import org.mariotaku.twidere.fragment.support.UserFragment;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
||||
import org.mariotaku.twidere.util.ImageLoadingHandler;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
|
@ -38,15 +39,18 @@ public abstract class AbsStatusesAdapter<D> extends Adapter<ViewHolder> implemen
|
|||
private final ImageLoaderWrapper mImageLoader;
|
||||
private final ImageLoadingHandler mLoadingHandler;
|
||||
private final int mCardLayoutResource;
|
||||
private final AsyncTwitterWrapper mTwitterWrapper;
|
||||
private boolean mLoadMoreIndicatorEnabled;
|
||||
|
||||
private StatusAdapterListener mStatusAdapterListener;
|
||||
|
||||
public AbsStatusesAdapter(Context context, boolean compact) {
|
||||
mContext = context;
|
||||
final TwidereApplication app = TwidereApplication.getInstance(context);
|
||||
mInflater = LayoutInflater.from(context);
|
||||
mImageLoader = TwidereApplication.getInstance(context).getImageLoaderWrapper();
|
||||
mImageLoader = app.getImageLoaderWrapper();
|
||||
mLoadingHandler = new ImageLoadingHandler(R.id.media_preview_progress);
|
||||
mTwitterWrapper = app.getTwitterWrapper();
|
||||
if (compact) {
|
||||
mCardLayoutResource = R.layout.card_item_status_compat;
|
||||
} else {
|
||||
|
@ -54,62 +58,13 @@ public abstract class AbsStatusesAdapter<D> extends Adapter<ViewHolder> implemen
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
switch (viewType) {
|
||||
case ITEM_VIEW_TYPE_STATUS: {
|
||||
final View view = mInflater.inflate(mCardLayoutResource, parent, false);
|
||||
final StatusViewHolder holder = new StatusViewHolder(this, view);
|
||||
holder.setupViews();
|
||||
return holder;
|
||||
}
|
||||
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);
|
||||
return new LoadIndicatorViewHolder(view);
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("Unknown view type " + viewType);
|
||||
}
|
||||
public abstract D getData();
|
||||
|
||||
public void setLoadMoreIndicatorEnabled(boolean enabled) {
|
||||
if (mLoadMoreIndicatorEnabled == enabled) return;
|
||||
mLoadMoreIndicatorEnabled = enabled;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public boolean hasLoadMoreIndicator() {
|
||||
return mLoadMoreIndicatorEnabled;
|
||||
}
|
||||
public abstract void setData(D data);
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(ViewHolder holder, int position) {
|
||||
switch (holder.getItemViewType()) {
|
||||
case ITEM_VIEW_TYPE_STATUS: {
|
||||
bindStatus(((StatusViewHolder) holder), position);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void bindStatus(StatusViewHolder holder, int position);
|
||||
|
||||
@Override
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getItemCount() {
|
||||
return getStatusCount() + (mLoadMoreIndicatorEnabled ? 1 : 0);
|
||||
public AsyncTwitterWrapper getTwitterWrapper() {
|
||||
return mTwitterWrapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -150,6 +105,63 @@ public abstract class AbsStatusesAdapter<D> extends Adapter<ViewHolder> implemen
|
|||
}
|
||||
}
|
||||
|
||||
public boolean hasLoadMoreIndicator() {
|
||||
return mLoadMoreIndicatorEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
switch (viewType) {
|
||||
case ITEM_VIEW_TYPE_STATUS: {
|
||||
final View view = mInflater.inflate(mCardLayoutResource, parent, false);
|
||||
final StatusViewHolder holder = new StatusViewHolder(this, view);
|
||||
holder.setupViews();
|
||||
return holder;
|
||||
}
|
||||
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);
|
||||
return new LoadIndicatorViewHolder(view);
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("Unknown view type " + viewType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(ViewHolder holder, int position) {
|
||||
switch (holder.getItemViewType()) {
|
||||
case ITEM_VIEW_TYPE_STATUS: {
|
||||
bindStatus(((StatusViewHolder) holder), position);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getItemCount() {
|
||||
return getStatusCount() + (mLoadMoreIndicatorEnabled ? 1 : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onGapClick(ViewHolder holder, int position) {
|
||||
if (mStatusAdapterListener != null) {
|
||||
mStatusAdapterListener.onGapClick((GapViewHolder) holder, position);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemActionClick(ViewHolder holder, int id, int position) {
|
||||
if (mStatusAdapterListener != null) {
|
||||
|
@ -164,28 +176,25 @@ public abstract class AbsStatusesAdapter<D> extends Adapter<ViewHolder> implemen
|
|||
}
|
||||
}
|
||||
|
||||
public abstract void setData(D data);
|
||||
|
||||
public abstract D getData();
|
||||
|
||||
public void setEventListener(StatusAdapterListener listener) {
|
||||
mStatusAdapterListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onGapClick(ViewHolder holder, int position) {
|
||||
if (mStatusAdapterListener != null) {
|
||||
mStatusAdapterListener.onGapClick((GapViewHolder) holder, position);
|
||||
}
|
||||
public void setLoadMoreIndicatorEnabled(boolean enabled) {
|
||||
if (mLoadMoreIndicatorEnabled == enabled) return;
|
||||
mLoadMoreIndicatorEnabled = enabled;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
protected abstract void bindStatus(StatusViewHolder holder, int position);
|
||||
|
||||
public static interface StatusAdapterListener {
|
||||
void onGapClick(GapViewHolder holder, int position);
|
||||
|
||||
void onStatusActionClick(StatusViewHolder holder, int id, int position);
|
||||
|
||||
void onStatusClick(StatusViewHolder holder, int position);
|
||||
|
||||
void onGapClick(GapViewHolder holder, int position);
|
||||
|
||||
void onStatusMenuClick(StatusViewHolder holder, int position);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ import android.database.Cursor;
|
|||
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus.CursorIndices;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
import org.mariotaku.twidere.view.holder.StatusViewHolder;
|
||||
|
||||
/**
|
||||
|
@ -72,7 +73,6 @@ public class CursorStatusesAdapter extends AbsStatusesAdapter<Cursor> {
|
|||
mIndices = data != null ? new CursorIndices(data) : null;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor getData() {
|
||||
return mCursor;
|
||||
|
|
|
@ -1,347 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.adapter;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.support.v7.widget.RecyclerView.ViewHolder;
|
||||
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.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.util.ImageLoadingHandler;
|
||||
import org.mariotaku.twidere.util.MultiSelectManager;
|
||||
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.util.Utils.configBaseCardAdapter;
|
||||
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 ParcelableStatusesListAdapter extends BaseArrayAdapter<ParcelableStatus> implements
|
||||
IStatusesListAdapter<List<ParcelableStatus>>, OnClickListener, OnOverflowIconClickListener {
|
||||
|
||||
private final Context mContext;
|
||||
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 ScaleType mImagePreviewScaleType;
|
||||
private String[] mHighlightKeywords;
|
||||
|
||||
public ParcelableStatusesListAdapter(final Context context) {
|
||||
this(context, Utils.isCompactCards(context));
|
||||
}
|
||||
|
||||
public ParcelableStatusesListAdapter(final Context context, final boolean compactCards) {
|
||||
super(context, getItemResource(compactCards));
|
||||
mContext = context;
|
||||
final TwidereApplication app = TwidereApplication.getInstance(context);
|
||||
mMultiSelectManager = app.getMultiSelectManager();
|
||||
mDatabase = app.getSQLiteDatabase();
|
||||
mImageLoadingHandler = new ImageLoadingHandler();
|
||||
configBaseCardAdapter(context, this);
|
||||
setMaxAnimationPosition(-1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int findPositionByStatusId(final long status_id) {
|
||||
for (int i = 0, count = getCount(); i < count; i++) {
|
||||
if (getItem(i).id == status_id) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getAccountId(final int position) {
|
||||
if (position >= 0 && position < getCount()) {
|
||||
final ParcelableStatus status = getItem(position);
|
||||
return status != null ? status.account_id : -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatusCount() {
|
||||
return super.getCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemActionClick(ViewHolder holder, int id, int position) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemMenuClick(ViewHolder 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 long getItemId(final int position) {
|
||||
final ParcelableStatus item = getItem(position);
|
||||
return item != null ? item.id : -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelableStatus getLastStatus() {
|
||||
if (super.getCount() == 0) return null;
|
||||
return getItem(super.getCount() - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastStatusId() {
|
||||
if (super.getCount() == 0) return -1;
|
||||
return getItem(super.getCount() - 1).id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageLoadingHandler getImageLoadingHandler() {
|
||||
return mImageLoadingHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelableStatus getStatus(final int position) {
|
||||
return getItem(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getStatusId(final int position) {
|
||||
if (position >= 0 && position < getCount()) {
|
||||
final ParcelableStatus status = getItem(position);
|
||||
return status != null ? status.id : -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@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 StatusViewHolder holder;
|
||||
if (tag instanceof StatusViewHolder) {
|
||||
holder = (StatusViewHolder) tag;
|
||||
} else {
|
||||
holder = new StatusViewHolder(this, view);
|
||||
view.setTag(holder);
|
||||
}
|
||||
final ParcelableStatus status = getItem(position);
|
||||
holder.displayStatus(status);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGapItem(int position) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGapClick(ViewHolder holder, int position) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLastItemFiltered() {
|
||||
return mIsLastItemFiltered;
|
||||
}
|
||||
|
||||
@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;
|
||||
if (mContext instanceof Activity) {
|
||||
openUserProfile(mContext, status.account_id, status.user_id,
|
||||
status.user_screen_name, null);
|
||||
}
|
||||
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 List<ParcelableStatus> data) {
|
||||
clear();
|
||||
if (data != null && !data.isEmpty()) {
|
||||
addAll(data);
|
||||
}
|
||||
rebuildFilterInfo();
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGapDisallowed(final boolean disallowed) {
|
||||
mGapDisallowed = disallowed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHighlightKeyword(final String... keywords) {
|
||||
mHighlightKeywords = keywords;
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
private void rebuildFilterInfo() {
|
||||
if (!isEmpty()) {
|
||||
final ParcelableStatus last = getItem(super.getCount() - 1);
|
||||
final long user_id = mFilterIgnoreUser ? -1 : last.user_id;
|
||||
final String text_plain = mFilterIgnoreTextPlain ? null : last.text_plain;
|
||||
final String text_html = mFilterIgnoreTextHtml ? null : last.text_html;
|
||||
final String source = mFilterIgnoreSource ? null : last.source;
|
||||
final long retweeted_by_id = mFilterRetweetedById ? -1 : last.retweeted_by_id;
|
||||
mIsLastItemFiltered = isFiltered(mDatabase, user_id, text_plain, text_html, source, retweeted_by_id);
|
||||
} else {
|
||||
mIsLastItemFiltered = false;
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private static int getItemResource(final boolean compactCards) {
|
||||
return compactCards ? R.layout.card_item_status_compat : R.layout.card_item_status;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,157 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Adapter;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.BaseAdapter;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class SeparatedListAdapter<T extends Adapter> extends BaseAdapter {
|
||||
|
||||
private final Map<String, T> mSections = new LinkedHashMap<String, T>();
|
||||
private final ArrayAdapter<String> mHeaders;
|
||||
private final static int TYPE_SECTION_HEADER = 0;
|
||||
|
||||
public SeparatedListAdapter(final Context context) {
|
||||
mHeaders = new ArrayAdapter<String>(context, R.layout.list_item_section_header);
|
||||
}
|
||||
|
||||
public void addSection(final String section, final T adapter) {
|
||||
mHeaders.add(section);
|
||||
mSections.put(section, adapter);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public boolean areAllItemsSelectable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
mHeaders.clear();
|
||||
mSections.clear();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public ArrayList<T> getAdapters() {
|
||||
return new ArrayList<T>(mSections.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
// total together all sections, plus one for each section header
|
||||
int total = 0;
|
||||
for (final T adapter : mSections.values()) {
|
||||
total += adapter.getCount() + 1;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItem(int position) {
|
||||
for (final Object section : mSections.keySet()) {
|
||||
final Adapter adapter = mSections.get(section);
|
||||
final int size = adapter.getCount() + 1;
|
||||
|
||||
// check if position inside this section
|
||||
if (position == 0) return section;
|
||||
if (position < size) return adapter.getItem(position - 1);
|
||||
|
||||
// otherwise jump into next section
|
||||
position -= size;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(final int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
int type = 1;
|
||||
for (final Object section : mSections.keySet()) {
|
||||
final Adapter adapter = mSections.get(section);
|
||||
final int size = adapter.getCount() + 1;
|
||||
|
||||
// check if position inside this section
|
||||
if (position == 0) return TYPE_SECTION_HEADER;
|
||||
if (position < size) return type + adapter.getItemViewType(position - 1);
|
||||
|
||||
// otherwise jump into next section
|
||||
position -= size;
|
||||
type += adapter.getViewTypeCount();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, final View convertView, final ViewGroup parent) {
|
||||
int sectionnum = 0;
|
||||
for (final Object section : mSections.keySet()) {
|
||||
final Adapter adapter = mSections.get(section);
|
||||
final int size = adapter.getCount() + 1;
|
||||
|
||||
// check if position inside this section
|
||||
if (position == 0) return mHeaders.getView(sectionnum, convertView, parent);
|
||||
if (position < size) return adapter.getView(position - 1, convertView, parent);
|
||||
|
||||
// otherwise jump into next section
|
||||
position -= size;
|
||||
sectionnum++;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViewTypeCount() {
|
||||
// assume that headers count as one, then total all sections
|
||||
int total = 1;
|
||||
for (final Adapter adapter : mSections.values()) {
|
||||
total += adapter.getViewTypeCount();
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(final int position) {
|
||||
return getItemViewType(position) != TYPE_SECTION_HEADER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyDataSetChanged() {
|
||||
for (final T adapter : mSections.values()) {
|
||||
if (adapter instanceof BaseAdapter) {
|
||||
((BaseAdapter) adapter).notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
super.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
}
|
|
@ -3,6 +3,7 @@ package org.mariotaku.twidere.adapter.iface;
|
|||
import android.content.Context;
|
||||
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
||||
import org.mariotaku.twidere.util.ImageLoadingHandler;
|
||||
import org.mariotaku.twidere.view.holder.StatusViewHolder;
|
||||
|
@ -27,4 +28,6 @@ public interface IStatusesAdapter<Data> extends IGapSupportedAdapter, ICardSuppo
|
|||
void onUserProfileClick(StatusViewHolder holder, int position);
|
||||
|
||||
void setData(Data data);
|
||||
|
||||
AsyncTwitterWrapper getTwitterWrapper();
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import android.view.View;
|
|||
import android.view.ViewGroup;
|
||||
|
||||
import com.squareup.otto.Bus;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.AbsStatusesAdapter;
|
||||
|
@ -31,6 +32,7 @@ import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
|||
import org.mariotaku.twidere.util.SimpleDrawerCallback;
|
||||
import org.mariotaku.twidere.util.ThemeUtils;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.util.message.StatusListChangedEvent;
|
||||
import org.mariotaku.twidere.view.HeaderDrawerLayout.DrawerCallback;
|
||||
import org.mariotaku.twidere.view.holder.GapViewHolder;
|
||||
import org.mariotaku.twidere.view.holder.StatusViewHolder;
|
||||
|
@ -41,6 +43,13 @@ import org.mariotaku.twidere.view.holder.StatusViewHolder;
|
|||
public abstract class AbsStatusesFragment<Data> extends BaseSupportFragment implements LoaderCallbacks<Data>,
|
||||
OnRefreshListener, DrawerCallback, RefreshScrollTopInterface, StatusAdapterListener {
|
||||
|
||||
|
||||
private final Object mStatusesBusCallback;
|
||||
|
||||
protected AbsStatusesFragment() {
|
||||
mStatusesBusCallback = createMessageBusCallback();
|
||||
}
|
||||
|
||||
private View mContentView;
|
||||
private SharedPreferences mPreferences;
|
||||
private View mProgressContainer;
|
||||
|
@ -151,19 +160,13 @@ public abstract class AbsStatusesFragment<Data> extends BaseSupportFragment impl
|
|||
public void onStart() {
|
||||
super.onStart();
|
||||
final Bus bus = TwidereApplication.getInstance(getActivity()).getMessageBus();
|
||||
final Object callback = getMessageBusCallback();
|
||||
if (callback != null) {
|
||||
bus.register(callback);
|
||||
}
|
||||
bus.register(mStatusesBusCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
final Bus bus = TwidereApplication.getInstance(getActivity()).getMessageBus();
|
||||
final Object callback = getMessageBusCallback();
|
||||
if (callback != null) {
|
||||
bus.unregister(callback);
|
||||
}
|
||||
bus.unregister(mStatusesBusCallback);
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
|
@ -273,8 +276,8 @@ public abstract class AbsStatusesFragment<Data> extends BaseSupportFragment impl
|
|||
mAdapter.setData(data);
|
||||
}
|
||||
|
||||
protected Object getMessageBusCallback() {
|
||||
return null;
|
||||
protected Object createMessageBusCallback() {
|
||||
return new StatusesBusCallback();
|
||||
}
|
||||
|
||||
protected abstract AbsStatusesAdapter<Data> onCreateAdapter(Context context, boolean compact);
|
||||
|
@ -285,4 +288,17 @@ public abstract class AbsStatusesFragment<Data> extends BaseSupportFragment impl
|
|||
mProgressContainer.setVisibility(shown ? View.GONE : View.VISIBLE);
|
||||
mSwipeRefreshLayout.setVisibility(shown ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
|
||||
protected final class StatusesBusCallback {
|
||||
|
||||
protected StatusesBusCallback() {
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void notifyStatusListChanged(StatusListChangedEvent event) {
|
||||
mAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,592 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment.support;
|
||||
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.support.v4.util.LongSparseArray;
|
||||
import android.util.Log;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MenuItem.OnMenuItemClickListener;
|
||||
import android.view.View;
|
||||
import android.widget.AbsListView;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemLongClickListener;
|
||||
import android.widget.ImageView.ScaleType;
|
||||
import android.widget.ListView;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.iface.IBaseCardAdapter.MenuButtonClickListener;
|
||||
import org.mariotaku.twidere.adapter.iface.IStatusesListAdapter;
|
||||
import org.mariotaku.twidere.model.ParcelableAccount;
|
||||
import org.mariotaku.twidere.model.ParcelableAccount.ParcelableAccountWithCredentials;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.task.TwidereAsyncTask;
|
||||
import org.mariotaku.twidere.util.AsyncTaskManager;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
import org.mariotaku.twidere.util.ClipboardUtils;
|
||||
import org.mariotaku.twidere.util.MultiSelectManager;
|
||||
import org.mariotaku.twidere.util.PositionManager;
|
||||
import org.mariotaku.twidere.util.TwitterWrapper;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.util.collection.NoDuplicatesCopyOnWriteArrayList;
|
||||
import org.mariotaku.twidere.view.holder.StatusListViewHolder;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.mariotaku.twidere.util.Utils.clearListViewChoices;
|
||||
import static org.mariotaku.twidere.util.Utils.configBaseCardAdapter;
|
||||
import static org.mariotaku.twidere.util.Utils.isMyRetweet;
|
||||
import static org.mariotaku.twidere.util.Utils.openStatus;
|
||||
import static org.mariotaku.twidere.util.Utils.showOkMessage;
|
||||
import static org.mariotaku.twidere.util.Utils.startStatusShareChooser;
|
||||
|
||||
abstract class BaseStatusesListFragment<Data> extends BasePullToRefreshListFragment implements LoaderCallbacks<Data>,
|
||||
OnItemLongClickListener, OnMenuItemClickListener, MultiSelectManager.Callback, MenuButtonClickListener {
|
||||
|
||||
private AsyncTaskManager mAsyncTaskManager;
|
||||
private SharedPreferences mPreferences;
|
||||
|
||||
private ListView mListView;
|
||||
private IStatusesListAdapter<Data> mAdapter;
|
||||
|
||||
private Data mData;
|
||||
private ParcelableStatus mSelectedStatus;
|
||||
|
||||
private boolean mLoadMoreAutomatically;
|
||||
private int mListScrollOffset;
|
||||
|
||||
private MultiSelectManager mMultiSelectManager;
|
||||
private PositionManager mPositionManager;
|
||||
|
||||
private int mFirstVisibleItem;
|
||||
private int mSelectedPosition;
|
||||
|
||||
private final LongSparseArray<Set<Long>> mUnreadCountsToRemove = new LongSparseArray<>();
|
||||
private final List<Integer> mReadPositions = new NoDuplicatesCopyOnWriteArrayList<>();
|
||||
|
||||
private RemoveUnreadCountsTask<Data> mRemoveUnreadCountsTask;
|
||||
|
||||
public AsyncTaskManager getAsyncTaskManager() {
|
||||
return mAsyncTaskManager;
|
||||
}
|
||||
|
||||
public final Data getData() {
|
||||
return mData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStatusesListAdapter<Data> getListAdapter() {
|
||||
return mAdapter;
|
||||
}
|
||||
|
||||
public ParcelableStatus getSelectedStatus() {
|
||||
return mSelectedStatus;
|
||||
}
|
||||
|
||||
public SharedPreferences getSharedPreferences() {
|
||||
return mPreferences;
|
||||
}
|
||||
|
||||
public abstract int getStatuses(long[] account_ids, long[] max_ids, long[] since_ids);
|
||||
|
||||
public final LongSparseArray<Set<Long>> getUnreadCountsToRemove() {
|
||||
return mUnreadCountsToRemove;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
final Context context = getActivity();
|
||||
mAsyncTaskManager = getAsyncTaskManager();
|
||||
mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
||||
mPositionManager = new PositionManager(context);
|
||||
mMultiSelectManager = getMultiSelectManager();
|
||||
mListView = getListView();
|
||||
final boolean compactCards = mPreferences.getBoolean(KEY_COMPACT_CARDS, false);
|
||||
mAdapter = newAdapterInstance(compactCards);
|
||||
mAdapter.setMenuButtonClickListener(this);
|
||||
setListAdapter(null);
|
||||
setListHeaderFooters(mListView);
|
||||
setListAdapter(mAdapter);
|
||||
if (!compactCards) {
|
||||
mListView.setDivider(null);
|
||||
}
|
||||
mListView.setSelector(android.R.color.transparent);
|
||||
mListView.setOnItemLongClickListener(this);
|
||||
setListShown(false);
|
||||
getLoaderManager().initLoader(0, getArguments(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract Loader<Data> onCreateLoader(int id, Bundle args);
|
||||
|
||||
@Override
|
||||
public boolean onItemLongClick(final AdapterView<?> parent, final View view, final int position, final long id) {
|
||||
final Object tag = view.getTag();
|
||||
if (tag instanceof StatusListViewHolder) {
|
||||
final StatusListViewHolder holder = (StatusListViewHolder) tag;
|
||||
final ParcelableStatus status = mAdapter.getStatus(position - mListView.getHeaderViewsCount());
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
if (twitter != null) {
|
||||
TwitterWrapper.removeUnreadCounts(getActivity(), getTabPosition(), status.account_id, status.id);
|
||||
}
|
||||
if (holder.show_as_gap) return false;
|
||||
if (mPreferences.getBoolean(KEY_LONG_CLICK_TO_OPEN_MENU, false)) {
|
||||
openMenu(holder.content.getFakeOverflowButton(), status, position);
|
||||
} else {
|
||||
setItemSelected(status, position, !mMultiSelectManager.isSelected(status));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemsCleared() {
|
||||
clearListViewChoices(mListView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemSelected(final Object item) {
|
||||
mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemUnselected(final Object item) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onListItemClick(final ListView l, final View v, final int position, final long id) {
|
||||
final Object tag = v.getTag();
|
||||
if (tag instanceof StatusListViewHolder) {
|
||||
final int pos = position - l.getHeaderViewsCount();
|
||||
final ParcelableStatus status = mAdapter.getStatus(pos);
|
||||
if (status == null) return;
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
if (twitter != null) {
|
||||
TwitterWrapper.removeUnreadCounts(getActivity(), getTabPosition(), status.account_id, status.id);
|
||||
}
|
||||
if (((StatusListViewHolder) tag).show_as_gap) {
|
||||
final long since_id = position + 1 < mAdapter.getStatusCount() ? mAdapter.getStatus(pos + 1).id : -1;
|
||||
getStatuses(new long[]{status.account_id}, new long[]{status.id}, new long[]{since_id});
|
||||
mListView.setItemChecked(position, false);
|
||||
} else {
|
||||
if (mMultiSelectManager.isActive()) {
|
||||
setItemSelected(status, position, !mMultiSelectManager.isSelected(status));
|
||||
return;
|
||||
}
|
||||
openStatus(getActivity(), status.account_id, status.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onLoaderReset(final Loader<Data> loader) {
|
||||
mAdapter.setData(mData = null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(final Loader<Data> loader, final Data data) {
|
||||
if (getActivity() == null || getView() == null) return;
|
||||
setListShown(true);
|
||||
setRefreshComplete();
|
||||
setProgressBarIndeterminateVisibility(false);
|
||||
setData(data);
|
||||
mFirstVisibleItem = -1;
|
||||
mReadPositions.clear();
|
||||
final int firstVisiblePosition = mListView.getFirstVisiblePosition();
|
||||
final int lastVisiblePosition = mListView.getLastVisiblePosition();
|
||||
final int listVisiblePosition, savedChildIndex;
|
||||
final boolean rememberPosition = mPreferences.getBoolean(KEY_REMEMBER_POSITION, true);
|
||||
final boolean loadMoreFromTop = mPreferences.getBoolean(KEY_LOAD_MORE_FROM_TOP, false);
|
||||
final int childCount = mListView.getChildCount();
|
||||
if (firstVisiblePosition != 0 && lastVisiblePosition != mListView.getCount() - 1 && loadMoreFromTop) {
|
||||
listVisiblePosition = lastVisiblePosition;
|
||||
savedChildIndex = childCount - 1;
|
||||
if (childCount > 0) {
|
||||
final View lastChild = mListView.getChildAt(savedChildIndex);
|
||||
mListScrollOffset = lastChild != null ? lastChild.getTop() - mListView.getListPaddingTop() : 0;
|
||||
}
|
||||
} else {
|
||||
listVisiblePosition = firstVisiblePosition;
|
||||
savedChildIndex = 0;
|
||||
if (childCount > 0) {
|
||||
final View firstChild = mListView.getChildAt(savedChildIndex);
|
||||
mListScrollOffset = firstChild != null ? firstChild.getTop() - mListView.getListPaddingTop() : 0;
|
||||
}
|
||||
}
|
||||
final long lastViewedId = mAdapter.getStatusId(listVisiblePosition);
|
||||
mAdapter.setData(data);
|
||||
mAdapter.setShowAccountColor(shouldShowAccountColor());
|
||||
final int currFirstVisiblePosition = mListView.getFirstVisiblePosition();
|
||||
final long currViewedId = mAdapter.getStatusId(currFirstVisiblePosition);
|
||||
final long statusId;
|
||||
if (lastViewedId <= 0) {
|
||||
if (!rememberPosition) return;
|
||||
statusId = mPositionManager.getPosition(getPositionKey());
|
||||
} else if ((listVisiblePosition > 0 || rememberPosition) && currViewedId > 0 && lastViewedId != currViewedId) {
|
||||
statusId = lastViewedId;
|
||||
} else {
|
||||
if (listVisiblePosition == 0 && mAdapter.getStatusId(0) != lastViewedId) {
|
||||
mAdapter.setMaxAnimationPosition(mListView.getLastVisiblePosition());
|
||||
}
|
||||
return;
|
||||
}
|
||||
final int position = mAdapter.findPositionByStatusId(statusId);
|
||||
if (position > -1 && position < mListView.getCount()) {
|
||||
mAdapter.setMaxAnimationPosition(mListView.getLastVisiblePosition());
|
||||
mListView.setSelectionFromTop(position, mListScrollOffset);
|
||||
mListScrollOffset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMenuButtonClick(final View button, final int position, final long id) {
|
||||
if (mMultiSelectManager.isActive()) return;
|
||||
final ParcelableStatus status = mAdapter.getStatus(position);
|
||||
if (status == null) return;
|
||||
openMenu(button, status, position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean onMenuItemClick(final MenuItem item) {
|
||||
final ParcelableStatus status = mSelectedStatus;
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
if (status == null || twitter == null) return false;
|
||||
switch (item.getItemId()) {
|
||||
case MENU_VIEW: {
|
||||
openStatus(getActivity(), status, null);
|
||||
break;
|
||||
}
|
||||
case MENU_SHARE: {
|
||||
startStatusShareChooser(getActivity(), status);
|
||||
break;
|
||||
}
|
||||
case MENU_COPY: {
|
||||
if (ClipboardUtils.setText(getActivity(), status.text_plain)) {
|
||||
showOkMessage(getActivity(), R.string.text_copied, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MENU_RETWEET: {
|
||||
if (isMyRetweet(status)) {
|
||||
twitter.cancelRetweetAsync(status.account_id, status.id, status.my_retweet_id);
|
||||
} else {
|
||||
twitter.retweetStatusAsync(status.account_id, status.id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MENU_QUOTE: {
|
||||
final Intent intent = new Intent(INTENT_ACTION_QUOTE);
|
||||
final Bundle bundle = new Bundle();
|
||||
bundle.putParcelable(EXTRA_STATUS, status);
|
||||
intent.putExtras(bundle);
|
||||
startActivity(intent);
|
||||
break;
|
||||
}
|
||||
case MENU_REPLY: {
|
||||
final Intent intent = new Intent(INTENT_ACTION_REPLY);
|
||||
final Bundle bundle = new Bundle();
|
||||
bundle.putParcelable(EXTRA_STATUS, status);
|
||||
intent.putExtras(bundle);
|
||||
startActivity(intent);
|
||||
break;
|
||||
}
|
||||
case MENU_FAVORITE: {
|
||||
if (status.is_favorite) {
|
||||
twitter.destroyFavoriteAsync(status.account_id, status.id);
|
||||
} else {
|
||||
twitter.createFavoriteAsync(status.account_id, status.id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MENU_DELETE: {
|
||||
DestroyStatusDialogFragment.show(getFragmentManager(), status);
|
||||
break;
|
||||
}
|
||||
case MENU_ADD_TO_FILTER: {
|
||||
AddStatusFilterDialogFragment.show(getFragmentManager(), status);
|
||||
break;
|
||||
}
|
||||
case MENU_TRANSLATE: {
|
||||
final ParcelableAccountWithCredentials account = ParcelableAccount.getAccountWithCredentials(getActivity(),
|
||||
status.account_id);
|
||||
if (ParcelableAccountWithCredentials.isOfficialCredentials(getActivity(), account)) {
|
||||
StatusTranslateDialogFragment.show(getFragmentManager(), status);
|
||||
} else {
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MENU_MULTI_SELECT: {
|
||||
final boolean isSelected = !mMultiSelectManager.isSelected(status);
|
||||
setItemSelected(status, mSelectedPosition, isSelected);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
if (item.getIntent() != null) {
|
||||
try {
|
||||
startActivity(item.getIntent());
|
||||
} catch (final ActivityNotFoundException e) {
|
||||
Log.w(LOGTAG, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRefreshFromEnd() {
|
||||
if (mLoadMoreAutomatically) return;
|
||||
loadMoreStatuses();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mListView.setFastScrollEnabled(mPreferences.getBoolean(KEY_FAST_SCROLL_THUMB, false));
|
||||
configBaseCardAdapter(getActivity(), mAdapter);
|
||||
final boolean displayImagePreview = mPreferences.getBoolean(KEY_DISPLAY_IMAGE_PREVIEW, false);
|
||||
final boolean displaySensitiveContents = mPreferences.getBoolean(KEY_DISPLAY_SENSITIVE_CONTENTS, false);
|
||||
final boolean indicateMyStatus = mPreferences.getBoolean(KEY_INDICATE_MY_STATUS, true);
|
||||
final String cardHighlightOption = mPreferences.getString(KEY_CARD_HIGHLIGHT_OPTION,
|
||||
DEFAULT_CARD_HIGHLIGHT_OPTION);
|
||||
final String previewScaleType = Utils.getNonEmptyString(mPreferences, KEY_IMAGE_PREVIEW_SCALE_TYPE,
|
||||
ScaleType.CENTER_CROP.name());
|
||||
mAdapter.setDisplayImagePreview(displayImagePreview);
|
||||
mAdapter.setImagePreviewScaleType(previewScaleType);
|
||||
mAdapter.setDisplaySensitiveContents(displaySensitiveContents);
|
||||
mAdapter.setIndicateMyStatusDisabled(isMyTimeline() || !indicateMyStatus);
|
||||
mAdapter.setCardHighlightOption(cardHighlightOption);
|
||||
mAdapter.notifyDataSetChanged();
|
||||
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 onScrollStateChanged(final AbsListView view, final int scrollState) {
|
||||
super.onScrollStateChanged(view, scrollState);
|
||||
switch (scrollState) {
|
||||
case SCROLL_STATE_IDLE:
|
||||
for (int i = mListView.getFirstVisiblePosition(), j = mListView.getLastVisiblePosition(); i < j; i++) {
|
||||
mReadPositions.add(i);
|
||||
}
|
||||
removeUnreadCounts();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
mMultiSelectManager.registerCallback(this);
|
||||
final int choiceMode = mListView.getChoiceMode();
|
||||
if (mMultiSelectManager.isActive()) {
|
||||
if (choiceMode != ListView.CHOICE_MODE_MULTIPLE) {
|
||||
mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
|
||||
}
|
||||
} else {
|
||||
if (choiceMode != ListView.CHOICE_MODE_NONE) {
|
||||
Utils.clearListViewChoices(mListView);
|
||||
}
|
||||
}
|
||||
updateRefreshState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
savePosition();
|
||||
mMultiSelectManager.unregisterCallback(this);
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean scrollToStart() {
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
final int tab_position = getTabPosition();
|
||||
if (twitter != null && tab_position >= 0) {
|
||||
twitter.clearUnreadCountAsync(tab_position);
|
||||
}
|
||||
return super.scrollToStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUserVisibleHint(final boolean isVisibleToUser) {
|
||||
super.setUserVisibleHint(isVisibleToUser);
|
||||
updateRefreshState();
|
||||
}
|
||||
|
||||
protected final int getListScrollOffset() {
|
||||
return mListScrollOffset;
|
||||
}
|
||||
|
||||
protected abstract long[] getNewestStatusIds();
|
||||
|
||||
protected abstract long[] getOldestStatusIds();
|
||||
|
||||
protected abstract String getPositionKey();
|
||||
|
||||
protected boolean isMyTimeline() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected abstract void loadMoreStatuses();
|
||||
|
||||
protected abstract IStatusesListAdapter<Data> newAdapterInstance(boolean compact);
|
||||
|
||||
@Override
|
||||
protected void onReachedBottom() {
|
||||
if (!mLoadMoreAutomatically) return;
|
||||
loadMoreStatuses();
|
||||
}
|
||||
|
||||
protected void savePosition() {
|
||||
final int first_visible_position = mListView.getFirstVisiblePosition();
|
||||
if (mListView.getChildCount() > 0) {
|
||||
final View first_child = mListView.getChildAt(0);
|
||||
mListScrollOffset = first_child != null ? first_child.getTop() : 0;
|
||||
}
|
||||
final long status_id = mAdapter.getStatusId(first_visible_position);
|
||||
mPositionManager.setPosition(getPositionKey(), status_id);
|
||||
}
|
||||
|
||||
protected final void setData(final Data data) {
|
||||
mData = data;
|
||||
}
|
||||
|
||||
protected void setItemSelected(final ParcelableStatus status, final int position, final boolean selected) {
|
||||
if (selected) {
|
||||
mMultiSelectManager.selectItem(status);
|
||||
} else {
|
||||
mMultiSelectManager.unselectItem(status);
|
||||
}
|
||||
if (position >= 0) {
|
||||
mListView.setItemChecked(position, selected);
|
||||
}
|
||||
}
|
||||
|
||||
protected void setListHeaderFooters(final ListView list) {
|
||||
|
||||
}
|
||||
|
||||
protected boolean shouldEnablePullToRefresh() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected abstract boolean shouldShowAccountColor();
|
||||
|
||||
protected abstract void updateRefreshState();
|
||||
|
||||
private void addReadPosition(final int firstVisibleItem) {
|
||||
if (mFirstVisibleItem != firstVisibleItem) {
|
||||
mReadPositions.add(firstVisibleItem);
|
||||
}
|
||||
mFirstVisibleItem = firstVisibleItem;
|
||||
}
|
||||
|
||||
private void addUnreadCountsToRemove(final long accountId, final long id) {
|
||||
if (mUnreadCountsToRemove.indexOfKey(accountId) < 0) {
|
||||
final Set<Long> counts = new HashSet<>();
|
||||
counts.add(id);
|
||||
mUnreadCountsToRemove.put(accountId, counts);
|
||||
} else {
|
||||
final Set<Long> counts = mUnreadCountsToRemove.get(accountId);
|
||||
counts.add(id);
|
||||
}
|
||||
}
|
||||
|
||||
private void openMenu(final View view, final ParcelableStatus status, final int position) {
|
||||
mSelectedStatus = status;
|
||||
mSelectedPosition = position;
|
||||
final FragmentActivity activity = getActivity();
|
||||
if (activity == null || activity.isFinishing() || view == null || status == null) return;
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
if (twitter != null) {
|
||||
TwitterWrapper.removeUnreadCounts(getActivity(), getTabPosition(), status.account_id, status.id);
|
||||
}
|
||||
final StatusMenuDialogFragment df = new StatusMenuDialogFragment();
|
||||
final Bundle args = new Bundle();
|
||||
args.putParcelable(EXTRA_STATUS, status);
|
||||
df.setArguments(args);
|
||||
df.show(getChildFragmentManager(), "status_menu");
|
||||
}
|
||||
|
||||
private void removeUnreadCounts() {
|
||||
if (mRemoveUnreadCountsTask != null && mRemoveUnreadCountsTask.getStatus() == TwidereAsyncTask.Status.RUNNING)
|
||||
return;
|
||||
mRemoveUnreadCountsTask = new RemoveUnreadCountsTask<Data>(mReadPositions, this);
|
||||
mRemoveUnreadCountsTask.executeTask();
|
||||
}
|
||||
|
||||
static class RemoveUnreadCountsTask<T> extends TwidereAsyncTask<Void, Void, Void> {
|
||||
private final List<Integer> read_positions;
|
||||
private final IStatusesListAdapter<T> adapter;
|
||||
private final BaseStatusesListFragment<T> fragment;
|
||||
|
||||
RemoveUnreadCountsTask(final List<Integer> read_positions, final BaseStatusesListFragment<T> fragment) {
|
||||
this.read_positions = read_positions;
|
||||
this.fragment = fragment;
|
||||
this.adapter = fragment.getListAdapter();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(final Void... params) {
|
||||
for (final int pos : read_positions) {
|
||||
final long id = adapter.getStatusId(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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -32,6 +32,7 @@ import org.mariotaku.twidere.model.ParcelableStatus;
|
|||
import org.mariotaku.twidere.util.message.FavoriteCreatedEvent;
|
||||
import org.mariotaku.twidere.util.message.FavoriteDestroyedEvent;
|
||||
import org.mariotaku.twidere.util.message.StatusDestroyedEvent;
|
||||
import org.mariotaku.twidere.util.message.StatusListChangedEvent;
|
||||
import org.mariotaku.twidere.util.message.StatusRetweetedEvent;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
@ -43,11 +44,6 @@ import java.util.Set;
|
|||
*/
|
||||
public abstract class ParcelableStatusesFragment extends AbsStatusesFragment<List<ParcelableStatus>> {
|
||||
|
||||
private final StatusesBusCallback mStatusesBusCallback;
|
||||
|
||||
protected ParcelableStatusesFragment() {
|
||||
mStatusesBusCallback = new StatusesBusCallback(this);
|
||||
}
|
||||
|
||||
public final void deleteStatus(final long statusId) {
|
||||
final List<ParcelableStatus> data = getAdapterData();
|
||||
|
@ -98,8 +94,8 @@ public abstract class ParcelableStatusesFragment extends AbsStatusesFragment<Lis
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Object getMessageBusCallback() {
|
||||
return mStatusesBusCallback;
|
||||
protected Object createMessageBusCallback() {
|
||||
return new ParcelableStatusesBusCallback();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -155,36 +151,6 @@ public abstract class ParcelableStatusesFragment extends AbsStatusesFragment<Lis
|
|||
}
|
||||
}
|
||||
|
||||
protected static class StatusesBusCallback {
|
||||
|
||||
private final ParcelableStatusesFragment fragment;
|
||||
|
||||
StatusesBusCallback(ParcelableStatusesFragment fragment) {
|
||||
this.fragment = fragment;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void notifyFavoriteCreated(FavoriteCreatedEvent event) {
|
||||
fragment.updateFavoritedStatus(event.status);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void notifyStatusRetweeted(StatusRetweetedEvent event) {
|
||||
fragment.updateRetweetedStatuses(event.status);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void notifyFavoriteDestroyed(FavoriteDestroyedEvent event) {
|
||||
fragment.updateFavoritedStatus(event.status);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void notifyStatusDestroyed(StatusDestroyedEvent event) {
|
||||
fragment.deleteStatus(event.status.id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void updateRetweetedStatuses(ParcelableStatus status) {
|
||||
final List<ParcelableStatus> data = getAdapterData();
|
||||
if (status == null || status.retweet_id <= 0 || data == null) return;
|
||||
|
@ -197,4 +163,33 @@ public abstract class ParcelableStatusesFragment extends AbsStatusesFragment<Lis
|
|||
setAdapterData(data);
|
||||
}
|
||||
|
||||
protected class ParcelableStatusesBusCallback {
|
||||
|
||||
@Subscribe
|
||||
public void notifyFavoriteCreated(FavoriteCreatedEvent event) {
|
||||
updateFavoritedStatus(event.status);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void notifyFavoriteDestroyed(FavoriteDestroyedEvent event) {
|
||||
updateFavoritedStatus(event.status);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void notifyStatusDestroyed(StatusDestroyedEvent event) {
|
||||
deleteStatus(event.status.id);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void notifyStatusListChanged(StatusListChangedEvent event) {
|
||||
getAdapter().notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void notifyStatusRetweeted(StatusRetweetedEvent event) {
|
||||
updateRetweetedStatuses(event.status);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,222 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment.support;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.Loader;
|
||||
|
||||
import org.mariotaku.twidere.adapter.ParcelableStatusesListAdapter;
|
||||
import org.mariotaku.twidere.adapter.iface.IStatusesListAdapter;
|
||||
import org.mariotaku.twidere.loader.support.DummyParcelableStatusesLoader;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.util.ArrayUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.mariotaku.twidere.util.Utils.encodeQueryParams;
|
||||
|
||||
public abstract class ParcelableStatusesListFragment extends BaseStatusesListFragment<List<ParcelableStatus>> {
|
||||
|
||||
protected SharedPreferences mPreferences;
|
||||
|
||||
private boolean mStatusesRestored;
|
||||
private boolean mIsFirstCreated;
|
||||
|
||||
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();
|
||||
switch (action) {
|
||||
// case BROADCAST_STATUS_RETWEETED: {
|
||||
// final long status_id = intent.getLongExtra(EXTRA_STATUS_ID, -1);
|
||||
// final boolean retweeted = intent.getBooleanExtra(EXTRA_RETWEETED, false);
|
||||
// if (status_id > 0 && !retweeted) {
|
||||
// deleteStatus(status_id);
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
case BROADCAST_MULTI_MUTESTATE_CHANGED: {
|
||||
final Bundle args = getArguments();
|
||||
final long account_id = args != null ? args.getLong(EXTRA_ACCOUNT_ID, -1) : -1;
|
||||
if (account_id <= 0) return;
|
||||
getStatuses(new long[]{account_id}, null, null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
public final void deleteStatus(final long status_id) {
|
||||
final List<ParcelableStatus> data = getData();
|
||||
if (status_id <= 0 || data == null) return;
|
||||
final ArrayList<ParcelableStatus> data_to_remove = new ArrayList<ParcelableStatus>();
|
||||
for (final ParcelableStatus status : data) {
|
||||
if (status.id == status_id || status.retweet_id > 0 && status.retweet_id == status_id) {
|
||||
data_to_remove.add(status);
|
||||
}
|
||||
}
|
||||
data.removeAll(data_to_remove);
|
||||
getListAdapter().setData(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getStatuses(final long[] accountIds, final long[] maxIds, final long[] sinceIds) {
|
||||
mStatusesRestored = true;
|
||||
final long maxId = maxIds != null && maxIds.length == 1 ? maxIds[0] : -1;
|
||||
final long sinceId = sinceIds != null && sinceIds.length == 1 ? sinceIds[0] : -1;
|
||||
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 onActivityCreated(final Bundle savedInstanceState) {
|
||||
mStatusesRestored = false;
|
||||
if (savedInstanceState != null) {
|
||||
final List<ParcelableStatus> saved = savedInstanceState.getParcelableArrayList(EXTRA_DATA);
|
||||
if (saved != null) {
|
||||
setData(saved);
|
||||
}
|
||||
}
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
mPreferences = getSharedPreferences();
|
||||
mIsFirstCreated = savedInstanceState == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Loader<List<ParcelableStatus>> onCreateLoader(final int id, final Bundle args) {
|
||||
setProgressBarIndeterminateVisibility(true);
|
||||
final List<ParcelableStatus> data = getData();
|
||||
if (isInstanceStateSaved() && data != null && !mStatusesRestored)
|
||||
return new DummyParcelableStatusesLoader(getActivity(), data);
|
||||
final Loader<List<ParcelableStatus>> loader = newLoaderInstance(getActivity(), args);
|
||||
return loader != null ? loader : new DummyParcelableStatusesLoader(getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(final Loader<List<ParcelableStatus>> loader, final List<ParcelableStatus> data) {
|
||||
super.onLoadFinished(loader, data);
|
||||
if (mIsFirstCreated && mPreferences.getBoolean(KEY_REFRESH_ON_START, false)) {
|
||||
onRefreshFromStart();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRefreshFromStart() {
|
||||
if (isRefreshing()) return;
|
||||
final IStatusesListAdapter<List<ParcelableStatus>> adapter = getListAdapter();
|
||||
final int count = adapter.getCount();
|
||||
final ParcelableStatus status = count > 0 ? adapter.getStatus(0) : null;
|
||||
if (status != null) {
|
||||
getStatuses(new long[]{status.account_id}, null, new long[]{status.id});
|
||||
} else {
|
||||
getStatuses(null, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(final Bundle outState) {
|
||||
final List<ParcelableStatus> data = getData();
|
||||
if (data != null) {
|
||||
outState.putParcelableArrayList(EXTRA_DATA, new ArrayList<>(data));
|
||||
}
|
||||
super.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final long[] getNewestStatusIds() {
|
||||
final IStatusesListAdapter<List<ParcelableStatus>> adapter = getListAdapter();
|
||||
final long last_id = adapter.getCount() > 0 ? adapter.getStatus(0).id : -1;
|
||||
return last_id > 0 ? new long[]{last_id} : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final long[] getOldestStatusIds() {
|
||||
final IStatusesListAdapter<List<ParcelableStatus>> adapter = getListAdapter();
|
||||
final ParcelableStatus status = adapter.getLastStatus();
|
||||
final long last_id = status != null ? status.id : -1;
|
||||
return last_id > 0 ? new long[]{last_id} : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final String getPositionKey() {
|
||||
final Object[] args = getSavedStatusesFileArgs();
|
||||
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[] getSavedStatusesFileArgs();
|
||||
|
||||
@Override
|
||||
protected void loadMoreStatuses() {
|
||||
if (isRefreshing()) return;
|
||||
final IStatusesListAdapter<List<ParcelableStatus>> adapter = getListAdapter();
|
||||
final ParcelableStatus status = adapter.getLastStatus();
|
||||
if (status != null) {
|
||||
getStatuses(new long[]{status.account_id}, new long[]{status.id}, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ParcelableStatusesListAdapter newAdapterInstance(final boolean compact) {
|
||||
return new ParcelableStatusesListAdapter(getActivity(), compact);
|
||||
}
|
||||
|
||||
protected abstract Loader<List<ParcelableStatus>> newLoaderInstance(Context context, Bundle args);
|
||||
|
||||
@Override
|
||||
protected void updateRefreshState() {
|
||||
if (getActivity() == null || !getUserVisibleHint() || !isVisible()) return;
|
||||
final LoaderManager lm = getLoaderManager();
|
||||
final boolean hasRunningLoaders = lm.hasRunningLoaders();
|
||||
if (!hasRunningLoaders) {
|
||||
setRefreshing(true);
|
||||
}
|
||||
setRefreshing(hasRunningLoaders);
|
||||
}
|
||||
|
||||
}
|
|
@ -72,6 +72,7 @@ public class RetweetQuoteDialogFragment extends BaseSupportDialogFragment implem
|
|||
final Context context = builder.getContext();
|
||||
final ImageLoaderWrapper loader = TwidereApplication.getInstance(context).getImageLoaderWrapper();
|
||||
final ImageLoadingHandler handler = new ImageLoadingHandler(R.id.media_preview_progress);
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
final LayoutInflater inflater = LayoutInflater.from(context);
|
||||
@SuppressLint("InflateParams") final View view = inflater.inflate(R.layout.dialog_scrollable_status, null);
|
||||
final StatusViewHolder holder = new StatusViewHolder(view.findViewById(R.id.item_content));
|
||||
|
@ -85,7 +86,7 @@ public class RetweetQuoteDialogFragment extends BaseSupportDialogFragment implem
|
|||
builder.setNegativeButton(android.R.string.cancel, null);
|
||||
|
||||
|
||||
holder.displayStatus(context, loader, handler, getStatus());
|
||||
holder.displayStatus(context, loader, handler, twitter, getStatus());
|
||||
view.findViewById(R.id.item_menu).setVisibility(View.GONE);
|
||||
view.findViewById(R.id.action_buttons).setVisibility(View.GONE);
|
||||
view.findViewById(R.id.reply_retweet_status).setVisibility(View.GONE);
|
||||
|
|
|
@ -33,8 +33,6 @@ import android.view.MenuItem;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.astuetz.PagerSlidingTabStrip;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.activity.support.LinkHandlerActivity;
|
||||
import org.mariotaku.twidere.adapter.support.SupportTabsAdapter;
|
||||
|
@ -43,6 +41,7 @@ import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface;
|
|||
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback;
|
||||
import org.mariotaku.twidere.provider.RecentSearchProvider;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
import org.mariotaku.twidere.view.TabPagerIndicator;
|
||||
|
||||
public class SearchFragment extends BaseSupportFragment implements RefreshScrollTopInterface,
|
||||
SupportFragmentCallback, SystemWindowsInsetsCallback {
|
||||
|
@ -50,7 +49,7 @@ public class SearchFragment extends BaseSupportFragment implements RefreshScroll
|
|||
private ViewPager mViewPager;
|
||||
|
||||
private SupportTabsAdapter mAdapter;
|
||||
private PagerSlidingTabStrip mPagerIndicator;
|
||||
private TabPagerIndicator mPagerIndicator;
|
||||
|
||||
private Fragment mCurrentVisibleFragment;
|
||||
|
||||
|
@ -141,7 +140,7 @@ public class SearchFragment extends BaseSupportFragment implements RefreshScroll
|
|||
public void onViewCreated(final View view, final Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
mViewPager = (ViewPager) view.findViewById(R.id.view_pager);
|
||||
mPagerIndicator = (PagerSlidingTabStrip) view.findViewById(R.id.view_pager_tabs);
|
||||
mPagerIndicator = (TabPagerIndicator) view.findViewById(R.id.view_pager_tabs);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -438,6 +438,11 @@ public class StatusFragment extends BaseSupportFragment
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncTwitterWrapper getTwitterWrapper() {
|
||||
return mFragment.getTwitterWrapper();
|
||||
}
|
||||
|
||||
public ParcelableStatus getStatus() {
|
||||
return mStatus;
|
||||
}
|
||||
|
|
|
@ -71,7 +71,6 @@ import android.widget.ImageView;
|
|||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.astuetz.PagerSlidingTabStrip;
|
||||
import com.squareup.otto.Bus;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
|
@ -113,6 +112,7 @@ import org.mariotaku.twidere.view.CircularImageView;
|
|||
import org.mariotaku.twidere.view.HeaderDrawerLayout;
|
||||
import org.mariotaku.twidere.view.HeaderDrawerLayout.DrawerCallback;
|
||||
import org.mariotaku.twidere.view.ProfileBannerImageView;
|
||||
import org.mariotaku.twidere.view.TabPagerIndicator;
|
||||
import org.mariotaku.twidere.view.TintedStatusFrameLayout;
|
||||
import org.mariotaku.twidere.view.iface.IColorLabelView;
|
||||
import org.mariotaku.twidere.view.iface.IExtendedView.OnSizeChangedListener;
|
||||
|
@ -180,7 +180,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
|||
private TintedStatusFrameLayout mTintedStatusContent;
|
||||
private HeaderDrawerLayout mHeaderDrawerLayout;
|
||||
private ViewPager mViewPager;
|
||||
private PagerSlidingTabStrip mPagerIndicator;
|
||||
private TabPagerIndicator mPagerIndicator;
|
||||
private CardView mCardView;
|
||||
private View mUuckyFooter;
|
||||
private View mProfileBannerContainer;
|
||||
|
@ -617,6 +617,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
|||
mViewPager.setOffscreenPageLimit(3);
|
||||
mViewPager.setAdapter(mPagerAdapter);
|
||||
mPagerIndicator.setViewPager(mViewPager);
|
||||
mPagerIndicator.setTabDisplayOption(TabPagerIndicator.LABEL);
|
||||
|
||||
mFollowButton.setOnClickListener(this);
|
||||
mProfileImageView.setOnClickListener(this);
|
||||
|
@ -853,7 +854,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
|||
mURLContainer = headerView.findViewById(R.id.url_container);
|
||||
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);
|
||||
mPagerIndicator = (TabPagerIndicator) contentView.findViewById(R.id.view_pager_tabs);
|
||||
mFollowButton = (Button) headerView.findViewById(R.id.follow);
|
||||
mFollowProgress = (ProgressBar) headerView.findViewById(R.id.follow_progress);
|
||||
mUuckyFooter = headerView.findViewById(R.id.uucky_footer);
|
||||
|
@ -1143,7 +1144,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
|||
}
|
||||
mActionBarBackground.setColor(color);
|
||||
mTintedStatusContent.setColor(color, ThemeUtils.getThemeAlpha(getActivity()));
|
||||
mPagerIndicator.setIndicatorColor(color);
|
||||
mPagerIndicator.setStripColor(color);
|
||||
}
|
||||
|
||||
private void setupUserPages() {
|
||||
|
@ -1161,12 +1162,11 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
|||
tabArgs.putLong(EXTRA_USER_ID, args.getLong(EXTRA_USER_ID, -1));
|
||||
tabArgs.putString(EXTRA_SCREEN_NAME, args.getString(EXTRA_SCREEN_NAME));
|
||||
}
|
||||
mPagerAdapter.addTab(UserTimelineFragment.class, tabArgs, getString(R.string.statuses), null, 0);
|
||||
mPagerAdapter.addTab(UserTimelineFragment.class, tabArgs, getString(R.string.statuses), R.drawable.ic_action_quote, 0);
|
||||
if (Utils.isOfficialKeyAccount(context, accountId)) {
|
||||
mPagerAdapter.addTab(UserMediaTimelineFragment.class, tabArgs, getString(R.string.media), null, 1);
|
||||
mPagerAdapter.addTab(UserMediaTimelineFragment.class, tabArgs, getString(R.string.media), R.drawable.ic_action_gallery, 1);
|
||||
}
|
||||
mPagerAdapter.addTab(UserFavoritesFragment.class, tabArgs, getString(R.string.favorites), null, 2);
|
||||
mPagerIndicator.notifyDataSetChanged();
|
||||
mPagerAdapter.addTab(UserFavoritesFragment.class, tabArgs, getString(R.string.favorites), R.drawable.ic_action_star, 2);
|
||||
}
|
||||
|
||||
private boolean shouldUseNativeMenu() {
|
||||
|
|
|
@ -55,8 +55,6 @@ import android.widget.EditText;
|
|||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.astuetz.PagerSlidingTabStrip;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.activity.support.UserListSelectorActivity;
|
||||
import org.mariotaku.twidere.adapter.support.SupportTabsAdapter;
|
||||
|
@ -74,6 +72,7 @@ import org.mariotaku.twidere.util.TwidereLinkify;
|
|||
import org.mariotaku.twidere.view.ColorLabelRelativeLayout;
|
||||
import org.mariotaku.twidere.view.HeaderDrawerLayout;
|
||||
import org.mariotaku.twidere.view.HeaderDrawerLayout.DrawerCallback;
|
||||
import org.mariotaku.twidere.view.TabPagerIndicator;
|
||||
|
||||
import twitter4j.Twitter;
|
||||
import twitter4j.TwitterException;
|
||||
|
@ -102,7 +101,7 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList
|
|||
private Button mRetryButton;
|
||||
private HeaderDrawerLayout mHeaderDrawerLayout;
|
||||
private ViewPager mViewPager;
|
||||
private PagerSlidingTabStrip mPagerIndicator;
|
||||
private TabPagerIndicator mPagerIndicator;
|
||||
private CardView mCardView;
|
||||
|
||||
private SupportTabsAdapter mPagerAdapter;
|
||||
|
@ -484,7 +483,7 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList
|
|||
mRetryButton = (Button) mErrorRetryContainer.findViewById(R.id.retry);
|
||||
mErrorMessageView = (TextView) mErrorRetryContainer.findViewById(R.id.error_message);
|
||||
mViewPager = (ViewPager) contentView.findViewById(R.id.view_pager);
|
||||
mPagerIndicator = (PagerSlidingTabStrip) contentView.findViewById(R.id.view_pager_tabs);
|
||||
mPagerIndicator = (TabPagerIndicator) contentView.findViewById(R.id.view_pager_tabs);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -28,13 +28,12 @@ import android.view.LayoutInflater;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.astuetz.PagerSlidingTabStrip;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.support.SupportTabsAdapter;
|
||||
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback;
|
||||
import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface;
|
||||
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback;
|
||||
import org.mariotaku.twidere.view.TabPagerIndicator;
|
||||
|
||||
public class UserListsFragment extends BaseSupportFragment implements RefreshScrollTopInterface,
|
||||
SupportFragmentCallback, SystemWindowsInsetsCallback {
|
||||
|
@ -42,7 +41,7 @@ public class UserListsFragment extends BaseSupportFragment implements RefreshScr
|
|||
private ViewPager mViewPager;
|
||||
|
||||
private SupportTabsAdapter mAdapter;
|
||||
private PagerSlidingTabStrip mPagerIndicator;
|
||||
private TabPagerIndicator mPagerIndicator;
|
||||
|
||||
private Fragment mCurrentVisibleFragment;
|
||||
|
||||
|
@ -90,7 +89,7 @@ public class UserListsFragment extends BaseSupportFragment implements RefreshScr
|
|||
public void onViewCreated(final View view, final Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
mViewPager = (ViewPager) view.findViewById(R.id.view_pager);
|
||||
mPagerIndicator = (PagerSlidingTabStrip) view.findViewById(R.id.view_pager_tabs);
|
||||
mPagerIndicator = (TabPagerIndicator) view.findViewById(R.id.view_pager_tabs);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,60 +19,61 @@
|
|||
|
||||
package org.mariotaku.twidere.model;
|
||||
|
||||
import static org.mariotaku.twidere.util.CompareUtils.bundleEquals;
|
||||
import static org.mariotaku.twidere.util.CompareUtils.classEquals;
|
||||
import static org.mariotaku.twidere.util.CompareUtils.objectEquals;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.Fragment;
|
||||
|
||||
import org.mariotaku.twidere.TwidereConstants;
|
||||
|
||||
import static org.mariotaku.twidere.util.CompareUtils.bundleEquals;
|
||||
import static org.mariotaku.twidere.util.CompareUtils.classEquals;
|
||||
import static org.mariotaku.twidere.util.CompareUtils.objectEquals;
|
||||
|
||||
public class SupportTabSpec implements Comparable<SupportTabSpec>, TwidereConstants {
|
||||
|
||||
public final String name;
|
||||
public final Object icon;
|
||||
public final String type;
|
||||
public final Class<? extends Fragment> cls;
|
||||
public final Bundle args;
|
||||
public final int position;
|
||||
public final String name;
|
||||
public final Object icon;
|
||||
public final String type;
|
||||
public final Class<? extends Fragment> cls;
|
||||
public final Bundle args;
|
||||
public final int position;
|
||||
|
||||
public SupportTabSpec(final String name, final Object icon, final Class<? extends Fragment> cls, final Bundle args,
|
||||
final int position) {
|
||||
this(name, icon, null, cls, args, position);
|
||||
}
|
||||
public SupportTabSpec(final String name, final Object icon, final Class<? extends Fragment> cls, final Bundle args,
|
||||
final int position) {
|
||||
this(name, icon, null, cls, args, position);
|
||||
}
|
||||
|
||||
public SupportTabSpec(final String name, final Object icon, final String type, final Class<? extends Fragment> cls,
|
||||
final Bundle args, final int position) {
|
||||
if (cls == null) throw new IllegalArgumentException("Fragment cannot be null!");
|
||||
if (name == null && icon == null)
|
||||
throw new IllegalArgumentException("You must specify a name or icon for this tab!");
|
||||
this.name = name;
|
||||
this.icon = icon;
|
||||
this.type = type;
|
||||
this.cls = cls;
|
||||
this.args = args;
|
||||
this.position = position;
|
||||
public SupportTabSpec(final String name, final Object icon, final String type, final Class<? extends Fragment> cls,
|
||||
final Bundle args, final int position) {
|
||||
if (cls == null) throw new IllegalArgumentException("Fragment cannot be null!");
|
||||
if (name == null && icon == null)
|
||||
throw new IllegalArgumentException("You must specify a name or icon for this tab!");
|
||||
this.name = name;
|
||||
this.icon = icon;
|
||||
this.type = type;
|
||||
this.cls = cls;
|
||||
this.args = args;
|
||||
this.position = position;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(final SupportTabSpec another) {
|
||||
return position - another.position;
|
||||
}
|
||||
@Override
|
||||
public int compareTo(@NonNull final SupportTabSpec another) {
|
||||
return position - another.position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (!(o instanceof SupportTabSpec)) return false;
|
||||
final SupportTabSpec spec = (SupportTabSpec) o;
|
||||
return objectEquals(name, spec.name) && objectEquals(icon, spec.icon) && classEquals(cls, spec.cls)
|
||||
&& bundleEquals(args, spec.args) && position == spec.position;
|
||||
}
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (!(o instanceof SupportTabSpec)) return false;
|
||||
final SupportTabSpec spec = (SupportTabSpec) o;
|
||||
return objectEquals(name, spec.name) && objectEquals(icon, spec.icon) && classEquals(cls, spec.cls)
|
||||
&& bundleEquals(args, spec.args) && position == spec.position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SupportTabSpec{name=" + name + ", icon=" + icon + ", type=" + type + ", cls=" + cls + ", args=" + args
|
||||
+ ", position=" + position + "}";
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SupportTabSpec{name=" + name + ", icon=" + icon + ", type=" + type + ", cls=" + cls + ", args=" + args
|
||||
+ ", position=" + position + "}";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,11 +19,6 @@
|
|||
|
||||
package org.mariotaku.twidere.preference;
|
||||
|
||||
import static org.mariotaku.twidere.util.HtmlEscapeHelper.toPlainText;
|
||||
import static org.mariotaku.twidere.util.Utils.getDefaultTextSize;
|
||||
import static org.mariotaku.twidere.util.Utils.getLinkHighlightOptionInt;
|
||||
import static org.mariotaku.twidere.util.Utils.getSampleDisplayName;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||
|
@ -38,106 +33,108 @@ import org.mariotaku.twidere.Constants;
|
|||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.util.ThemeUtils;
|
||||
import org.mariotaku.twidere.util.TwidereLinkify;
|
||||
import org.mariotaku.twidere.view.CardItemLinearLayout;
|
||||
import org.mariotaku.twidere.view.ForegroundImageView;
|
||||
import org.mariotaku.twidere.view.holder.StatusListViewHolder;
|
||||
|
||||
import static org.mariotaku.twidere.util.HtmlEscapeHelper.toPlainText;
|
||||
import static org.mariotaku.twidere.util.Utils.getDefaultTextSize;
|
||||
import static org.mariotaku.twidere.util.Utils.getLinkHighlightOptionInt;
|
||||
import static org.mariotaku.twidere.util.Utils.getSampleDisplayName;
|
||||
|
||||
public class CardPreviewPreference extends Preference implements Constants, OnSharedPreferenceChangeListener {
|
||||
|
||||
private final LayoutInflater mInflater;
|
||||
private final SharedPreferences mPreferences;
|
||||
private final TwidereLinkify mLinkify;
|
||||
private StatusListViewHolder mHolder;
|
||||
private boolean mCompactModeChanged;
|
||||
private final LayoutInflater mInflater;
|
||||
private final SharedPreferences mPreferences;
|
||||
private final TwidereLinkify mLinkify;
|
||||
private StatusListViewHolder mHolder;
|
||||
private boolean mCompactModeChanged;
|
||||
|
||||
public CardPreviewPreference(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
public CardPreviewPreference(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public CardPreviewPreference(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
public CardPreviewPreference(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public CardPreviewPreference(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
mInflater = LayoutInflater.from(context);
|
||||
mLinkify = new TwidereLinkify(null);
|
||||
mLinkify.setLinkTextColor(ThemeUtils.getUserLinkTextColor(context));
|
||||
mPreferences = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
||||
mPreferences.registerOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
public CardPreviewPreference(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
mInflater = LayoutInflater.from(context);
|
||||
mLinkify = new TwidereLinkify(null);
|
||||
mLinkify.setLinkTextColor(ThemeUtils.getUserLinkTextColor(context));
|
||||
mPreferences = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
|
||||
mPreferences.registerOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(final View convertView, final ViewGroup parent) {
|
||||
if (mCompactModeChanged) return super.getView(null, parent);
|
||||
return super.getView(convertView, parent);
|
||||
}
|
||||
@Override
|
||||
public View getView(final View convertView, final ViewGroup parent) {
|
||||
if (mCompactModeChanged) return super.getView(null, parent);
|
||||
return super.getView(convertView, parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(final SharedPreferences preferences, final String key) {
|
||||
if (mHolder == null) return;
|
||||
if (KEY_COMPACT_CARDS.equals(key)) {
|
||||
mCompactModeChanged = true;
|
||||
}
|
||||
notifyChanged();
|
||||
}
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(final SharedPreferences preferences, final String key) {
|
||||
if (mHolder == null) return;
|
||||
if (KEY_COMPACT_CARDS.equals(key)) {
|
||||
mCompactModeChanged = true;
|
||||
}
|
||||
notifyChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBindView(final View view) {
|
||||
if (mPreferences == null) return;
|
||||
mCompactModeChanged = false;
|
||||
final Context context = getContext();
|
||||
final int highlightOption = getLinkHighlightOptionInt(context);
|
||||
final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST, true);
|
||||
final boolean display_image_preview = mPreferences.getBoolean(KEY_DISPLAY_IMAGE_PREVIEW, false);
|
||||
final boolean display_profile_image = mPreferences.getBoolean(KEY_DISPLAY_PROFILE_IMAGE, true);
|
||||
final boolean nickname_only = mPreferences.getBoolean(KEY_NICKNAME_ONLY, false);
|
||||
mHolder = new StatusListViewHolder(view);
|
||||
mLinkify.setHighlightOption(highlightOption);
|
||||
mHolder.setDisplayNameFirst(nameFirst);
|
||||
mHolder.setNicknameOnly(nickname_only);
|
||||
mHolder.setShowAsGap(false);
|
||||
mHolder.setIsMyStatus(false);
|
||||
mHolder.setTextSize(mPreferences.getInt(KEY_TEXT_SIZE, getDefaultTextSize(context)));
|
||||
mHolder.image_preview_container.setVisibility(display_image_preview ? View.VISIBLE : View.GONE);
|
||||
mHolder.profile_image.setVisibility(display_profile_image ? View.VISIBLE : View.GONE);
|
||||
mHolder.image_preview_progress.setVisibility(View.GONE);
|
||||
@Override
|
||||
protected void onBindView(final View view) {
|
||||
if (mPreferences == null) return;
|
||||
mCompactModeChanged = false;
|
||||
final Context context = getContext();
|
||||
final int highlightOption = getLinkHighlightOptionInt(context);
|
||||
final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST, true);
|
||||
final boolean display_image_preview = mPreferences.getBoolean(KEY_DISPLAY_IMAGE_PREVIEW, false);
|
||||
final boolean display_profile_image = mPreferences.getBoolean(KEY_DISPLAY_PROFILE_IMAGE, true);
|
||||
final boolean nickname_only = mPreferences.getBoolean(KEY_NICKNAME_ONLY, false);
|
||||
mHolder = new StatusListViewHolder(view);
|
||||
mLinkify.setHighlightOption(highlightOption);
|
||||
mHolder.setDisplayNameFirst(nameFirst);
|
||||
mHolder.setNicknameOnly(nickname_only);
|
||||
mHolder.setShowAsGap(false);
|
||||
mHolder.setIsMyStatus(false);
|
||||
mHolder.setTextSize(mPreferences.getInt(KEY_TEXT_SIZE, getDefaultTextSize(context)));
|
||||
mHolder.image_preview_container.setVisibility(display_image_preview ? View.VISIBLE : View.GONE);
|
||||
mHolder.profile_image.setVisibility(display_profile_image ? View.VISIBLE : View.GONE);
|
||||
mHolder.image_preview_progress.setVisibility(View.GONE);
|
||||
|
||||
if (mHolder.profile_image instanceof ForegroundImageView) {
|
||||
((ForegroundImageView) mHolder.profile_image).setForeground(null);
|
||||
}
|
||||
if (mHolder.image_preview instanceof ForegroundImageView) {
|
||||
((ForegroundImageView) mHolder.image_preview).setForeground(null);
|
||||
}
|
||||
if (mHolder.content instanceof CardItemLinearLayout) {
|
||||
((CardItemLinearLayout) mHolder.content).setItemSelector(null);
|
||||
}
|
||||
mHolder.profile_image.setImageResource(R.drawable.ic_launcher);
|
||||
mHolder.image_preview.setImageResource(R.drawable.twidere_feature_graphic);
|
||||
mHolder.name.setText(nickname_only ? TWIDERE_PREVIEW_NICKNAME : context.getString(R.string.name_with_nickname,
|
||||
TWIDERE_PREVIEW_NAME, TWIDERE_PREVIEW_NICKNAME));
|
||||
mHolder.screen_name.setText("@" + TWIDERE_PREVIEW_SCREEN_NAME);
|
||||
if (highlightOption != VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE) {
|
||||
mHolder.text.setText(Html.fromHtml(TWIDERE_PREVIEW_TEXT_HTML));
|
||||
mLinkify.applyAllLinks(mHolder.text, 0, false);
|
||||
mLinkify.applyUserProfileLinkNoHighlight(mHolder.name, 0, 0, TWIDERE_PREVIEW_SCREEN_NAME);
|
||||
mLinkify.applyUserProfileLinkNoHighlight(mHolder.screen_name, 0, 0, TWIDERE_PREVIEW_SCREEN_NAME);
|
||||
} else {
|
||||
mHolder.text.setText(toPlainText(TWIDERE_PREVIEW_TEXT_HTML));
|
||||
}
|
||||
final String display_name = getSampleDisplayName(context, nameFirst, nickname_only);
|
||||
mHolder.reply_retweet_status.setText(context.getString(R.string.retweeted_by_name, display_name));
|
||||
mHolder.reply_retweet_status.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_indicator_retweet, 0, 0, 0);
|
||||
mHolder.time.setTime(System.currentTimeMillis() - 360000);
|
||||
mHolder.time.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_indicator_media, 0);
|
||||
super.onBindView(view);
|
||||
}
|
||||
if (mHolder.profile_image instanceof ForegroundImageView) {
|
||||
((ForegroundImageView) mHolder.profile_image).setForeground(null);
|
||||
}
|
||||
if (mHolder.image_preview instanceof ForegroundImageView) {
|
||||
((ForegroundImageView) mHolder.image_preview).setForeground(null);
|
||||
}
|
||||
mHolder.content.setItemSelector(null);
|
||||
mHolder.profile_image.setImageResource(R.drawable.ic_launcher);
|
||||
mHolder.image_preview.setImageResource(R.drawable.twidere_feature_graphic);
|
||||
mHolder.name.setText(nickname_only ? TWIDERE_PREVIEW_NICKNAME : context.getString(R.string.name_with_nickname,
|
||||
TWIDERE_PREVIEW_NAME, TWIDERE_PREVIEW_NICKNAME));
|
||||
mHolder.screen_name.setText("@" + TWIDERE_PREVIEW_SCREEN_NAME);
|
||||
if (highlightOption != VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE) {
|
||||
mHolder.text.setText(Html.fromHtml(TWIDERE_PREVIEW_TEXT_HTML));
|
||||
mLinkify.applyAllLinks(mHolder.text, 0, false);
|
||||
mLinkify.applyUserProfileLinkNoHighlight(mHolder.name, 0, 0, TWIDERE_PREVIEW_SCREEN_NAME);
|
||||
mLinkify.applyUserProfileLinkNoHighlight(mHolder.screen_name, 0, 0, TWIDERE_PREVIEW_SCREEN_NAME);
|
||||
} else {
|
||||
mHolder.text.setText(toPlainText(TWIDERE_PREVIEW_TEXT_HTML));
|
||||
}
|
||||
final String display_name = getSampleDisplayName(context, nameFirst, nickname_only);
|
||||
mHolder.reply_retweet_status.setText(context.getString(R.string.retweeted_by_name, display_name));
|
||||
mHolder.reply_retweet_status.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_indicator_retweet, 0, 0, 0);
|
||||
mHolder.time.setTime(System.currentTimeMillis() - 360000);
|
||||
mHolder.time.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_indicator_media, 0);
|
||||
super.onBindView(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected View onCreateView(final ViewGroup parent) {
|
||||
if (mPreferences != null && mPreferences.getBoolean(KEY_COMPACT_CARDS, false))
|
||||
return mInflater.inflate(R.layout.list_item_status_compact_deprecated, parent, false);
|
||||
return mInflater.inflate(R.layout.list_item_status_deprecated, parent, false);
|
||||
}
|
||||
@Override
|
||||
protected View onCreateView(final ViewGroup parent) {
|
||||
if (mPreferences != null && mPreferences.getBoolean(KEY_COMPACT_CARDS, false))
|
||||
return mInflater.inflate(R.layout.list_item_status_compact_deprecated, parent, false);
|
||||
return mInflater.inflate(R.layout.list_item_status_deprecated, parent, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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.service;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.job.JobParameters;
|
||||
import android.app.job.JobService;
|
||||
import android.os.Build;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/12/12.
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
public class BackgroundJobService extends JobService {
|
||||
@Override
|
||||
public boolean onStartJob(JobParameters params) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onStopJob(JobParameters params) {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -59,11 +59,13 @@ import org.mariotaku.twidere.service.BackgroundOperationService;
|
|||
import org.mariotaku.twidere.task.CacheUsersStatusesTask;
|
||||
import org.mariotaku.twidere.task.ManagedAsyncTask;
|
||||
import org.mariotaku.twidere.task.TwidereAsyncTask;
|
||||
import org.mariotaku.twidere.util.collection.LongSparseMap;
|
||||
import org.mariotaku.twidere.util.message.FavoriteCreatedEvent;
|
||||
import org.mariotaku.twidere.util.message.FavoriteDestroyedEvent;
|
||||
import org.mariotaku.twidere.util.message.FriendshipUpdatedEvent;
|
||||
import org.mariotaku.twidere.util.message.ProfileUpdatedEvent;
|
||||
import org.mariotaku.twidere.util.message.StatusDestroyedEvent;
|
||||
import org.mariotaku.twidere.util.message.StatusListChangedEvent;
|
||||
import org.mariotaku.twidere.util.message.StatusRetweetedEvent;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
|
@ -116,6 +118,9 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
|||
private int mGetReceivedDirectMessagesTaskId, mGetSentDirectMessagesTaskId;
|
||||
private int mGetLocalTrendsTaskId;
|
||||
|
||||
private LongSparseMap<Long> mCreatingFavoriteIds = new LongSparseMap<>();
|
||||
private LongSparseMap<Long> mDestroyingFavoriteIds = new LongSparseMap<>();
|
||||
|
||||
public AsyncTwitterWrapper(final Context context) {
|
||||
mContext = context;
|
||||
final TwidereApplication app = TwidereApplication.getInstance(context);
|
||||
|
@ -135,6 +140,15 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
|||
return mAsyncTaskManager.add(task, true);
|
||||
}
|
||||
|
||||
public boolean isCreatingFavorite(final long accountId, final long statusId) {
|
||||
return mCreatingFavoriteIds.has(accountId, statusId);
|
||||
}
|
||||
|
||||
|
||||
public boolean isDestroyingFavorite(final long accountId, final long statusId) {
|
||||
return mDestroyingFavoriteIds.has(accountId, statusId);
|
||||
}
|
||||
|
||||
public void clearNotificationAsync(final int notificationType) {
|
||||
clearNotificationAsync(notificationType, 0);
|
||||
}
|
||||
|
@ -849,8 +863,17 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
super.onPreExecute();
|
||||
mCreatingFavoriteIds.put(account_id, status_id);
|
||||
final Bus bus = TwidereApplication.getInstance(mContext).getMessageBus();
|
||||
bus.post(new StatusListChangedEvent());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(final SingleResponse<ParcelableStatus> result) {
|
||||
mCreatingFavoriteIds.remove(account_id, status_id);
|
||||
if (result.hasData()) {
|
||||
final Bus bus = TwidereApplication.getInstance(mContext).getMessageBus();
|
||||
bus.post(new FavoriteCreatedEvent(result.getData()));
|
||||
|
@ -1367,8 +1390,17 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
|||
return SingleResponse.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
super.onPreExecute();
|
||||
mDestroyingFavoriteIds.put(account_id, status_id);
|
||||
final Bus bus = TwidereApplication.getInstance(mContext).getMessageBus();
|
||||
bus.post(new StatusListChangedEvent());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(final SingleResponse<ParcelableStatus> result) {
|
||||
mDestroyingFavoriteIds.remove(account_id, status_id);
|
||||
if (result.hasData()) {
|
||||
final Bus bus = TwidereApplication.getInstance(mContext).getMessageBus();
|
||||
bus.post(new FavoriteDestroyedEvent(result.getData()));
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* 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.collection;
|
||||
|
||||
import android.support.v4.util.LongSparseArray;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/12/12.
|
||||
*/
|
||||
public class LongSparseMap<T> {
|
||||
|
||||
private final LongSparseArray<HashSet<T>> internalArray;
|
||||
|
||||
public LongSparseMap() {
|
||||
internalArray = new LongSparseArray<>();
|
||||
}
|
||||
|
||||
public boolean put(long key, T value) {
|
||||
final int idx = internalArray.indexOfKey(key);
|
||||
final HashSet<T> set;
|
||||
if (idx < 0) {
|
||||
set = new HashSet<>();
|
||||
internalArray.put(key, set);
|
||||
} else {
|
||||
set = internalArray.valueAt(idx);
|
||||
}
|
||||
return set.add(value);
|
||||
}
|
||||
|
||||
public boolean clear(long key) {
|
||||
final int idx = internalArray.indexOfKey(key);
|
||||
if (idx < 0) return false;
|
||||
internalArray.valueAt(idx).clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean remove(long key, T value) {
|
||||
final int idx = internalArray.indexOfKey(key);
|
||||
return idx >= 0 && internalArray.valueAt(idx).remove(value);
|
||||
}
|
||||
|
||||
public boolean has(long key, T value) {
|
||||
final int idx = internalArray.indexOfKey(key);
|
||||
return idx >= 0 && internalArray.valueAt(idx).contains(value);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* 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.message;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/12/12.
|
||||
*/
|
||||
public class StatusListChangedEvent {
|
||||
}
|
|
@ -1,7 +1,12 @@
|
|||
package org.mariotaku.twidere.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.annotation.IntDef;
|
||||
import android.support.v4.view.PagerAdapter;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.support.v4.view.ViewPager;
|
||||
|
@ -14,39 +19,56 @@ import android.view.LayoutInflater;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.view.iface.PagerIndicator;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/10/21.
|
||||
*/
|
||||
public class TabPagerIndicator extends RecyclerView implements PagerIndicator {
|
||||
|
||||
public static final int ICON = 0x1;
|
||||
public static final int LABEL = 0x2;
|
||||
public static final int BOTH = ICON | LABEL;
|
||||
|
||||
private final int mStripHeight;
|
||||
|
||||
private ViewPager mViewPager;
|
||||
|
||||
private final TabPagerIndicatorAdapter mIndicatorAdapter;
|
||||
private ViewPager mViewPager;
|
||||
private PagerAdapter mPagerProvider;
|
||||
|
||||
private OnPageChangeListener mPageChangeListener;
|
||||
private int mOption;
|
||||
private boolean mTabExpandEnabled;
|
||||
private int mHorizontalPadding, mVerticalPadding;
|
||||
|
||||
public TabPagerIndicator(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
final Resources res = getResources();
|
||||
mIndicatorAdapter = new TabPagerIndicatorAdapter(this);
|
||||
mStripHeight = getResources().getDimensionPixelSize(R.dimen.element_spacing_small);
|
||||
ViewCompat.setOverScrollMode(this, ViewCompat.OVER_SCROLL_NEVER);
|
||||
setHorizontalScrollBarEnabled(false);
|
||||
setVerticalScrollBarEnabled(false);
|
||||
setLayoutManager(new TabLayoutManager(this));
|
||||
mIndicatorAdapter = new TabPagerIndicatorAdapter(this);
|
||||
setItemContext(context);
|
||||
setAdapter(mIndicatorAdapter);
|
||||
mStripHeight = getResources().getDimensionPixelSize(R.dimen.element_spacing_small);
|
||||
setTabDisplayOption(ICON);
|
||||
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TabPagerIndicator);
|
||||
setTabExpandEnabled(a.getBoolean(R.styleable.TabPagerIndicator_tabExpandEnabled, false));
|
||||
setHorizontalPadding(a.getDimensionPixelSize(R.styleable.TabPagerIndicator_tabHorizontalPadding, 0));
|
||||
setVerticalPadding(a.getDimensionPixelSize(R.styleable.TabPagerIndicator_tabHorizontalPadding, 0));
|
||||
setStripColor(a.getColor(R.styleable.TabPagerIndicator_tabStripColor, 0));
|
||||
setIconColor(a.getColor(R.styleable.TabPagerIndicator_tabIconColor, 0));
|
||||
setTabDisplayOption(a.getInt(R.styleable.TabPagerIndicator_tabDisplayOption, ICON));
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
public void setStripColor(int color) {
|
||||
mIndicatorAdapter.setStripColor(color);
|
||||
}
|
||||
|
||||
public TabPagerIndicator(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
|
@ -56,11 +78,91 @@ public class TabPagerIndicator extends RecyclerView implements PagerIndicator {
|
|||
this(context, null);
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return mIndicatorAdapter.getItemCount();
|
||||
}
|
||||
|
||||
public Context getItemContext() {
|
||||
return mIndicatorAdapter.getItemContext();
|
||||
}
|
||||
|
||||
public void setItemContext(Context context) {
|
||||
mIndicatorAdapter.setItemContext(context);
|
||||
}
|
||||
|
||||
public int getStripHeight() {
|
||||
return mStripHeight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyDataSetChanged() {
|
||||
mIndicatorAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
if (mPageChangeListener == null) return;
|
||||
mPageChangeListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageSelected(int position) {
|
||||
mIndicatorAdapter.notifyDataSetChanged();
|
||||
if (mPageChangeListener == null) return;
|
||||
mPageChangeListener.onPageSelected(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int state) {
|
||||
if (mPageChangeListener == null) return;
|
||||
mPageChangeListener.onPageScrollStateChanged(state);
|
||||
}
|
||||
|
||||
public void setBadge(int position, int count) {
|
||||
mIndicatorAdapter.setBadge(position, count);
|
||||
}
|
||||
|
||||
public void setDisplayBadge(boolean display) {
|
||||
mIndicatorAdapter.setDisplayBadge(display);
|
||||
}
|
||||
|
||||
public void setIconColor(int color) {
|
||||
mIndicatorAdapter.setIconColor(color);
|
||||
}
|
||||
|
||||
public void setStripColor(int color) {
|
||||
mIndicatorAdapter.setStripColor(color);
|
||||
}
|
||||
|
||||
@DisplayOption
|
||||
public void setTabDisplayOption(int flags) {
|
||||
mOption = flags;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private void dispatchTabClick(int position) {
|
||||
final int currentItem = getCurrentItem();
|
||||
setCurrentItem(position);
|
||||
if (mPagerProvider instanceof TabListener) {
|
||||
if (currentItem != position) {
|
||||
((TabListener) mPagerProvider).onPageSelected(position);
|
||||
} else {
|
||||
((TabListener) mPagerProvider).onPageReselected(position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean dispatchTabLongClick(int position) {
|
||||
if (mPagerProvider instanceof TabListener) {
|
||||
return ((TabListener) mPagerProvider).onTabLongClick(position);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private int getCurrentItem() {
|
||||
return mViewPager.getCurrentItem();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCurrentItem(int item) {
|
||||
mViewPager.setCurrentItem(item);
|
||||
|
@ -88,62 +190,46 @@ public class TabPagerIndicator extends RecyclerView implements PagerIndicator {
|
|||
mIndicatorAdapter.setTabProvider((TabProvider) adapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
if (mPageChangeListener == null) return;
|
||||
mPageChangeListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
|
||||
private int getTabHorizontalPadding() {
|
||||
return mHorizontalPadding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageSelected(int position) {
|
||||
mIndicatorAdapter.notifyDataSetChanged();
|
||||
if (mPageChangeListener == null) return;
|
||||
mPageChangeListener.onPageSelected(position);
|
||||
private int getTabVerticalPadding() {
|
||||
return mVerticalPadding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int state) {
|
||||
if (mPageChangeListener == null) return;
|
||||
mPageChangeListener.onPageScrollStateChanged(state);
|
||||
private boolean isIconDisplayed() {
|
||||
return (mOption & ICON) != 0;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return mIndicatorAdapter.getItemCount();
|
||||
private boolean isLabelDisplayed() {
|
||||
return (mOption & LABEL) != 0;
|
||||
}
|
||||
|
||||
public void setBadge(int position, int count) {
|
||||
mIndicatorAdapter.setBadge(position, count);
|
||||
private boolean isTabExpandEnabled() {
|
||||
return mTabExpandEnabled;
|
||||
}
|
||||
|
||||
public void setDisplayLabel(boolean display) {
|
||||
|
||||
public void setTabExpandEnabled(boolean expandEnabled) {
|
||||
mTabExpandEnabled = expandEnabled;
|
||||
}
|
||||
|
||||
public void setDisplayIcon(boolean display) {
|
||||
|
||||
private void setHorizontalPadding(int padding) {
|
||||
mHorizontalPadding = padding;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public int getStripHeight() {
|
||||
return mStripHeight;
|
||||
private void setVerticalPadding(int padding) {
|
||||
mVerticalPadding = padding;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void setIconColor(int color) {
|
||||
mIndicatorAdapter.setIconColor(color);
|
||||
@IntDef({ICON, LABEL, BOTH})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface DisplayOption {
|
||||
}
|
||||
|
||||
public Context getItemContext() {
|
||||
return mIndicatorAdapter.getItemContext();
|
||||
}
|
||||
|
||||
public void setItemContext(Context context) {
|
||||
mIndicatorAdapter.setItemContext(context);
|
||||
}
|
||||
|
||||
public void setDisplayBadge(boolean display) {
|
||||
mIndicatorAdapter.setDisplayBadge(display);
|
||||
}
|
||||
|
||||
private static class TabPagerIndicatorAdapter extends Adapter<TabItemHolder> implements OnClickListener, OnLongClickListener {
|
||||
private static class TabPagerIndicatorAdapter extends Adapter<TabItemHolder> {
|
||||
|
||||
private final TabPagerIndicator mIndicator;
|
||||
private final SparseIntArray mUnreadCounts;
|
||||
|
@ -159,61 +245,8 @@ public class TabPagerIndicator extends RecyclerView implements PagerIndicator {
|
|||
mUnreadCounts = new SparseIntArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TabItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
final View view = mInflater.inflate(R.layout.tab_item_home, parent, false);
|
||||
view.setOnClickListener(this);
|
||||
view.setOnLongClickListener(this);
|
||||
final View selectedIndicator = view.findViewById(R.id.selected_indicator);
|
||||
final ViewGroup.LayoutParams lp = selectedIndicator.getLayoutParams();
|
||||
lp.height = mIndicator.getStripHeight();
|
||||
selectedIndicator.setLayoutParams(lp);
|
||||
return new TabItemHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(TabItemHolder holder, int position) {
|
||||
final Drawable icon = mTabProvider.getPageIcon(position);
|
||||
final CharSequence title = mTabProvider.getPageTitle(position);
|
||||
holder.setTabData(position, icon, title, mIndicator.getCurrentItem() == position);
|
||||
holder.setStripColor(mStripColor);
|
||||
holder.setIconColor(mIconColor);
|
||||
holder.setBadge(mUnreadCounts.get(position, 0), mDisplayBadge);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
if (mTabProvider == null) return 0;
|
||||
return mTabProvider.getCount();
|
||||
}
|
||||
|
||||
public void setTabProvider(TabProvider tabProvider) {
|
||||
mTabProvider = tabProvider;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
final Object tag = v.getTag();
|
||||
if (!(tag instanceof Integer)) return;
|
||||
mIndicator.dispatchTabClick((Integer) tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
final Object tag = v.getTag();
|
||||
if (!(tag instanceof Integer)) return false;
|
||||
return mIndicator.dispatchTabLongClick((Integer) tag);
|
||||
}
|
||||
|
||||
public void setStripColor(int color) {
|
||||
mStripColor = color;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void setIconColor(int color) {
|
||||
mIconColor = color;
|
||||
notifyDataSetChanged();
|
||||
public Context getItemContext() {
|
||||
return mItemContext;
|
||||
}
|
||||
|
||||
public void setItemContext(Context itemContext) {
|
||||
|
@ -221,8 +254,30 @@ public class TabPagerIndicator extends RecyclerView implements PagerIndicator {
|
|||
mInflater = LayoutInflater.from(itemContext);
|
||||
}
|
||||
|
||||
public Context getItemContext() {
|
||||
return mItemContext;
|
||||
@Override
|
||||
public TabItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
if (mIndicator == null) throw new IllegalStateException("item context not set");
|
||||
final View view = mInflater.inflate(R.layout.layout_tab_item, parent, false);
|
||||
return new TabItemHolder(mIndicator, view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(TabItemHolder holder, int position) {
|
||||
final Drawable icon = mTabProvider.getPageIcon(position);
|
||||
final CharSequence title = mTabProvider.getPageTitle(position);
|
||||
holder.setTabData(icon, title, mIndicator.getCurrentItem() == position);
|
||||
holder.setPadding(mIndicator.getTabHorizontalPadding(), mIndicator.getTabVerticalPadding());
|
||||
holder.setStripHeight(mIndicator.getStripHeight());
|
||||
holder.setStripColor(mStripColor);
|
||||
holder.setIconColor(mIconColor);
|
||||
holder.setBadge(mUnreadCounts.get(position, 0), mDisplayBadge);
|
||||
holder.setDisplayOption(mIndicator.isIconDisplayed(), mIndicator.isLabelDisplayed());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
if (mTabProvider == null) return 0;
|
||||
return mTabProvider.getCount();
|
||||
}
|
||||
|
||||
public void setBadge(int position, int count) {
|
||||
|
@ -234,67 +289,88 @@ public class TabPagerIndicator extends RecyclerView implements PagerIndicator {
|
|||
mDisplayBadge = display;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void dispatchTabClick(int position) {
|
||||
final int currentItem = getCurrentItem();
|
||||
setCurrentItem(position);
|
||||
if (mPagerProvider instanceof TabListener) {
|
||||
if (currentItem != position) {
|
||||
((TabListener) mPagerProvider).onPageSelected(position);
|
||||
} else {
|
||||
((TabListener) mPagerProvider).onPageReselected(position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean dispatchTabLongClick(int position) {
|
||||
if (mPagerProvider instanceof TabListener) {
|
||||
return ((TabListener) mPagerProvider).onTabLongClick(position);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private int getCurrentItem() {
|
||||
return mViewPager.getCurrentItem();
|
||||
}
|
||||
|
||||
private static class TabItemHolder extends ViewHolder {
|
||||
|
||||
private final View itemView;
|
||||
private final ImageView iconView;
|
||||
private final View selectedIndicator;
|
||||
private final BadgeView badgeView;
|
||||
|
||||
public TabItemHolder(View itemView) {
|
||||
super(itemView);
|
||||
this.itemView = itemView;
|
||||
selectedIndicator = itemView.findViewById(R.id.selected_indicator);
|
||||
iconView = (ImageView) itemView.findViewById(R.id.tab_icon);
|
||||
badgeView = (BadgeView) itemView.findViewById(R.id.unread_indicator);
|
||||
}
|
||||
|
||||
|
||||
public void setTabData(int position, Drawable icon, CharSequence title, boolean activated) {
|
||||
itemView.setTag(position);
|
||||
itemView.setContentDescription(title);
|
||||
iconView.setImageDrawable(icon);
|
||||
iconView.setContentDescription(title);
|
||||
selectedIndicator.setVisibility(activated ? VISIBLE : INVISIBLE);
|
||||
public void setIconColor(int color) {
|
||||
mIconColor = color;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void setStripColor(int color) {
|
||||
selectedIndicator.setBackgroundColor(color);
|
||||
mStripColor = color;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void setIconColor(int color) {
|
||||
iconView.setColorFilter(color);
|
||||
public void setTabProvider(TabProvider tabProvider) {
|
||||
mTabProvider = tabProvider;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private static class TabItemHolder extends ViewHolder implements OnClickListener, OnLongClickListener {
|
||||
|
||||
private final TabPagerIndicator indicator;
|
||||
private final ItemLayout itemView;
|
||||
private final ImageView iconView;
|
||||
private final TextView labelView;
|
||||
private final BadgeView badgeView;
|
||||
|
||||
public TabItemHolder(TabPagerIndicator indicator, View itemView) {
|
||||
super(itemView);
|
||||
this.indicator = indicator;
|
||||
this.itemView = (ItemLayout) itemView;
|
||||
itemView.setOnClickListener(this);
|
||||
itemView.setOnLongClickListener(this);
|
||||
iconView = (ImageView) itemView.findViewById(R.id.tab_icon);
|
||||
labelView = (TextView) itemView.findViewById(R.id.tab_label);
|
||||
badgeView = (BadgeView) itemView.findViewById(R.id.unread_indicator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
indicator.dispatchTabClick(getPosition());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
return indicator.dispatchTabLongClick(getPosition());
|
||||
}
|
||||
|
||||
public void setBadge(int count, boolean display) {
|
||||
badgeView.setText(String.valueOf(count));
|
||||
badgeView.setVisibility(display && count > 0 ? VISIBLE : GONE);
|
||||
}
|
||||
|
||||
public void setDisplayOption(boolean iconDisplayed, boolean labelDisplayed) {
|
||||
iconView.setVisibility(iconDisplayed ? VISIBLE : GONE);
|
||||
labelView.setVisibility(labelDisplayed ? VISIBLE : GONE);
|
||||
}
|
||||
|
||||
public void setIconColor(int color) {
|
||||
if (color != 0) {
|
||||
iconView.setColorFilter(color);
|
||||
} else {
|
||||
iconView.clearColorFilter();
|
||||
}
|
||||
}
|
||||
|
||||
public void setPadding(int horizontalPadding, int verticalPadding) {
|
||||
itemView.setPadding(horizontalPadding, verticalPadding, horizontalPadding, verticalPadding);
|
||||
}
|
||||
|
||||
public void setStripColor(int color) {
|
||||
itemView.setStripColor(color);
|
||||
}
|
||||
|
||||
public void setStripHeight(int stripHeight) {
|
||||
itemView.setStripHeight(stripHeight);
|
||||
}
|
||||
|
||||
public void setTabData(Drawable icon, CharSequence title, boolean activated) {
|
||||
itemView.setContentDescription(title);
|
||||
iconView.setImageDrawable(icon);
|
||||
labelView.setText(title);
|
||||
itemView.setIsCurrent(activated);
|
||||
}
|
||||
}
|
||||
|
||||
public static class TabLayoutManager extends LinearLayoutManager {
|
||||
|
@ -308,13 +384,59 @@ public class TabPagerIndicator extends RecyclerView implements PagerIndicator {
|
|||
|
||||
@Override
|
||||
public void measureChildWithMargins(View child, int widthUsed, int heightUsed) {
|
||||
// first get default measured size
|
||||
super.measureChildWithMargins(child, widthUsed, heightUsed);
|
||||
if (!mIndicator.isTabExpandEnabled()) return;
|
||||
final int count = mIndicator.getCount();
|
||||
if (count == 0) return;
|
||||
final int parentHeight = mIndicator.getHeight(), parentWidth = mIndicator.getWidth();
|
||||
final int width = Math.max(parentWidth / count, parentHeight);
|
||||
final int width = Math.max(parentWidth / count, child.getMeasuredWidth());
|
||||
final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(parentHeight, MeasureSpec.EXACTLY);
|
||||
final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
|
||||
child.measure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
}
|
||||
|
||||
public static final class ItemLayout extends RelativeLayout {
|
||||
|
||||
private final Paint mStripPaint;
|
||||
|
||||
private boolean mIsCurrent;
|
||||
private int mStripColor;
|
||||
private int mStripHeight;
|
||||
|
||||
public ItemLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mStripPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
setWillNotDraw(false);
|
||||
}
|
||||
|
||||
public void setIsCurrent(boolean isCurrent) {
|
||||
if (mIsCurrent == isCurrent) return;
|
||||
mIsCurrent = isCurrent;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setStripColor(int stripColor) {
|
||||
if (mStripColor == stripColor) return;
|
||||
mStripColor = stripColor;
|
||||
mStripPaint.setColor(stripColor);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setStripHeight(int stripHeight) {
|
||||
if (mStripHeight == stripHeight) return;
|
||||
mStripHeight = stripHeight;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
if (mIsCurrent) {
|
||||
final int width = canvas.getWidth(), height = canvas.getHeight();
|
||||
canvas.drawRect(0, height - mStripHeight, width, height, mStripPaint);
|
||||
}
|
||||
super.onDraw(canvas);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import org.mariotaku.twidere.adapter.iface.IStatusesAdapter;
|
|||
import org.mariotaku.twidere.model.ParcelableMedia;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus.CursorIndices;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
||||
import org.mariotaku.twidere.util.ImageLoadingHandler;
|
||||
import org.mariotaku.twidere.util.UserColorNicknameUtils;
|
||||
|
@ -84,11 +85,12 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
|
|||
|
||||
public void displayStatus(final ParcelableStatus status) {
|
||||
displayStatus(adapter.getContext(), adapter.getImageLoader(),
|
||||
adapter.getImageLoadingHandler(), status);
|
||||
adapter.getImageLoadingHandler(), adapter.getTwitterWrapper(), status);
|
||||
}
|
||||
|
||||
public void displayStatus(final Context context, final ImageLoaderWrapper loader,
|
||||
final ImageLoadingHandler handler, final ParcelableStatus status) {
|
||||
final ImageLoadingHandler handler, final AsyncTwitterWrapper twitter,
|
||||
final ParcelableStatus status) {
|
||||
final ParcelableMedia[] media = status.media;
|
||||
|
||||
if (status.retweet_id > 0) {
|
||||
|
@ -163,12 +165,18 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
|
|||
retweetCountView.setEnabled(!status.user_is_protected);
|
||||
|
||||
retweetCountView.setActivated(Utils.isMyRetweet(status));
|
||||
favoriteCountView.setActivated(status.is_favorite);
|
||||
if (twitter.isDestroyingFavorite(status.account_id, status.id)) {
|
||||
favoriteCountView.setActivated(false);
|
||||
} else {
|
||||
favoriteCountView.setActivated(twitter.isCreatingFavorite(status.account_id, status.id)
|
||||
|| status.is_favorite);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void displayStatus(Cursor cursor, CursorIndices indices) {
|
||||
final ImageLoaderWrapper loader = adapter.getImageLoader();
|
||||
final AsyncTwitterWrapper twitter = adapter.getTwitterWrapper();
|
||||
final Context context = adapter.getContext();
|
||||
|
||||
final int reply_count = cursor.getInt(indices.reply_count);
|
||||
|
@ -178,6 +186,7 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
|
|||
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 status_id = cursor.getLong(indices.status_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);
|
||||
|
@ -269,6 +278,12 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
|
|||
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);
|
||||
if (twitter.isDestroyingFavorite(account_id, status_id)) {
|
||||
favoriteCountView.setActivated(false);
|
||||
} else {
|
||||
favoriteCountView.setActivated(twitter.isCreatingFavorite(account_id, status_id)
|
||||
|| cursor.getInt(indices.is_favorite) == 1);
|
||||
}
|
||||
}
|
||||
|
||||
public CardView getCardView() {
|
||||
|
|
|
@ -42,387 +42,387 @@ import org.mariotaku.twidere.util.ThemeUtils;
|
|||
|
||||
public interface ICardItemView extends IColorLabelView {
|
||||
|
||||
public View getFakeOverflowButton();
|
||||
|
||||
public boolean isGap();
|
||||
|
||||
public void setActivatedIndicator(Drawable activatedIndicator);
|
||||
|
||||
public void setIsGap(boolean isGap);
|
||||
|
||||
public void setItemBackground(Drawable itemBackground);
|
||||
|
||||
public void setItemSelector(Drawable itemSelector);
|
||||
|
||||
public void setOnOverflowIconClickListener(final OnOverflowIconClickListener listener);
|
||||
|
||||
public void setOverflowIcon(Drawable overflowIcon);
|
||||
|
||||
public static final class DrawingHelper {
|
||||
|
||||
private final View mView;
|
||||
|
||||
private final int mCardGapHeight;
|
||||
private final String mCardGapText;
|
||||
private final Paint mGapTextPaint;
|
||||
|
||||
private final Rect mGapTextBounds = new Rect();
|
||||
private final Rect mBackgroundPadding = new Rect();
|
||||
private final Rect mOverflowIconBounds = new Rect();
|
||||
|
||||
private Drawable mBackground;
|
||||
private Drawable mItemSelector;
|
||||
private Drawable mActivatedIndicator;
|
||||
private Drawable mOverflowIcon;
|
||||
private Drawable mPaddedOverflowIcon;
|
||||
|
||||
private boolean mIsGap;
|
||||
|
||||
private final int mThemeColor;
|
||||
|
||||
private final GestureDetector mOverflowIconGestureDetector;
|
||||
|
||||
private OnOverflowIconClickListener mOnOverflowIconClickListener;
|
||||
|
||||
private final FakeOverflowButton mFakeOverflowButton;
|
||||
|
||||
private float mBackgroundAlpha;
|
||||
|
||||
public DrawingHelper(final View view, final Context context, final AttributeSet attrs, final int defStyleAttr) {
|
||||
mView = view;
|
||||
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CardItemView, defStyleAttr,
|
||||
R.style.Widget_CardItemView);
|
||||
mGapTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mCardGapHeight = a.getDimensionPixelSize(R.styleable.CardItemView_cardGapHeight, 0);
|
||||
mCardGapText = a.getString(R.styleable.CardItemView_cardGapText);
|
||||
mGapTextPaint.setColor(a.getColor(R.styleable.CardItemView_cardGapTextColor, Color.GRAY));
|
||||
mGapTextPaint.setTextSize(a.getDimensionPixelSize(R.styleable.CardItemView_cardGapTextSize, 18));
|
||||
mGapTextPaint.setTypeface(Typeface.DEFAULT_BOLD);
|
||||
mThemeColor = ThemeUtils.getUserAccentColor(context);
|
||||
mOverflowIconGestureDetector = new GestureDetector(context, new OverflowIconGestureListener(this));
|
||||
mFakeOverflowButton = new FakeOverflowButton(this);
|
||||
mBackgroundAlpha = a.getFraction(R.styleable.CardItemView_cardBackgroundAlpha, 1, 1, 1.0f);
|
||||
setItemBackground(a.getDrawable(R.styleable.CardItemView_cardBackground));
|
||||
setItemSelector(a.getDrawable(R.styleable.CardItemView_cardSelector));
|
||||
setActivatedIndicator(a.getDrawable(R.styleable.CardItemView_cardActivatedIndicator));
|
||||
setOverflowIcon(a.getDrawable(R.styleable.CardItemView_cardOverflowIcon));
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
public void dispatchDrawableStateChanged() {
|
||||
final int[] state = mView.getDrawableState();
|
||||
if (mBackground != null) {
|
||||
mBackground.setState(state);
|
||||
}
|
||||
if (mItemSelector != null) {
|
||||
mItemSelector.setState(state);
|
||||
}
|
||||
if (mActivatedIndicator != null) {
|
||||
mActivatedIndicator.setState(state);
|
||||
}
|
||||
}
|
||||
|
||||
public void dispatchOnSizeChanged(final int w, final int h, final int oldw, final int oldh) {
|
||||
final int paddingLeft = mView.getPaddingLeft();
|
||||
final int paddingTop = mView.getPaddingTop();
|
||||
final int paddingRight = mView.getPaddingRight();
|
||||
final int paddingBottom = mView.getPaddingBottom();
|
||||
final int l = paddingLeft, t = paddingTop, r = w - paddingRight, b = h - paddingBottom;
|
||||
if (mBackground != null) {
|
||||
if (mBackground instanceof NinePatchDrawable) {
|
||||
final NinePatchDrawable npd = (NinePatchDrawable) mBackground;
|
||||
npd.getPadding(mBackgroundPadding);
|
||||
npd.setBounds(l - mBackgroundPadding.left, t - mBackgroundPadding.top,
|
||||
r + mBackgroundPadding.right, b + mBackgroundPadding.bottom);
|
||||
} else {
|
||||
mBackground.setBounds(l, t, r, b);
|
||||
}
|
||||
}
|
||||
if (mItemSelector != null) {
|
||||
if (mIsGap) {
|
||||
mItemSelector.setBounds(0, 0, w, h);
|
||||
} else {
|
||||
mItemSelector.setBounds(l, t, r, b);
|
||||
}
|
||||
}
|
||||
if (mActivatedIndicator != null) {
|
||||
mActivatedIndicator.setBounds(l, t, r, b);
|
||||
}
|
||||
if (mOverflowIcon != null) {
|
||||
mPaddedOverflowIcon = new PaddingDrawable(mOverflowIcon, paddingTop, 0, paddingRight, 0);
|
||||
final int iw = mPaddedOverflowIcon.getIntrinsicWidth();
|
||||
final int ih = mPaddedOverflowIcon.getIntrinsicHeight();
|
||||
mOverflowIconBounds.set(w - iw, 0, w, ih);
|
||||
mPaddedOverflowIcon.setBounds(mOverflowIconBounds);
|
||||
} else {
|
||||
mPaddedOverflowIcon = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void drawBackground(final Canvas canvas) {
|
||||
if (mBackground != null && !mIsGap) {
|
||||
mBackground.draw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
public void drawGap(final Canvas canvas) {
|
||||
if (mIsGap) {
|
||||
final int centerX = canvas.getWidth() / 2, centerY = canvas.getHeight() / 2;
|
||||
if (mCardGapText != null) {
|
||||
mGapTextPaint.getTextBounds(mCardGapText, 0, mCardGapText.length(), mGapTextBounds);
|
||||
final float xPos = centerX - mGapTextBounds.width() / 2;
|
||||
final float yPos = centerY - (mGapTextPaint.descent() + mGapTextPaint.ascent()) / 2;
|
||||
canvas.drawText(mCardGapText, xPos, yPos, mGapTextPaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void drawOverflowIcon(final Canvas canvas) {
|
||||
if (mPaddedOverflowIcon != null && mOnOverflowIconClickListener != null) {
|
||||
mPaddedOverflowIcon.draw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
public void drawSelector(final Canvas canvas) {
|
||||
if (mActivatedIndicator != null) {
|
||||
mActivatedIndicator.draw(canvas);
|
||||
}
|
||||
if (mItemSelector != null) {
|
||||
mItemSelector.draw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
public int getCardGapHeight() {
|
||||
return mCardGapHeight;
|
||||
}
|
||||
|
||||
public View getFakeOverflowButton() {
|
||||
return mFakeOverflowButton;
|
||||
}
|
||||
|
||||
public boolean handleOverflowTouchEvent(final MotionEvent ev) {
|
||||
return mOverflowIconGestureDetector.onTouchEvent(ev);
|
||||
}
|
||||
|
||||
public boolean isGap() {
|
||||
return mIsGap;
|
||||
}
|
||||
|
||||
public boolean isOverflowIconClicked(final MotionEvent ev) {
|
||||
if (mOverflowIcon == null || mOnOverflowIconClickListener == null) return false;
|
||||
final int x = Math.round(ev.getX()), y = Math.round(ev.getY());
|
||||
if (mOverflowIconBounds.contains(x, y)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setActivatedIndicator(final Drawable activatedIndicator) {
|
||||
preSetDrawable(mActivatedIndicator);
|
||||
mActivatedIndicator = activatedIndicator;
|
||||
if (activatedIndicator != null) {
|
||||
activatedIndicator.setAlpha(0x80);
|
||||
}
|
||||
postSetDrawable(activatedIndicator);
|
||||
}
|
||||
|
||||
public void setIsGap(final boolean isGap) {
|
||||
mIsGap = isGap;
|
||||
mView.requestLayout();
|
||||
}
|
||||
|
||||
public void setItemBackground(final Drawable itemBackground) {
|
||||
preSetDrawable(mBackground);
|
||||
mBackground = itemBackground;
|
||||
updateBackgroundAlpha();
|
||||
postSetDrawable(itemBackground);
|
||||
}
|
||||
|
||||
public void setItemBackgroundAlpha(final float alpha) {
|
||||
mBackgroundAlpha = alpha;
|
||||
updateBackgroundAlpha();
|
||||
}
|
||||
|
||||
public void setItemSelector(final Drawable itemSelector) {
|
||||
preSetDrawable(mItemSelector);
|
||||
mItemSelector = itemSelector;
|
||||
if (itemSelector != null) {
|
||||
itemSelector.setAlpha(0x80);
|
||||
}
|
||||
postSetDrawable(itemSelector);
|
||||
}
|
||||
|
||||
public void setOnOverflowIconClickListener(final OnOverflowIconClickListener listener) {
|
||||
mOnOverflowIconClickListener = listener;
|
||||
}
|
||||
|
||||
public void setOverflowIcon(final Drawable overflowIcon) {
|
||||
preSetDrawable(mOverflowIcon);
|
||||
mOverflowIcon = overflowIcon;
|
||||
if (mOverflowIcon != null) {
|
||||
mOverflowIcon.mutate();
|
||||
}
|
||||
postSetDrawable(overflowIcon);
|
||||
}
|
||||
|
||||
public boolean verifyDrawable(final Drawable who) {
|
||||
return who == mBackground || who == mItemSelector || who == mActivatedIndicator || who == mOverflowIcon;
|
||||
}
|
||||
|
||||
private void postSetDrawable(final Drawable curr) {
|
||||
mView.setWillNotDraw(verifyDrawable(curr));
|
||||
if (curr != null) {
|
||||
if (curr.isStateful()) {
|
||||
curr.setState(mView.getDrawableState());
|
||||
}
|
||||
curr.setCallback(mView);
|
||||
}
|
||||
}
|
||||
|
||||
private void preSetDrawable(final Drawable prev) {
|
||||
if (prev != null) {
|
||||
mView.unscheduleDrawable(prev);
|
||||
prev.setCallback(null);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateBackgroundAlpha() {
|
||||
if (mBackground != null) {
|
||||
mBackground.setAlpha(Math.round(mBackgroundAlpha * 0xff));
|
||||
}
|
||||
}
|
||||
|
||||
static class FakeOverflowButton extends View {
|
||||
|
||||
private final DrawingHelper mHelper;
|
||||
|
||||
public FakeOverflowButton(final DrawingHelper helper) {
|
||||
super(helper.mView.getContext());
|
||||
mHelper = helper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getLocationInWindow(final int[] location) {
|
||||
mHelper.mView.getLocationInWindow(location);
|
||||
location[0] += mHelper.mOverflowIconBounds.left;
|
||||
location[1] += mHelper.mOverflowIconBounds.top;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getLocationOnScreen(final int[] location) {
|
||||
mHelper.mView.getLocationOnScreen(location);
|
||||
location[0] += mHelper.mOverflowIconBounds.left;
|
||||
location[1] += mHelper.mOverflowIconBounds.top;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getRootView() {
|
||||
return mHelper.mView.getRootView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTag() {
|
||||
return mHelper.mView.getTag();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder getWindowToken() {
|
||||
return mHelper.mView.getWindowToken();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getWindowVisibleDisplayFrame(final Rect outRect) {
|
||||
mHelper.mView.getWindowVisibleDisplayFrame(outRect);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(final boolean changed, final int left, final int top, final int right,
|
||||
final int bottom) {
|
||||
final Rect bounds = mHelper.mOverflowIconBounds;
|
||||
layout(bounds.left, bounds.top, bounds.right, bounds.bottom);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||
final int width = mHelper.mOverflowIconBounds.width();
|
||||
final int height = mHelper.mOverflowIconBounds.height();
|
||||
final int wSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.getMode(widthMeasureSpec));
|
||||
final int hSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.getMode(heightMeasureSpec));
|
||||
setMeasuredDimension(width, height);
|
||||
super.onMeasure(wSpec, hSpec);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class OverflowIconGestureListener extends SimpleOnGestureListener {
|
||||
|
||||
private final DrawingHelper mDrawingHelper;
|
||||
|
||||
public OverflowIconGestureListener(final DrawingHelper drawingHelper) {
|
||||
mDrawingHelper = drawingHelper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDown(final MotionEvent e) {
|
||||
final Drawable d = mDrawingHelper.mPaddedOverflowIcon;
|
||||
final OnOverflowIconClickListener l = mDrawingHelper.mOnOverflowIconClickListener;
|
||||
if (d == null || l == null) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onFling(final MotionEvent e1, final MotionEvent e2, final float velocityX,
|
||||
final float velocityY) {
|
||||
return clearHighlight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLongPress(final MotionEvent e) {
|
||||
clearHighlight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onScroll(final MotionEvent e1, final MotionEvent e2, final float distanceX,
|
||||
final float distanceY) {
|
||||
return clearHighlight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShowPress(final MotionEvent e) {
|
||||
final Drawable d = mDrawingHelper.mPaddedOverflowIcon;
|
||||
final int c = mDrawingHelper.mThemeColor;
|
||||
if (d != null) {
|
||||
d.setColorFilter(c, PorterDuff.Mode.SRC_ATOP);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSingleTapConfirmed(final MotionEvent e) {
|
||||
final OnOverflowIconClickListener l = mDrawingHelper.mOnOverflowIconClickListener;
|
||||
if (clearHighlight() && l != null) {
|
||||
l.onOverflowIconClick(mDrawingHelper.mFakeOverflowButton);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSingleTapUp(final MotionEvent e) {
|
||||
return clearHighlight();
|
||||
}
|
||||
|
||||
private boolean clearHighlight() {
|
||||
final Drawable d = mDrawingHelper.mPaddedOverflowIcon;
|
||||
if (d != null) {
|
||||
d.clearColorFilter();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static interface OnOverflowIconClickListener {
|
||||
|
||||
public void onOverflowIconClick(View view);
|
||||
|
||||
}
|
||||
public View getFakeOverflowButton();
|
||||
|
||||
public boolean isGap();
|
||||
|
||||
public void setActivatedIndicator(Drawable activatedIndicator);
|
||||
|
||||
public void setIsGap(boolean isGap);
|
||||
|
||||
public void setItemBackground(Drawable itemBackground);
|
||||
|
||||
public void setItemSelector(Drawable itemSelector);
|
||||
|
||||
public void setOnOverflowIconClickListener(final OnOverflowIconClickListener listener);
|
||||
|
||||
public void setOverflowIcon(Drawable overflowIcon);
|
||||
|
||||
public static final class DrawingHelper {
|
||||
|
||||
private final View mView;
|
||||
|
||||
private final int mCardGapHeight;
|
||||
private final String mCardGapText;
|
||||
private final Paint mGapTextPaint;
|
||||
|
||||
private final Rect mGapTextBounds = new Rect();
|
||||
private final Rect mBackgroundPadding = new Rect();
|
||||
private final Rect mOverflowIconBounds = new Rect();
|
||||
|
||||
private Drawable mBackground;
|
||||
private Drawable mItemSelector;
|
||||
private Drawable mActivatedIndicator;
|
||||
private Drawable mOverflowIcon;
|
||||
private Drawable mPaddedOverflowIcon;
|
||||
|
||||
private boolean mIsGap;
|
||||
|
||||
private final int mThemeColor;
|
||||
|
||||
private final GestureDetector mOverflowIconGestureDetector;
|
||||
|
||||
private OnOverflowIconClickListener mOnOverflowIconClickListener;
|
||||
|
||||
private final FakeOverflowButton mFakeOverflowButton;
|
||||
|
||||
private float mBackgroundAlpha;
|
||||
|
||||
public DrawingHelper(final View view, final Context context, final AttributeSet attrs, final int defStyleAttr) {
|
||||
mView = view;
|
||||
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CardItemView, defStyleAttr,
|
||||
R.style.Widget_CardItemView);
|
||||
mGapTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mCardGapHeight = a.getDimensionPixelSize(R.styleable.CardItemView_cardGapHeight, 0);
|
||||
mCardGapText = a.getString(R.styleable.CardItemView_cardGapText);
|
||||
mGapTextPaint.setColor(a.getColor(R.styleable.CardItemView_cardGapTextColor, Color.GRAY));
|
||||
mGapTextPaint.setTextSize(a.getDimensionPixelSize(R.styleable.CardItemView_cardGapTextSize, 18));
|
||||
mGapTextPaint.setTypeface(Typeface.DEFAULT_BOLD);
|
||||
mThemeColor = view.isInEditMode() ? 0 : ThemeUtils.getUserAccentColor(context);
|
||||
mOverflowIconGestureDetector = new GestureDetector(context, new OverflowIconGestureListener(this));
|
||||
mFakeOverflowButton = new FakeOverflowButton(this);
|
||||
mBackgroundAlpha = a.getFraction(R.styleable.CardItemView_cardBackgroundAlpha, 1, 1, 1.0f);
|
||||
setItemBackground(a.getDrawable(R.styleable.CardItemView_cardBackground));
|
||||
setItemSelector(a.getDrawable(R.styleable.CardItemView_cardSelector));
|
||||
setActivatedIndicator(a.getDrawable(R.styleable.CardItemView_cardActivatedIndicator));
|
||||
setOverflowIcon(a.getDrawable(R.styleable.CardItemView_cardOverflowIcon));
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
public void dispatchDrawableStateChanged() {
|
||||
final int[] state = mView.getDrawableState();
|
||||
if (mBackground != null) {
|
||||
mBackground.setState(state);
|
||||
}
|
||||
if (mItemSelector != null) {
|
||||
mItemSelector.setState(state);
|
||||
}
|
||||
if (mActivatedIndicator != null) {
|
||||
mActivatedIndicator.setState(state);
|
||||
}
|
||||
}
|
||||
|
||||
public void dispatchOnSizeChanged(final int w, final int h, final int oldw, final int oldh) {
|
||||
final int paddingLeft = mView.getPaddingLeft();
|
||||
final int paddingTop = mView.getPaddingTop();
|
||||
final int paddingRight = mView.getPaddingRight();
|
||||
final int paddingBottom = mView.getPaddingBottom();
|
||||
final int l = paddingLeft, t = paddingTop, r = w - paddingRight, b = h - paddingBottom;
|
||||
if (mBackground != null) {
|
||||
if (mBackground instanceof NinePatchDrawable) {
|
||||
final NinePatchDrawable npd = (NinePatchDrawable) mBackground;
|
||||
npd.getPadding(mBackgroundPadding);
|
||||
npd.setBounds(l - mBackgroundPadding.left, t - mBackgroundPadding.top,
|
||||
r + mBackgroundPadding.right, b + mBackgroundPadding.bottom);
|
||||
} else {
|
||||
mBackground.setBounds(l, t, r, b);
|
||||
}
|
||||
}
|
||||
if (mItemSelector != null) {
|
||||
if (mIsGap) {
|
||||
mItemSelector.setBounds(0, 0, w, h);
|
||||
} else {
|
||||
mItemSelector.setBounds(l, t, r, b);
|
||||
}
|
||||
}
|
||||
if (mActivatedIndicator != null) {
|
||||
mActivatedIndicator.setBounds(l, t, r, b);
|
||||
}
|
||||
if (mOverflowIcon != null) {
|
||||
mPaddedOverflowIcon = new PaddingDrawable(mOverflowIcon, paddingTop, 0, paddingRight, 0);
|
||||
final int iw = mPaddedOverflowIcon.getIntrinsicWidth();
|
||||
final int ih = mPaddedOverflowIcon.getIntrinsicHeight();
|
||||
mOverflowIconBounds.set(w - iw, 0, w, ih);
|
||||
mPaddedOverflowIcon.setBounds(mOverflowIconBounds);
|
||||
} else {
|
||||
mPaddedOverflowIcon = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void drawBackground(final Canvas canvas) {
|
||||
if (mBackground != null && !mIsGap) {
|
||||
mBackground.draw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
public void drawGap(final Canvas canvas) {
|
||||
if (mIsGap) {
|
||||
final int centerX = canvas.getWidth() / 2, centerY = canvas.getHeight() / 2;
|
||||
if (mCardGapText != null) {
|
||||
mGapTextPaint.getTextBounds(mCardGapText, 0, mCardGapText.length(), mGapTextBounds);
|
||||
final float xPos = centerX - mGapTextBounds.width() / 2;
|
||||
final float yPos = centerY - (mGapTextPaint.descent() + mGapTextPaint.ascent()) / 2;
|
||||
canvas.drawText(mCardGapText, xPos, yPos, mGapTextPaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void drawOverflowIcon(final Canvas canvas) {
|
||||
if (mPaddedOverflowIcon != null && mOnOverflowIconClickListener != null) {
|
||||
mPaddedOverflowIcon.draw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
public void drawSelector(final Canvas canvas) {
|
||||
if (mActivatedIndicator != null) {
|
||||
mActivatedIndicator.draw(canvas);
|
||||
}
|
||||
if (mItemSelector != null) {
|
||||
mItemSelector.draw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
public int getCardGapHeight() {
|
||||
return mCardGapHeight;
|
||||
}
|
||||
|
||||
public View getFakeOverflowButton() {
|
||||
return mFakeOverflowButton;
|
||||
}
|
||||
|
||||
public boolean handleOverflowTouchEvent(final MotionEvent ev) {
|
||||
return mOverflowIconGestureDetector.onTouchEvent(ev);
|
||||
}
|
||||
|
||||
public boolean isGap() {
|
||||
return mIsGap;
|
||||
}
|
||||
|
||||
public boolean isOverflowIconClicked(final MotionEvent ev) {
|
||||
if (mOverflowIcon == null || mOnOverflowIconClickListener == null) return false;
|
||||
final int x = Math.round(ev.getX()), y = Math.round(ev.getY());
|
||||
if (mOverflowIconBounds.contains(x, y)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setActivatedIndicator(final Drawable activatedIndicator) {
|
||||
preSetDrawable(mActivatedIndicator);
|
||||
mActivatedIndicator = activatedIndicator;
|
||||
if (activatedIndicator != null) {
|
||||
activatedIndicator.setAlpha(0x80);
|
||||
}
|
||||
postSetDrawable(activatedIndicator);
|
||||
}
|
||||
|
||||
public void setIsGap(final boolean isGap) {
|
||||
mIsGap = isGap;
|
||||
mView.requestLayout();
|
||||
}
|
||||
|
||||
public void setItemBackground(final Drawable itemBackground) {
|
||||
preSetDrawable(mBackground);
|
||||
mBackground = itemBackground;
|
||||
updateBackgroundAlpha();
|
||||
postSetDrawable(itemBackground);
|
||||
}
|
||||
|
||||
public void setItemBackgroundAlpha(final float alpha) {
|
||||
mBackgroundAlpha = alpha;
|
||||
updateBackgroundAlpha();
|
||||
}
|
||||
|
||||
public void setItemSelector(final Drawable itemSelector) {
|
||||
preSetDrawable(mItemSelector);
|
||||
mItemSelector = itemSelector;
|
||||
if (itemSelector != null) {
|
||||
itemSelector.setAlpha(0x80);
|
||||
}
|
||||
postSetDrawable(itemSelector);
|
||||
}
|
||||
|
||||
public void setOnOverflowIconClickListener(final OnOverflowIconClickListener listener) {
|
||||
mOnOverflowIconClickListener = listener;
|
||||
}
|
||||
|
||||
public void setOverflowIcon(final Drawable overflowIcon) {
|
||||
preSetDrawable(mOverflowIcon);
|
||||
mOverflowIcon = overflowIcon;
|
||||
if (mOverflowIcon != null) {
|
||||
mOverflowIcon.mutate();
|
||||
}
|
||||
postSetDrawable(overflowIcon);
|
||||
}
|
||||
|
||||
public boolean verifyDrawable(final Drawable who) {
|
||||
return who == mBackground || who == mItemSelector || who == mActivatedIndicator || who == mOverflowIcon;
|
||||
}
|
||||
|
||||
private void postSetDrawable(final Drawable curr) {
|
||||
mView.setWillNotDraw(verifyDrawable(curr));
|
||||
if (curr != null) {
|
||||
if (curr.isStateful()) {
|
||||
curr.setState(mView.getDrawableState());
|
||||
}
|
||||
curr.setCallback(mView);
|
||||
}
|
||||
}
|
||||
|
||||
private void preSetDrawable(final Drawable prev) {
|
||||
if (prev != null) {
|
||||
mView.unscheduleDrawable(prev);
|
||||
prev.setCallback(null);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateBackgroundAlpha() {
|
||||
if (mBackground != null) {
|
||||
mBackground.setAlpha(Math.round(mBackgroundAlpha * 0xff));
|
||||
}
|
||||
}
|
||||
|
||||
static class FakeOverflowButton extends View {
|
||||
|
||||
private final DrawingHelper mHelper;
|
||||
|
||||
public FakeOverflowButton(final DrawingHelper helper) {
|
||||
super(helper.mView.getContext());
|
||||
mHelper = helper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getLocationInWindow(final int[] location) {
|
||||
mHelper.mView.getLocationInWindow(location);
|
||||
location[0] += mHelper.mOverflowIconBounds.left;
|
||||
location[1] += mHelper.mOverflowIconBounds.top;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getLocationOnScreen(final int[] location) {
|
||||
mHelper.mView.getLocationOnScreen(location);
|
||||
location[0] += mHelper.mOverflowIconBounds.left;
|
||||
location[1] += mHelper.mOverflowIconBounds.top;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getRootView() {
|
||||
return mHelper.mView.getRootView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTag() {
|
||||
return mHelper.mView.getTag();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder getWindowToken() {
|
||||
return mHelper.mView.getWindowToken();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getWindowVisibleDisplayFrame(final Rect outRect) {
|
||||
mHelper.mView.getWindowVisibleDisplayFrame(outRect);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(final boolean changed, final int left, final int top, final int right,
|
||||
final int bottom) {
|
||||
final Rect bounds = mHelper.mOverflowIconBounds;
|
||||
layout(bounds.left, bounds.top, bounds.right, bounds.bottom);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||
final int width = mHelper.mOverflowIconBounds.width();
|
||||
final int height = mHelper.mOverflowIconBounds.height();
|
||||
final int wSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.getMode(widthMeasureSpec));
|
||||
final int hSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.getMode(heightMeasureSpec));
|
||||
setMeasuredDimension(width, height);
|
||||
super.onMeasure(wSpec, hSpec);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class OverflowIconGestureListener extends SimpleOnGestureListener {
|
||||
|
||||
private final DrawingHelper mDrawingHelper;
|
||||
|
||||
public OverflowIconGestureListener(final DrawingHelper drawingHelper) {
|
||||
mDrawingHelper = drawingHelper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDown(final MotionEvent e) {
|
||||
final Drawable d = mDrawingHelper.mPaddedOverflowIcon;
|
||||
final OnOverflowIconClickListener l = mDrawingHelper.mOnOverflowIconClickListener;
|
||||
if (d == null || l == null) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onFling(final MotionEvent e1, final MotionEvent e2, final float velocityX,
|
||||
final float velocityY) {
|
||||
return clearHighlight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLongPress(final MotionEvent e) {
|
||||
clearHighlight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onScroll(final MotionEvent e1, final MotionEvent e2, final float distanceX,
|
||||
final float distanceY) {
|
||||
return clearHighlight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShowPress(final MotionEvent e) {
|
||||
final Drawable d = mDrawingHelper.mPaddedOverflowIcon;
|
||||
final int c = mDrawingHelper.mThemeColor;
|
||||
if (d != null) {
|
||||
d.setColorFilter(c, PorterDuff.Mode.SRC_ATOP);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSingleTapConfirmed(final MotionEvent e) {
|
||||
final OnOverflowIconClickListener l = mDrawingHelper.mOnOverflowIconClickListener;
|
||||
if (clearHighlight() && l != null) {
|
||||
l.onOverflowIconClick(mDrawingHelper.mFakeOverflowButton);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSingleTapUp(final MotionEvent e) {
|
||||
return clearHighlight();
|
||||
}
|
||||
|
||||
private boolean clearHighlight() {
|
||||
final Drawable d = mDrawingHelper.mPaddedOverflowIcon;
|
||||
if (d != null) {
|
||||
d.clearColorFilter();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static interface OnOverflowIconClickListener {
|
||||
|
||||
public void onOverflowIconClick(View view);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Before Width: | Height: | Size: 485 B |
Before Width: | Height: | Size: 481 B |
Before Width: | Height: | Size: 472 B |
Before Width: | Height: | Size: 350 B |
Before Width: | Height: | Size: 454 B |
Before Width: | Height: | Size: 452 B |
Before Width: | Height: | Size: 468 B |
Before Width: | Height: | Size: 468 B |
Before Width: | Height: | Size: 455 B |
Before Width: | Height: | Size: 336 B |
Before Width: | Height: | Size: 437 B |
Before Width: | Height: | Size: 437 B |
Before Width: | Height: | Size: 349 B |
Before Width: | Height: | Size: 345 B |
Before Width: | Height: | Size: 342 B |
Before Width: | Height: | Size: 343 B |
Before Width: | Height: | Size: 592 B |
Before Width: | Height: | Size: 587 B |
Before Width: | Height: | Size: 564 B |
Before Width: | Height: | Size: 563 B |
Before Width: | Height: | Size: 584 B |
Before Width: | Height: | Size: 474 B |
Before Width: | Height: | Size: 565 B |
Before Width: | Height: | Size: 563 B |
Before Width: | Height: | Size: 564 B |
Before Width: | Height: | Size: 563 B |
Before Width: | Height: | Size: 525 B |
Before Width: | Height: | Size: 525 B |
Before Width: | Height: | Size: 543 B |
Before Width: | Height: | Size: 460 B |
Before Width: | Height: | Size: 525 B |
Before Width: | Height: | Size: 525 B |
Before Width: | Height: | Size: 406 B |
Before Width: | Height: | Size: 402 B |
Before Width: | Height: | Size: 410 B |
Before Width: | Height: | Size: 413 B |
|
@ -1,9 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:drawable="@drawable/bg_card_item_message_incoming_normal_dark" android:state_window_focused="false"/>
|
||||
<item android:drawable="@drawable/bg_card_item_message_incoming_pressed_dark" android:state_pressed="true" android:state_selected="true"/>
|
||||
<item android:drawable="@drawable/bg_card_item_message_incoming_pressed_dark" android:state_pressed="true" android:state_selected="false"/>
|
||||
<item android:drawable="@drawable/bg_card_item_message_incoming_focused_dark" android:state_selected="true"/>
|
||||
|
||||
</selector>
|
|
@ -1,9 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:drawable="@drawable/bg_card_item_message_incoming_normal_light" android:state_window_focused="false"/>
|
||||
<item android:drawable="@drawable/bg_card_item_message_incoming_pressed_light" android:state_pressed="true" android:state_selected="true"/>
|
||||
<item android:drawable="@drawable/bg_card_item_message_incoming_pressed_light" android:state_pressed="true" android:state_selected="false"/>
|
||||
<item android:drawable="@drawable/bg_card_item_message_incoming_focused_light" android:state_selected="true"/>
|
||||
|
||||
</selector>
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<transition xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:drawable="@drawable/bg_card_item_message_incoming_pressed_dark"/>
|
||||
<item android:drawable="@drawable/bg_card_item_message_incoming_longpressed_dark"/>
|
||||
|
||||
</transition>
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<transition xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:drawable="@drawable/bg_card_item_message_incoming_pressed_light"/>
|
||||
<item android:drawable="@drawable/bg_card_item_message_incoming_longpressed_light"/>
|
||||
|
||||
</transition>
|
|
@ -1,9 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:drawable="@drawable/bg_card_item_message_outgoing_normal_dark" android:state_window_focused="false"/>
|
||||
<item android:drawable="@drawable/bg_card_item_message_outgoing_pressed_dark" android:state_pressed="true" android:state_selected="true"/>
|
||||
<item android:drawable="@drawable/bg_card_item_message_outgoing_pressed_dark" android:state_pressed="true" android:state_selected="false"/>
|
||||
<item android:drawable="@drawable/bg_card_item_message_outgoing_focused_dark" android:state_selected="true"/>
|
||||
|
||||
</selector>
|
|
@ -1,9 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:drawable="@drawable/bg_card_item_message_outgoing_normal_light" android:state_window_focused="false"/>
|
||||
<item android:drawable="@drawable/bg_card_item_message_outgoing_pressed_light" android:state_pressed="true" android:state_selected="true"/>
|
||||
<item android:drawable="@drawable/bg_card_item_message_outgoing_pressed_light" android:state_pressed="true" android:state_selected="false"/>
|
||||
<item android:drawable="@drawable/bg_card_item_message_outgoing_focused_light" android:state_selected="true"/>
|
||||
|
||||
</selector>
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<transition xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:drawable="@drawable/bg_card_item_message_outgoing_pressed_dark"/>
|
||||
<item android:drawable="@drawable/bg_card_item_message_outgoing_longpressed_dark"/>
|
||||
|
||||
</transition>
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<transition xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:drawable="@drawable/bg_card_item_message_outgoing_pressed_light"/>
|
||||
<item android:drawable="@drawable/bg_card_item_message_outgoing_longpressed_light"/>
|
||||
|
||||
</transition>
|
|
@ -2,6 +2,7 @@
|
|||
<org.mariotaku.twidere.view.MainFrameLayout
|
||||
android:id="@+id/home_content"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
|
@ -23,7 +24,9 @@
|
|||
style="?android:actionBarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?android:actionBarSize"
|
||||
android:layout_weight="0"/>
|
||||
android:layout_weight="0"
|
||||
app:tabExpandEnabled="true"
|
||||
app:tabHorizontalPadding="@dimen/element_spacing_normal"/>
|
||||
|
||||
<View
|
||||
android:id="@+id/actionbar_overlay"
|
||||
|
|
|
@ -25,13 +25,14 @@
|
|||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.astuetz.PagerSlidingTabStrip
|
||||
<org.mariotaku.twidere.view.TabPagerIndicator
|
||||
android:id="@+id/view_pager_tabs"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/element_size_normal"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
app:pstsTabBackground="?android:selectableItemBackground"
|
||||
app:pstsTabPaddingLeftRight="@dimen/element_spacing_large"/>
|
||||
app:tabHorizontalPadding="@dimen/element_spacing_large"
|
||||
app:tabExpandEnabled="false"
|
||||
app:tabIconColor="?android:colorForeground"/>
|
||||
|
||||
<android.support.v4.view.ViewPager
|
||||
android:id="@+id/view_pager"
|
||||
|
|
|
@ -112,13 +112,20 @@
|
|||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="@dimen/element_spacing_small"
|
||||
android:singleLine="true"
|
||||
android:text="@string/description"
|
||||
android:textAppearance="?android:textAppearanceMedium"/>
|
||||
android:textAllCaps="true"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textStyle="bold"/>
|
||||
|
||||
<org.mariotaku.twidere.view.HandleSpanClickTextView
|
||||
android:id="@+id/description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="@dimen/element_spacing_small"
|
||||
android:paddingRight="@dimen/element_spacing_small"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textColor="?android:textColorSecondary"/>
|
||||
</LinearLayout>
|
||||
|
@ -135,14 +142,20 @@
|
|||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="@dimen/element_spacing_small"
|
||||
android:singleLine="true"
|
||||
android:text="@string/location"
|
||||
android:textAppearance="?android:textAppearanceMedium"/>
|
||||
android:textAllCaps="true"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textStyle="bold"/>
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:id="@+id/location"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="@dimen/element_spacing_small"
|
||||
android:paddingRight="@dimen/element_spacing_small"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textColor="?android:textColorSecondary"/>
|
||||
|
@ -160,15 +173,21 @@
|
|||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="@dimen/element_spacing_small"
|
||||
android:singleLine="true"
|
||||
android:text="@string/url"
|
||||
android:textAppearance="?android:textAppearanceMedium"/>
|
||||
android:textAllCaps="true"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textStyle="bold"/>
|
||||
|
||||
<org.mariotaku.twidere.view.HandleSpanClickTextView
|
||||
android:id="@+id/url"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:autoLink="web"
|
||||
android:paddingLeft="@dimen/element_spacing_small"
|
||||
android:paddingRight="@dimen/element_spacing_small"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textColor="?android:textColorSecondary"/>
|
||||
|
@ -184,16 +203,22 @@
|
|||
android:padding="@dimen/element_spacing_small">
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="@dimen/element_spacing_small"
|
||||
android:singleLine="true"
|
||||
android:text="@string/created_at"
|
||||
android:textAppearance="?android:textAppearanceMedium"/>
|
||||
android:textAllCaps="true"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textStyle="bold"/>
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:id="@+id/created_at"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="@dimen/element_spacing_small"
|
||||
android:paddingRight="@dimen/element_spacing_small"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textColor="?android:textColorSecondary"/>
|
||||
|
@ -332,7 +357,7 @@
|
|||
android:alpha="0.2"
|
||||
android:gravity="center"
|
||||
android:padding="@dimen/element_spacing_small"
|
||||
android:text="- Luna meae es -"
|
||||
android:text="@string/uucky_footer_text"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="10sp"
|
||||
android:textStyle="italic"
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<view
|
||||
class="org.mariotaku.twidere.view.TabPagerIndicator$ItemLayout"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?android:selectableItemBackground">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/tab_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/tab_icon"
|
||||
android:layout_width="@dimen/action_icon_size"
|
||||
android:layout_height="@dimen/action_icon_size"
|
||||
android:contentDescription="@string/icon"
|
||||
android:scaleType="centerInside"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tab_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAllCaps="true"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textStyle="bold"/>
|
||||
</LinearLayout>
|
||||
|
||||
<org.mariotaku.twidere.view.BadgeView
|
||||
android:id="@+id/unread_indicator"
|
||||
android:layout_width="@dimen/unread_indicator_size"
|
||||
android:layout_height="@dimen/unread_indicator_size"
|
||||
android:layout_alignRight="@+id/tab_content"
|
||||
android:layout_alignTop="@+id/tab_content"
|
||||
android:layout_marginRight="@dimen/element_spacing_minus_small"
|
||||
android:layout_marginTop="@dimen/element_spacing_minus_small"
|
||||
android:background="@drawable/bg_unread_indicator"
|
||||
android:ellipsize="none"
|
||||
android:gravity="center"
|
||||
android:padding="@dimen/element_spacing_xsmall"
|
||||
android:singleLine="true"
|
||||
android:textColor="?android:textColorPrimary"/>
|
||||
|
||||
|
||||
</view>
|
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<me.imid.swipebacklayout.lib.SwipeBackLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/swipe"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?android:selectableItemBackground">
|
||||
|
||||
<View
|
||||
android:id="@+id/selected_indicator"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:background="?android:activatedBackgroundIndicator"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/tab_icon"
|
||||
android:layout_width="@dimen/action_icon_size"
|
||||
android:layout_height="@dimen/action_icon_size"
|
||||
android:layout_centerInParent="true"
|
||||
android:scaleType="centerInside"/>
|
||||
|
||||
<org.mariotaku.twidere.view.BadgeView
|
||||
android:id="@+id/unread_indicator"
|
||||
android:layout_width="@dimen/unread_indicator_size"
|
||||
android:layout_height="@dimen/unread_indicator_size"
|
||||
android:layout_alignRight="@+id/tab_icon"
|
||||
android:layout_alignTop="@+id/tab_icon"
|
||||
android:layout_marginRight="@dimen/element_spacing_minus_small"
|
||||
android:layout_marginTop="@dimen/element_spacing_minus_small"
|
||||
android:background="@drawable/bg_unread_indicator"
|
||||
android:ellipsize="none"
|
||||
android:gravity="center"
|
||||
android:padding="@dimen/element_spacing_xsmall"
|
||||
android:singleLine="true"
|
||||
android:textColor="?android:textColorPrimary"/>
|
||||
|
||||
|
||||
</RelativeLayout>
|
|
@ -29,6 +29,7 @@
|
|||
<autoTransition>
|
||||
<targets>
|
||||
<target android:targetId="@id/profile_banner"/>
|
||||
<target android:targetId="@id/view_pager_tabs"/>
|
||||
</targets>
|
||||
</autoTransition>
|
||||
</transitionSet>
|
|
@ -11,10 +11,6 @@
|
|||
<attr name="messageBubbleColor" format="color"/>
|
||||
<attr name="cardItemBackground" format="reference"/>
|
||||
<attr name="cardItemBackgroundColor" format="color"/>
|
||||
<attr name="cardItemMessageIncomingBackground" format="reference"/>
|
||||
<attr name="cardItemMessageOutgoingBackground" format="reference"/>
|
||||
<attr name="cardItemMessageProfileImageIncomingBackground" format="reference"/>
|
||||
<attr name="cardItemMessageProfileImageOutgoingBackground" format="reference"/>
|
||||
<attr name="listMenuOverflowButton" format="reference"/>
|
||||
<attr name="ignorePadding" format="boolean"/>
|
||||
<attr name="linePageIndicatorStyle" format="reference"/>
|
||||
|
@ -32,9 +28,12 @@
|
|||
<attr name="cardGapTextSize" format="dimension"/>
|
||||
</declare-styleable>
|
||||
<declare-styleable name="TabPagerIndicator">
|
||||
<attr name="tabItemStyle" format="reference"/>
|
||||
<attr name="tabItemContentStyle" format="reference"/>
|
||||
<attr name="tabItemTextStyle" format="reference"/>
|
||||
<attr name="tabStripColor" format="color"/>
|
||||
<attr name="tabIconColor" format="color"/>
|
||||
<attr name="tabHorizontalPadding" format="dimension"/>
|
||||
<attr name="tabVerticalPadding" format="dimension"/>
|
||||
<attr name="tabExpandEnabled" format="boolean"/>
|
||||
<attr name="tabDisplayOption"/>
|
||||
</declare-styleable>
|
||||
<declare-styleable name="LinePageIndicator">
|
||||
<!-- Whether or not the indicators should be centered. -->
|
||||
|
@ -94,5 +93,8 @@
|
|||
<flag name="vibration" value="2"/>
|
||||
<flag name="light" value="4"/>
|
||||
</attr>
|
||||
|
||||
<attr name="tabDisplayOption">
|
||||
<flag name="label" value="0x1"/>
|
||||
<flag name="icon" value="0x2"/>
|
||||
</attr>
|
||||
</resources>
|
|
@ -12,5 +12,6 @@
|
|||
<string name="font_family_light" translatable="false">Light</string>
|
||||
<string name="font_family_thin" translatable="false">Thin</string>
|
||||
<string name="easter_egg_triggered_message" translatable="false">不二对你的膝盖发动了会心一击!</string>
|
||||
<string name="uucky_footer_text">- Luna meae es -</string>
|
||||
|
||||
</resources>
|
|
@ -30,27 +30,12 @@
|
|||
</item>
|
||||
|
||||
<!-- Custom view styles -->
|
||||
<item name="tabItemStyle">@style/Widget.TabPageIndicator.TabItem</item>
|
||||
<item name="tabItemContentStyle">@style/Widget.TabPageIndicator.TabItem.Content</item>
|
||||
<item name="tabItemTextStyle">@style/Widget.TabPageIndicator.TabItem.TextView.Dark</item>
|
||||
|
||||
<!-- Card UI styles -->
|
||||
<item name="cardActionButtonStyle">@style/Widget.CardActionButton</item>
|
||||
<item name="profileImageStyleLarge">@style/Widget.ProfileImage.Large</item>
|
||||
<item name="cardItemBackground">@drawable/bg_card_item_dark</item>
|
||||
<item name="cardItemBackgroundColor">#1a1a1a</item>
|
||||
<item name="cardItemMessageIncomingBackground">
|
||||
@drawable/bg_card_item_message_incoming_dark
|
||||
</item>
|
||||
<item name="cardItemMessageOutgoingBackground">
|
||||
@drawable/bg_card_item_message_outgoing_dark
|
||||
</item>
|
||||
<item name="cardItemMessageProfileImageIncomingBackground">
|
||||
@drawable/bg_card_item_message_profile_image_incoming_dark
|
||||
</item>
|
||||
<item name="cardItemMessageProfileImageOutgoingBackground">
|
||||
@drawable/bg_card_item_message_profile_image_outgoing_dark
|
||||
</item>
|
||||
<item name="listMenuOverflowButton">@drawable/ic_list_menu_moreoverflow_normal_holo_dark
|
||||
</item>
|
||||
<item name="cardItemViewStyle">@style/Widget.CardItemView</item>
|
||||
|
@ -75,33 +60,15 @@
|
|||
<!--<item name="android:actionBarWidgetTheme">@style/Theme.Twidere.Dark</item>-->
|
||||
|
||||
<!-- Custom view styles -->
|
||||
<item name="tabItemStyle">@style/Widget.TabPageIndicator.TabItem</item>
|
||||
<item name="tabItemContentStyle">@style/Widget.TabPageIndicator.TabItem.Content</item>
|
||||
<item name="tabItemTextStyle">
|
||||
@style/Widget.TabPageIndicator.TabItem.TextView.Light.DarkActionBar
|
||||
</item>
|
||||
|
||||
<!-- Card UI styles -->
|
||||
<item name="cardActionButtonStyle">@style/Widget.Light.CardActionButton</item>
|
||||
<item name="profileImageStyleLarge">@style/Widget.Light.ProfileImage.Large</item>
|
||||
<item name="cardItemBackground">@drawable/bg_card_item_light</item>
|
||||
<item name="cardItemBackgroundColor">#f8f8f8</item>
|
||||
<item name="cardItemMessageIncomingBackground">
|
||||
@drawable/bg_card_item_message_incoming_light
|
||||
</item>
|
||||
<item name="cardItemMessageOutgoingBackground">
|
||||
@drawable/bg_card_item_message_outgoing_light
|
||||
</item>
|
||||
<item name="cardItemMessageProfileImageIncomingBackground">
|
||||
@drawable/bg_card_item_message_profile_image_incoming_light
|
||||
</item>
|
||||
<item name="cardItemMessageProfileImageOutgoingBackground">
|
||||
@drawable/bg_card_item_message_profile_image_outgoing_light
|
||||
</item>
|
||||
<item name="listMenuOverflowButton">@drawable/ic_list_menu_moreoverflow_normal_holo_light
|
||||
</item>
|
||||
<item name="cardItemViewStyle">@style/Widget.CardItemView.Light</item>
|
||||
|
||||
<!-- Twidere specific styles -->
|
||||
<item name="menuIconColor">@color/action_icon_dark</item>
|
||||
<item name="menuIconColorDisabled">@color/action_icon_dark_disabled</item>
|
||||
|
@ -153,27 +120,13 @@
|
|||
<style name="Theme.Twidere.Dark.Dialog" parent="Theme.Base.Dialog">
|
||||
|
||||
<!-- Custom view styles -->
|
||||
<item name="tabItemStyle">@style/Widget.TabPageIndicator.TabItem</item>
|
||||
<item name="tabItemContentStyle">@style/Widget.TabPageIndicator.TabItem.Content</item>
|
||||
<item name="tabItemTextStyle">@style/Widget.TabPageIndicator.TabItem.TextView</item>
|
||||
|
||||
<!-- Card UI styles -->
|
||||
<item name="cardActionButtonStyle">@style/Widget.CardActionButton</item>
|
||||
<item name="profileImageStyleLarge">@style/Widget.ProfileImage.Large</item>
|
||||
<item name="cardItemBackground">@drawable/bg_card_item_dark</item>
|
||||
<item name="cardItemBackgroundColor">#1a1a1a</item>
|
||||
<item name="cardItemMessageIncomingBackground">
|
||||
@drawable/bg_card_item_message_incoming_dark
|
||||
</item>
|
||||
<item name="cardItemMessageOutgoingBackground">
|
||||
@drawable/bg_card_item_message_outgoing_dark
|
||||
</item>
|
||||
<item name="cardItemMessageProfileImageIncomingBackground">
|
||||
@drawable/bg_card_item_message_profile_image_incoming_dark
|
||||
</item>
|
||||
<item name="cardItemMessageProfileImageOutgoingBackground">
|
||||
@drawable/bg_card_item_message_profile_image_outgoing_dark
|
||||
</item>
|
||||
|
||||
<item name="listMenuOverflowButton">@drawable/ic_list_menu_moreoverflow_normal_holo_dark
|
||||
</item>
|
||||
<item name="cardItemViewStyle">@style/Widget.CardItemView</item>
|
||||
|
@ -187,27 +140,13 @@
|
|||
<style name="Theme.Twidere.Light.Dialog" parent="Theme.Base.Light.Dialog">
|
||||
|
||||
<!-- Custom view styles -->
|
||||
<item name="tabItemStyle">@style/Widget.TabPageIndicator.TabItem</item>
|
||||
<item name="tabItemContentStyle">@style/Widget.TabPageIndicator.TabItem.Content</item>
|
||||
<item name="tabItemTextStyle">@style/Widget.TabPageIndicator.TabItem.TextView</item>
|
||||
|
||||
<!-- Card UI styles -->
|
||||
<item name="cardActionButtonStyle">@style/Widget.Light.CardActionButton</item>
|
||||
<item name="profileImageStyleLarge">@style/Widget.Light.ProfileImage.Large</item>
|
||||
<item name="cardItemBackground">@drawable/bg_card_item_light</item>
|
||||
<item name="cardItemBackgroundColor">#f8f8f8</item>
|
||||
<item name="cardItemMessageIncomingBackground">
|
||||
@drawable/bg_card_item_message_incoming_light
|
||||
</item>
|
||||
<item name="cardItemMessageOutgoingBackground">
|
||||
@drawable/bg_card_item_message_outgoing_light
|
||||
</item>
|
||||
<item name="cardItemMessageProfileImageIncomingBackground">
|
||||
@drawable/bg_card_item_message_profile_image_incoming_light
|
||||
</item>
|
||||
<item name="cardItemMessageProfileImageOutgoingBackground">
|
||||
@drawable/bg_card_item_message_profile_image_outgoing_light
|
||||
</item>
|
||||
|
||||
<item name="listMenuOverflowButton">@drawable/ic_list_menu_moreoverflow_normal_holo_light
|
||||
</item>
|
||||
<item name="cardItemViewStyle">@style/Widget.CardItemView.Light</item>
|
||||
|
@ -258,18 +197,6 @@
|
|||
<item name="profileImageStyleLarge">@style/Widget.ProfileImage.Large</item>
|
||||
<item name="cardItemBackground">@drawable/bg_card_item_dark</item>
|
||||
<item name="cardItemBackgroundColor">#1a1a1a</item>
|
||||
<item name="cardItemMessageIncomingBackground">
|
||||
@drawable/bg_card_item_message_incoming_dark
|
||||
</item>
|
||||
<item name="cardItemMessageOutgoingBackground">
|
||||
@drawable/bg_card_item_message_outgoing_dark
|
||||
</item>
|
||||
<item name="cardItemMessageProfileImageIncomingBackground">
|
||||
@drawable/bg_card_item_message_profile_image_incoming_dark
|
||||
</item>
|
||||
<item name="cardItemMessageProfileImageOutgoingBackground">
|
||||
@drawable/bg_card_item_message_profile_image_outgoing_dark
|
||||
</item>
|
||||
<item name="listMenuOverflowButton">@drawable/ic_list_menu_moreoverflow_normal_holo_dark
|
||||
</item>
|
||||
<item name="cardItemViewStyle">@style/Widget.CardItemView</item>
|
||||
|
@ -351,27 +278,12 @@
|
|||
</item>
|
||||
|
||||
<!-- Custom view styles -->
|
||||
<item name="tabItemStyle">@style/Widget.TabPageIndicator.TabItem</item>
|
||||
<item name="tabItemContentStyle">@style/Widget.TabPageIndicator.TabItem.Content</item>
|
||||
<item name="tabItemTextStyle">@style/Widget.TabPageIndicator.TabItem.TextView.Dark</item>
|
||||
|
||||
<!-- Card UI styles -->
|
||||
<item name="cardActionButtonStyle">@style/Widget.CardActionButton</item>
|
||||
<item name="profileImageStyleLarge">@style/Widget.ProfileImage.Large</item>
|
||||
<item name="cardItemBackground">@drawable/bg_card_item_dark</item>
|
||||
<item name="cardItemBackgroundColor">#1a1a1a</item>
|
||||
<item name="cardItemMessageIncomingBackground">
|
||||
@drawable/bg_card_item_message_incoming_dark
|
||||
</item>
|
||||
<item name="cardItemMessageOutgoingBackground">
|
||||
@drawable/bg_card_item_message_outgoing_dark
|
||||
</item>
|
||||
<item name="cardItemMessageProfileImageIncomingBackground">
|
||||
@drawable/bg_card_item_message_profile_image_incoming_dark
|
||||
</item>
|
||||
<item name="cardItemMessageProfileImageOutgoingBackground">
|
||||
@drawable/bg_card_item_message_profile_image_outgoing_dark
|
||||
</item>
|
||||
<item name="listMenuOverflowButton">@drawable/ic_list_menu_moreoverflow_normal_holo_dark
|
||||
</item>
|
||||
<item name="cardItemViewStyle">@style/Widget.CardItemView</item>
|
||||
|
@ -392,27 +304,12 @@
|
|||
<!--<item name="android:windowBackground">@color/bg_color_light</item>-->
|
||||
|
||||
<!-- Custom view styles -->
|
||||
<item name="tabItemStyle">@style/Widget.TabPageIndicator.TabItem</item>
|
||||
<item name="tabItemContentStyle">@style/Widget.TabPageIndicator.TabItem.Content</item>
|
||||
<item name="tabItemTextStyle">@style/Widget.TabPageIndicator.TabItem.TextView.Light</item>
|
||||
|
||||
<!-- Card UI styles -->
|
||||
<item name="cardActionButtonStyle">@style/Widget.Light.CardActionButton</item>
|
||||
<item name="profileImageStyleLarge">@style/Widget.Light.ProfileImage.Large</item>
|
||||
<item name="cardItemBackground">@drawable/bg_card_item_light</item>
|
||||
<item name="cardItemBackgroundColor">#f8f8f8</item>
|
||||
<item name="cardItemMessageIncomingBackground">
|
||||
@drawable/bg_card_item_message_incoming_light
|
||||
</item>
|
||||
<item name="cardItemMessageOutgoingBackground">
|
||||
@drawable/bg_card_item_message_outgoing_light
|
||||
</item>
|
||||
<item name="cardItemMessageProfileImageIncomingBackground">
|
||||
@drawable/bg_card_item_message_profile_image_incoming_light
|
||||
</item>
|
||||
<item name="cardItemMessageProfileImageOutgoingBackground">
|
||||
@drawable/bg_card_item_message_profile_image_outgoing_light
|
||||
</item>
|
||||
<item name="listMenuOverflowButton">@drawable/ic_list_menu_moreoverflow_normal_holo_light
|
||||
</item>
|
||||
<item name="cardItemViewStyle">@style/Widget.CardItemView.Light</item>
|
||||
|
@ -433,27 +330,12 @@
|
|||
<!--<item name="android:windowBackground">@color/bg_color_light</item>-->
|
||||
|
||||
<!-- Custom view styles -->
|
||||
<item name="tabItemStyle">@style/Widget.TabPageIndicator.TabItem</item>
|
||||
<item name="tabItemContentStyle">@style/Widget.TabPageIndicator.TabItem.Content</item>
|
||||
<item name="tabItemTextStyle">@style/Widget.TabPageIndicator.TabItem.TextView.Light</item>
|
||||
|
||||
<!-- Card UI styles -->
|
||||
<item name="cardActionButtonStyle">@style/Widget.Light.CardActionButton</item>
|
||||
<item name="profileImageStyleLarge">@style/Widget.Light.ProfileImage.Large</item>
|
||||
<item name="cardItemBackground">@drawable/bg_card_item_light</item>
|
||||
<item name="cardItemBackgroundColor">#f8f8f8</item>
|
||||
<item name="cardItemMessageIncomingBackground">
|
||||
@drawable/bg_card_item_message_incoming_light
|
||||
</item>
|
||||
<item name="cardItemMessageOutgoingBackground">
|
||||
@drawable/bg_card_item_message_outgoing_light
|
||||
</item>
|
||||
<item name="cardItemMessageProfileImageIncomingBackground">
|
||||
@drawable/bg_card_item_message_profile_image_incoming_light
|
||||
</item>
|
||||
<item name="cardItemMessageProfileImageOutgoingBackground">
|
||||
@drawable/bg_card_item_message_profile_image_outgoing_light
|
||||
</item>
|
||||
<item name="listMenuOverflowButton">@drawable/ic_list_menu_moreoverflow_normal_holo_light
|
||||
</item>
|
||||
<item name="cardItemViewStyle">@style/Widget.CardItemView.Light</item>
|
||||
|
|