better status viewer adapter

This commit is contained in:
Mariotaku Lee 2015-09-24 14:50:36 +08:00
parent 5287eb17e8
commit 68039a10ec
4 changed files with 121 additions and 34 deletions

View File

@ -86,7 +86,6 @@ response = None
try: try:
response = urllib2.urlopen(request) response = urllib2.urlopen(request)
except HTTPError, err: except HTTPError, err:
print(err.code)
if err.code == 404: if err.code == 404:
print('Creating release for tag %s' % current_tag) print('Creating release for tag %s' % current_tag)
request = urllib2.Request( request = urllib2.Request(

View File

@ -134,6 +134,13 @@ public class TwitterLinkHandlerActivity extends Activity implements Constants {
handledIntent.putExtra(Intent.EXTRA_TEXT, Utils.getShareStatus(this, text, url)); handledIntent.putExtra(Intent.EXTRA_TEXT, Utils.getShareStatus(this, text, url));
return Pair.create(handledIntent, true); return Pair.create(handledIntent, true);
} }
case "search": {
final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE);
builder.authority(AUTHORITY_SEARCH);
builder.appendQueryParameter(QUERY_PARAM_QUERY, uri.getQueryParameter("q"));
return Pair.create(new Intent(Intent.ACTION_VIEW, builder.build()), true);
}
case "following": { case "following": {
final Uri.Builder builder = new Uri.Builder(); final Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_TWIDERE); builder.scheme(SCHEME_TWIDERE);

View File

@ -95,6 +95,7 @@ import org.mariotaku.twidere.util.CompareUtils;
import org.mariotaku.twidere.util.KeyboardShortcutsHandler; import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback; import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback;
import org.mariotaku.twidere.util.LinkCreator; import org.mariotaku.twidere.util.LinkCreator;
import org.mariotaku.twidere.util.MathUtils;
import org.mariotaku.twidere.util.MediaLoaderWrapper; import org.mariotaku.twidere.util.MediaLoaderWrapper;
import org.mariotaku.twidere.util.MediaLoadingHandler; import org.mariotaku.twidere.util.MediaLoadingHandler;
import org.mariotaku.twidere.util.RecyclerViewNavigationHelper; import org.mariotaku.twidere.util.RecyclerViewNavigationHelper;
@ -165,6 +166,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
private LoaderCallbacks<List<ParcelableStatus>> mRepliesLoaderCallback = new LoaderCallbacks<List<ParcelableStatus>>() { private LoaderCallbacks<List<ParcelableStatus>> mRepliesLoaderCallback = new LoaderCallbacks<List<ParcelableStatus>>() {
@Override @Override
public Loader<List<ParcelableStatus>> onCreateLoader(int id, Bundle args) { public Loader<List<ParcelableStatus>> onCreateLoader(int id, Bundle args) {
mStatusAdapter.setRepliesLoading(true);
mStatusAdapter.updateItemDecoration(); mStatusAdapter.updateItemDecoration();
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1); final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
final String screenName = args.getString(EXTRA_SCREEN_NAME); final String screenName = args.getString(EXTRA_SCREEN_NAME);
@ -180,6 +182,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
@Override @Override
public void onLoadFinished(Loader<List<ParcelableStatus>> loader, List<ParcelableStatus> data) { public void onLoadFinished(Loader<List<ParcelableStatus>> loader, List<ParcelableStatus> data) {
mStatusAdapter.setRepliesLoading(false);
mStatusAdapter.updateItemDecoration(); mStatusAdapter.updateItemDecoration();
final Pair<Long, Integer> readPosition = saveReadPosition(); final Pair<Long, Integer> readPosition = saveReadPosition();
setReplies(data); setReplies(data);
@ -968,8 +971,15 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
return ListResponse.getListInstance(list); return ListResponse.getListInstance(list);
} }
@Override
protected void onPreExecute() {
super.onPreExecute();
fragment.getAdapter().setConversationsLoading(true);
}
@Override @Override
protected void onPostExecute(final ListResponse<ParcelableStatus> data) { protected void onPostExecute(final ListResponse<ParcelableStatus> data) {
fragment.getAdapter().setConversationsLoading(false);
if (data.hasData()) { if (data.hasData()) {
fragment.setConversation(data.getData()); fragment.setConversation(data.getData());
} else { } else {
@ -1043,6 +1053,18 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
private final MediaLoadingHandler mMediaLoadingHandler; private final MediaLoadingHandler mMediaLoadingHandler;
private final TwidereLinkify mTwidereLinkify; private final TwidereLinkify mTwidereLinkify;
private static final int ITEM_IDX_CONVERSATION_ERROR = 0;
private static final int ITEM_IDX_CONVERSATION_LOAD_MORE = 1;
private static final int ITEM_IDX_CONVERSATION = 2;
private static final int ITEM_IDX_STATUS = 3;
private static final int ITEM_IDX_REPLY = 4;
private static final int ITEM_IDX_REPLY_LOAD_MORE = 5;
private static final int ITEM_IDX_REPLY_ERROR = 6;
private static final int ITEM_IDX_SPACE = 7;
private static final int ITEM_TYPES_SUM = 8;
private final int[] mItemCounts;
private final boolean mNameFirst; private final boolean mNameFirst;
private final int mCardLayoutResource; private final int mCardLayoutResource;
private final int mTextSize; private final int mTextSize;
@ -1072,6 +1094,9 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
final Resources res = context.getResources(); final Resources res = context.getResources();
final SharedPreferencesWrapper preferences = SharedPreferencesWrapper.getInstance(context, final SharedPreferencesWrapper preferences = SharedPreferencesWrapper.getInstance(context,
SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
mItemCounts = new int[ITEM_TYPES_SUM];
// There's always a space at the end of the list
mItemCounts[ITEM_IDX_SPACE] = 1;
mFragment = fragment; mFragment = fragment;
mContext = context; mContext = context;
mInflater = LayoutInflater.from(context); mInflater = LayoutInflater.from(context);
@ -1102,6 +1127,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
mConversation = new ArrayList<>(); mConversation = new ArrayList<>();
} }
mConversation.add(position, status); mConversation.add(position, status);
mItemCounts[ITEM_IDX_CONVERSATION] = mConversation.size();
notifyDataSetChanged(); notifyDataSetChanged();
updateItemDecoration(); updateItemDecoration();
} }
@ -1162,16 +1188,24 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
@Override @Override
public ParcelableStatus getStatus(int position) { public ParcelableStatus getStatus(int position) {
final int conversationCount = getConversationCount(); final int itemStart = getItemTypeStart(position);
if (position == getItemCount() - 1) { final int itemType = getItemType(position);
return null; return getStatusByItemType(position, itemStart, itemType);
} else if (position < conversationCount) { }
return mConversation != null ? mConversation.get(position) : null;
} else if (position > conversationCount) { private ParcelableStatus getStatusByItemType(int position, int itemStart, int itemType) {
return mReplies != null ? mReplies.get(position - conversationCount - 1) : null; switch (itemType) {
} else { case ITEM_IDX_CONVERSATION: {
return mStatus; return mConversation != null ? mConversation.get(position - itemStart) : null;
}
case ITEM_IDX_REPLY: {
return mReplies != null ? mReplies.get(position - itemStart) : null;
}
case ITEM_IDX_STATUS: {
return mStatus;
}
} }
return null;
} }
@Override @Override
@ -1182,7 +1216,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
@Override @Override
public int getStatusesCount() { public int getStatusesCount() {
return getConversationCount() + 1 + getRepliesCount() + 1; return mItemCounts[ITEM_IDX_CONVERSATION] + mItemCounts[ITEM_IDX_STATUS] + mItemCounts[ITEM_IDX_REPLY];
} }
@Override @Override
@ -1354,7 +1388,9 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
@Override @Override
public void onBindViewHolder(ViewHolder holder, int position) { public void onBindViewHolder(ViewHolder holder, int position) {
switch (getItemViewType(position)) { final int itemType = getItemType(position);
final int itemViewType = getItemViewTypeByItemType(itemType);
switch (itemViewType) {
case VIEW_TYPE_DETAIL_STATUS: { case VIEW_TYPE_DETAIL_STATUS: {
final ParcelableStatus status = getStatus(position); final ParcelableStatus status = getStatus(position);
final DetailStatusViewHolder detailHolder = (DetailStatusViewHolder) holder; final DetailStatusViewHolder detailHolder = (DetailStatusViewHolder) holder;
@ -1366,7 +1402,9 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
final StatusViewHolder statusHolder = (StatusViewHolder) holder; final StatusViewHolder statusHolder = (StatusViewHolder) holder;
// Display 'in reply to' for first item // Display 'in reply to' for first item
// useful to indicate whether first tweet has reply or not // useful to indicate whether first tweet has reply or not
statusHolder.displayStatus(status, position == 0); // We only display that indicator for first conversation item
statusHolder.displayStatus(status, itemType == ITEM_IDX_CONVERSATION
&& (position - getItemTypeStart(position)) == 0);
break; break;
} }
} }
@ -1374,36 +1412,58 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
@Override @Override
public int getItemViewType(int position) { public int getItemViewType(int position) {
final int conversationCount = getConversationCount(); return getItemViewTypeByItemType(getItemType(position));
if (position == getItemCount() - 1) { }
// Space is always the last item
return VIEW_TYPE_SPACE; private int getItemViewTypeByItemType(int type) {
} else if (position < conversationCount) { switch (type) {
return mConversation != null ? VIEW_TYPE_LIST_STATUS : VIEW_TYPE_CONVERSATION_LOAD_INDICATOR; case ITEM_IDX_CONVERSATION:
} else if (position > conversationCount) { case ITEM_IDX_REPLY:
return mReplies != null ? VIEW_TYPE_LIST_STATUS : VIEW_TYPE_REPLIES_LOAD_INDICATOR; return VIEW_TYPE_LIST_STATUS;
} else { case ITEM_IDX_CONVERSATION_LOAD_MORE:
return VIEW_TYPE_DETAIL_STATUS; return VIEW_TYPE_CONVERSATION_LOAD_INDICATOR;
case ITEM_IDX_REPLY_LOAD_MORE:
return VIEW_TYPE_REPLIES_LOAD_INDICATOR;
case ITEM_IDX_STATUS:
return VIEW_TYPE_DETAIL_STATUS;
case ITEM_IDX_SPACE:
return VIEW_TYPE_SPACE;
} }
throw new IllegalStateException();
}
private int getItemType(int position) {
int typeStart = 0;
for (int type = 0; type < ITEM_TYPES_SUM; type++) {
int typeCount = mItemCounts[type];
final int typeEnd = typeStart + typeCount;
if (position >= typeStart && position < typeEnd) return type;
typeStart = typeEnd;
}
throw new IllegalStateException();
}
private int getItemTypeStart(int position) {
int typeStart = 0;
for (int type = 0; type < ITEM_TYPES_SUM; type++) {
int typeCount = mItemCounts[type];
final int typeEnd = typeStart + typeCount;
if (position >= typeStart && position < typeEnd) return typeStart;
typeStart = typeEnd;
}
throw new IllegalStateException();
} }
@Override @Override
public long getItemId(int position) { public long getItemId(int position) {
final int conversationCount = getConversationCount(); final ParcelableStatus status = getStatus(position);
if (position == getItemCount() - 1) { if (status != null) return status.id;
return VIEW_TYPE_SPACE; return getItemType(position) * 100 + position;
} else if (position < conversationCount) {
return mConversation != null ? mConversation.get(position).id : VIEW_TYPE_CONVERSATION_LOAD_INDICATOR;
} else if (position > conversationCount) {
return mReplies != null ? mReplies.get(position - conversationCount - 1).id : VIEW_TYPE_REPLIES_LOAD_INDICATOR;
} else {
return mStatus != null ? mStatus.id : VIEW_TYPE_DETAIL_STATUS;
}
} }
@Override @Override
public int getItemCount() { public int getItemCount() {
return getStatusesCount(); return MathUtils.sum(mItemCounts);
} }
@Override @Override
@ -1469,6 +1529,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
public void setConversation(List<ParcelableStatus> conversation) { public void setConversation(List<ParcelableStatus> conversation) {
mConversation = conversation; mConversation = conversation;
mItemCounts[ITEM_IDX_CONVERSATION] = conversation != null ? conversation.size() : 0;
notifyDataSetChanged(); notifyDataSetChanged();
updateItemDecoration(); updateItemDecoration();
} }
@ -1479,6 +1540,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
public void setReplies(List<ParcelableStatus> replies) { public void setReplies(List<ParcelableStatus> replies) {
mReplies = replies; mReplies = replies;
mItemCounts[ITEM_IDX_REPLY] = replies != null ? replies.size() : 0;
notifyDataSetChanged(); notifyDataSetChanged();
updateItemDecoration(); updateItemDecoration();
} }
@ -1486,6 +1548,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
public boolean setStatus(final ParcelableStatus status, final ParcelableCredentials credentials) { public boolean setStatus(final ParcelableStatus status, final ParcelableCredentials credentials) {
final ParcelableStatus old = mStatus; final ParcelableStatus old = mStatus;
mStatus = status; mStatus = status;
mItemCounts[ITEM_IDX_STATUS] = status != null ? 1 : 0;
mStatusAccount = credentials; mStatusAccount = credentials;
notifyDataSetChanged(); notifyDataSetChanged();
updateItemDecoration(); updateItemDecoration();
@ -1515,6 +1578,16 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
} }
mRecyclerView.invalidateItemDecorations(); mRecyclerView.invalidateItemDecorations();
} }
public void setRepliesLoading(boolean loading) {
mItemCounts[ITEM_IDX_REPLY_LOAD_MORE] = loading ? 1 : 0;
notifyDataSetChanged();
}
public void setConversationsLoading(boolean loading) {
mItemCounts[ITEM_IDX_CONVERSATION_LOAD_MORE] = loading ? 1 : 0;
notifyDataSetChanged();
}
} }
private static class StatusListLinearLayoutManager extends FixedLinearLayoutManager { private static class StatusListLinearLayoutManager extends FixedLinearLayoutManager {

View File

@ -60,4 +60,12 @@ public class MathUtils {
} }
return sum; return sum;
} }
public static int sum(int[] ints) {
int sum = 0;
for (int i : ints) {
sum += i;
}
return sum;
}
} }