mirror of
https://github.com/TwidereProject/Twidere-Android
synced 2025-02-07 23:38:40 +01:00
implementing group
This commit is contained in:
parent
877e5296a6
commit
cb675ec7bc
@ -2,22 +2,19 @@ package org.mariotaku.twidere.model;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.bluelinelabs.logansquare.annotation.JsonField;
|
||||
import com.bluelinelabs.logansquare.annotation.JsonObject;
|
||||
import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease;
|
||||
import com.hannesdorfmann.parcelableplease.annotation.ParcelableThisPlease;
|
||||
|
||||
import org.mariotaku.twidere.api.twitter.util.TwitterDateConverter;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/3/9.
|
||||
*/
|
||||
@ParcelablePlease
|
||||
@JsonObject
|
||||
public class ParcelableGroup implements Parcelable {
|
||||
public class ParcelableGroup implements Parcelable, Comparable<ParcelableGroup> {
|
||||
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "account_key")
|
||||
@ -45,6 +42,10 @@ public class ParcelableGroup implements Parcelable {
|
||||
@JsonField(name = "location")
|
||||
public String location;
|
||||
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "position")
|
||||
public long position;
|
||||
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "created")
|
||||
public long created;
|
||||
@ -123,4 +124,9 @@ public class ParcelableGroup implements Parcelable {
|
||||
return new ParcelableGroup[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public int compareTo(@NonNull ParcelableGroup another) {
|
||||
return (int) (this.position - another.position);
|
||||
}
|
||||
}
|
||||
|
@ -82,10 +82,7 @@ public class ParcelableUserList implements Parcelable, Comparable<ParcelableUser
|
||||
|
||||
@Override
|
||||
public int compareTo(@NonNull final ParcelableUserList another) {
|
||||
final long diff = position - another.position;
|
||||
if (diff > Integer.MAX_VALUE) return Integer.MAX_VALUE;
|
||||
if (diff < Integer.MIN_VALUE) return Integer.MIN_VALUE;
|
||||
return (int) diff;
|
||||
return (int) (position - another.position);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,9 +1,24 @@
|
||||
package org.mariotaku.twidere.fragment.support;
|
||||
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.content.Loader;
|
||||
|
||||
import org.mariotaku.twidere.loader.support.UserGroupsLoader;
|
||||
import org.mariotaku.twidere.model.ParcelableGroup;
|
||||
import org.mariotaku.twidere.model.UserKey;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/3/9.
|
||||
*/
|
||||
public class UserGroupsFragment extends Fragment {
|
||||
public class UserGroupsFragment extends ParcelableGroupsFragment {
|
||||
@Override
|
||||
protected Loader<List<ParcelableGroup>> onCreateUserListsLoader(Context context, Bundle args, boolean fromUser) {
|
||||
final UserKey accountKey = args.getParcelable(EXTRA_ACCOUNT_KEY);
|
||||
final long userId = args.getLong(EXTRA_USER_ID, -1);
|
||||
final String screenName = args.getString(EXTRA_SCREEN_NAME);
|
||||
return new UserGroupsLoader(context, accountKey, userId, screenName, getData());
|
||||
}
|
||||
}
|
||||
|
@ -429,6 +429,10 @@ public class LinkHandlerActivity extends BaseAppCompatActivity implements System
|
||||
setTitle(R.string.user_lists);
|
||||
break;
|
||||
}
|
||||
case LINK_ID_USER_GROUPS: {
|
||||
setTitle(R.string.groups);
|
||||
break;
|
||||
}
|
||||
case LINK_ID_USER_LIST_TIMELINE: {
|
||||
setTitle(R.string.list_timeline);
|
||||
break;
|
||||
|
@ -1,156 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.RecyclerView.ViewHolder;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.iface.IUsersAdapter;
|
||||
import org.mariotaku.twidere.util.ThemeUtils;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.view.holder.LoadIndicatorViewHolder;
|
||||
import org.mariotaku.twidere.view.holder.UserViewHolder;
|
||||
|
||||
public abstract class AbsUsersAdapter<D> extends LoadMoreSupportAdapter<ViewHolder> implements Constants,
|
||||
IUsersAdapter<D> {
|
||||
|
||||
public static final int ITEM_VIEW_TYPE_USER = 2;
|
||||
|
||||
private final LayoutInflater mInflater;
|
||||
|
||||
private final int mCardBackgroundColor;
|
||||
private final int mProfileImageStyle;
|
||||
private final int mTextSize;
|
||||
private final boolean mDisplayProfileImage;
|
||||
private final boolean mShowAbsoluteTime;
|
||||
private UserAdapterListener mUserAdapterListener;
|
||||
private RequestClickListener mRequestClickListener;
|
||||
|
||||
public AbsUsersAdapter(final Context context) {
|
||||
super(context);
|
||||
mCardBackgroundColor = ThemeUtils.getCardBackgroundColor(context, ThemeUtils.getThemeBackgroundOption(context), ThemeUtils.getUserThemeBackgroundAlpha(context));
|
||||
mInflater = LayoutInflater.from(context);
|
||||
mTextSize = mPreferences.getInt(KEY_TEXT_SIZE, context.getResources().getInteger(R.integer.default_text_size));
|
||||
mProfileImageStyle = Utils.getProfileImageStyle(mPreferences.getString(KEY_PROFILE_IMAGE_STYLE, null));
|
||||
mDisplayProfileImage = mPreferences.getBoolean(KEY_DISPLAY_PROFILE_IMAGE);
|
||||
mShowAbsoluteTime = mPreferences.getBoolean(KEY_SHOW_ABSOLUTE_TIME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProfileImageStyle() {
|
||||
return mProfileImageStyle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getTextSize() {
|
||||
return mTextSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProfileImageEnabled() {
|
||||
return mDisplayProfileImage;
|
||||
}
|
||||
|
||||
public abstract D getData();
|
||||
|
||||
public boolean isUser(int position) {
|
||||
return position < getUserCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShowAbsoluteTime() {
|
||||
return mShowAbsoluteTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
switch (viewType) {
|
||||
case ITEM_VIEW_TYPE_USER: {
|
||||
final View view;
|
||||
view = mInflater.inflate(R.layout.card_item_user_compact, parent, false);
|
||||
final View itemContent = view.findViewById(R.id.item_content);
|
||||
itemContent.setBackgroundColor(mCardBackgroundColor);
|
||||
final UserViewHolder holder = new UserViewHolder(this, view);
|
||||
holder.setOnClickListeners();
|
||||
holder.setupViewOptions();
|
||||
return holder;
|
||||
}
|
||||
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_USER: {
|
||||
bindUser(((UserViewHolder) holder), position);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if ((getLoadMoreIndicatorPosition() & IndicatorPosition.START) != 0 && position == 0) {
|
||||
return ITEM_VIEW_TYPE_LOAD_INDICATOR;
|
||||
}
|
||||
if (position == getUserCount()) {
|
||||
return ITEM_VIEW_TYPE_LOAD_INDICATOR;
|
||||
}
|
||||
return ITEM_VIEW_TYPE_USER;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public UserAdapterListener getUserAdapterListener() {
|
||||
return mUserAdapterListener;
|
||||
}
|
||||
|
||||
public void setUserAdapterListener(UserAdapterListener userAdapterListener) {
|
||||
mUserAdapterListener = userAdapterListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestClickListener getRequestClickListener() {
|
||||
return mRequestClickListener;
|
||||
}
|
||||
|
||||
public void setRequestClickListener(RequestClickListener requestClickListener) {
|
||||
mRequestClickListener = requestClickListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldShowAccountsColor() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected abstract void bindUser(UserViewHolder holder, int position);
|
||||
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.mariotaku.twidere.model.ParcelableGroup;
|
||||
import org.mariotaku.twidere.view.holder.GroupViewHolder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ParcelableGroupsAdapter extends AbsGroupsAdapter<List<ParcelableGroup>> {
|
||||
|
||||
private List<ParcelableGroup> mData;
|
||||
|
||||
|
||||
public ParcelableGroupsAdapter(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ParcelableGroup> getData() {
|
||||
return mData;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setData(List<ParcelableGroup> data) {
|
||||
mData = data;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindGroup(GroupViewHolder holder, int position) {
|
||||
holder.displayGroup(getGroup(position));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
final int position = getLoadMoreIndicatorPosition();
|
||||
int count = getGroupsCount();
|
||||
if ((position & IndicatorPosition.START) != 0) {
|
||||
count++;
|
||||
}
|
||||
if ((position & IndicatorPosition.END) != 0) {
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelableGroup getGroup(int position) {
|
||||
if (position == getGroupsCount()) return null;
|
||||
return mData.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getGroupId(int position) {
|
||||
if (position == getGroupsCount()) return -1;
|
||||
return mData.get(position).id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGroupsCount() {
|
||||
if (mData == null) return 0;
|
||||
return mData.size();
|
||||
}
|
||||
}
|
@ -20,24 +20,51 @@
|
||||
package org.mariotaku.twidere.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import org.mariotaku.twidere.model.UserKey;
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.iface.IUsersAdapter;
|
||||
import org.mariotaku.twidere.model.ParcelableUser;
|
||||
import org.mariotaku.twidere.model.UserKey;
|
||||
import org.mariotaku.twidere.util.ThemeUtils;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.view.holder.LoadIndicatorViewHolder;
|
||||
import org.mariotaku.twidere.view.holder.UserViewHolder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ParcelableUsersAdapter extends AbsUsersAdapter<List<ParcelableUser>> {
|
||||
public class ParcelableUsersAdapter extends LoadMoreSupportAdapter<RecyclerView.ViewHolder>
|
||||
implements Constants, IUsersAdapter<List<ParcelableUser>> {
|
||||
|
||||
public static final int ITEM_VIEW_TYPE_USER = 2;
|
||||
private final LayoutInflater mInflater;
|
||||
private final int mCardBackgroundColor;
|
||||
private final int mProfileImageStyle;
|
||||
private final int mTextSize;
|
||||
private final boolean mDisplayProfileImage;
|
||||
private final boolean mShowAbsoluteTime;
|
||||
private List<ParcelableUser> mData;
|
||||
private UserAdapterListener mUserAdapterListener;
|
||||
private RequestClickListener mRequestClickListener;
|
||||
|
||||
|
||||
public ParcelableUsersAdapter(Context context) {
|
||||
super(context);
|
||||
mCardBackgroundColor = ThemeUtils.getCardBackgroundColor(context,
|
||||
ThemeUtils.getThemeBackgroundOption(context),
|
||||
ThemeUtils.getUserThemeBackgroundAlpha(context));
|
||||
mInflater = LayoutInflater.from(context);
|
||||
mTextSize = mPreferences.getInt(KEY_TEXT_SIZE, context.getResources().getInteger(R.integer.default_text_size));
|
||||
mProfileImageStyle = Utils.getProfileImageStyle(mPreferences.getString(KEY_PROFILE_IMAGE_STYLE, null));
|
||||
mDisplayProfileImage = mPreferences.getBoolean(KEY_DISPLAY_PROFILE_IMAGE);
|
||||
mShowAbsoluteTime = mPreferences.getBoolean(KEY_SHOW_ABSOLUTE_TIME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ParcelableUser> getData() {
|
||||
return mData;
|
||||
}
|
||||
@ -49,7 +76,6 @@ public class ParcelableUsersAdapter extends AbsUsersAdapter<List<ParcelableUser>
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindUser(UserViewHolder holder, int position) {
|
||||
holder.displayUser(getUser(position));
|
||||
}
|
||||
@ -114,4 +140,89 @@ public class ParcelableUsersAdapter extends AbsUsersAdapter<List<ParcelableUser>
|
||||
return RecyclerView.NO_POSITION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProfileImageStyle() {
|
||||
return mProfileImageStyle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getTextSize() {
|
||||
return mTextSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProfileImageEnabled() {
|
||||
return mDisplayProfileImage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShowAbsoluteTime() {
|
||||
return mShowAbsoluteTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
switch (viewType) {
|
||||
case ITEM_VIEW_TYPE_USER: {
|
||||
final View view;
|
||||
view = mInflater.inflate(R.layout.card_item_user_compact, parent, false);
|
||||
final View itemContent = view.findViewById(R.id.item_content);
|
||||
itemContent.setBackgroundColor(mCardBackgroundColor);
|
||||
final UserViewHolder holder = new UserViewHolder(this, view);
|
||||
holder.setOnClickListeners();
|
||||
holder.setupViewOptions();
|
||||
return holder;
|
||||
}
|
||||
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(RecyclerView.ViewHolder holder, int position) {
|
||||
switch (holder.getItemViewType()) {
|
||||
case ITEM_VIEW_TYPE_USER: {
|
||||
bindUser(((UserViewHolder) holder), position);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if ((getLoadMoreIndicatorPosition() & IndicatorPosition.START) != 0 && position == 0) {
|
||||
return ITEM_VIEW_TYPE_LOAD_INDICATOR;
|
||||
}
|
||||
if (position == getUserCount()) {
|
||||
return ITEM_VIEW_TYPE_LOAD_INDICATOR;
|
||||
}
|
||||
return ITEM_VIEW_TYPE_USER;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public UserAdapterListener getUserAdapterListener() {
|
||||
return mUserAdapterListener;
|
||||
}
|
||||
|
||||
public void setUserAdapterListener(UserAdapterListener userAdapterListener) {
|
||||
mUserAdapterListener = userAdapterListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestClickListener getRequestClickListener() {
|
||||
return mRequestClickListener;
|
||||
}
|
||||
|
||||
public void setRequestClickListener(RequestClickListener requestClickListener) {
|
||||
mRequestClickListener = requestClickListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldShowAccountsColor() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1,157 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment.support;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import org.mariotaku.twidere.adapter.AbsUsersAdapter;
|
||||
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosition;
|
||||
import org.mariotaku.twidere.adapter.iface.IUsersAdapter.UserAdapterListener;
|
||||
import org.mariotaku.twidere.loader.iface.IExtendedLoader;
|
||||
import org.mariotaku.twidere.model.ParcelableUser;
|
||||
import org.mariotaku.twidere.model.util.UserKeyUtils;
|
||||
import org.mariotaku.twidere.util.IntentUtils;
|
||||
import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
|
||||
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback;
|
||||
import org.mariotaku.twidere.util.LinkCreator;
|
||||
import org.mariotaku.twidere.util.RecyclerViewNavigationHelper;
|
||||
import org.mariotaku.twidere.view.holder.UserViewHolder;
|
||||
|
||||
abstract class AbsUsersFragment<Data> extends AbsContentListRecyclerViewFragment<AbsUsersAdapter<Data>>
|
||||
implements LoaderCallbacks<Data>, UserAdapterListener, KeyboardShortcutCallback {
|
||||
|
||||
private RecyclerViewNavigationHelper mNavigationHelper;
|
||||
|
||||
public final Data getData() {
|
||||
return getAdapter().getData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleKeyboardShortcutSingle(@NonNull KeyboardShortcutsHandler handler, int keyCode, @NonNull KeyEvent event, int metaState) {
|
||||
return mNavigationHelper.handleKeyboardShortcutSingle(handler, keyCode, event, metaState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleKeyboardShortcutRepeat(@NonNull KeyboardShortcutsHandler handler, int keyCode, int repeatCount, @NonNull KeyEvent event, int metaState) {
|
||||
return mNavigationHelper.handleKeyboardShortcutRepeat(handler, keyCode, repeatCount, event, metaState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isKeyboardShortcutHandled(@NonNull KeyboardShortcutsHandler handler, int keyCode, @NonNull KeyEvent event, int metaState) {
|
||||
return mNavigationHelper.isKeyboardShortcutHandled(handler, keyCode, event, metaState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
final AbsUsersAdapter<Data> adapter = getAdapter();
|
||||
final RecyclerView recyclerView = getRecyclerView();
|
||||
final LinearLayoutManager layoutManager = getLayoutManager();
|
||||
adapter.setUserAdapterListener(this);
|
||||
|
||||
mNavigationHelper = new RecyclerViewNavigationHelper(recyclerView, layoutManager, adapter,
|
||||
this);
|
||||
final Bundle loaderArgs = new Bundle(getArguments());
|
||||
loaderArgs.putBoolean(EXTRA_FROM_USER, true);
|
||||
getLoaderManager().initLoader(0, loaderArgs, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Loader<Data> onCreateLoader(int id, Bundle args) {
|
||||
final boolean fromUser = args.getBoolean(EXTRA_FROM_USER);
|
||||
args.remove(EXTRA_FROM_USER);
|
||||
return onCreateUsersLoader(getActivity(), args, fromUser);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(Loader<Data> loader, Data data) {
|
||||
final AbsUsersAdapter<Data> adapter = getAdapter();
|
||||
adapter.setData(data);
|
||||
if (!(loader instanceof IExtendedLoader) || ((IExtendedLoader) loader).isFromUser()) {
|
||||
adapter.setLoadMoreSupportedPosition(hasMoreData(data) ? IndicatorPosition.END : IndicatorPosition.NONE);
|
||||
setRefreshEnabled(true);
|
||||
}
|
||||
if (loader instanceof IExtendedLoader) {
|
||||
((IExtendedLoader) loader).setFromUser(false);
|
||||
}
|
||||
showContent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<Data> loader) {
|
||||
if (loader instanceof IExtendedLoader) {
|
||||
((IExtendedLoader) loader).setFromUser(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserClick(UserViewHolder holder, int position) {
|
||||
final ParcelableUser user = getAdapter().getUser(position);
|
||||
final FragmentActivity activity = getActivity();
|
||||
if (UserKeyUtils.isSameHost(user.account_key, user.key)) {
|
||||
IntentUtils.openUserProfile(activity, user.account_key, user.key.getId(),
|
||||
user.screen_name, null, true, getUserReferral());
|
||||
} else if (user.extras != null && user.extras.statusnet_profile_url != null) {
|
||||
final Uri uri = Uri.parse(user.extras.statusnet_profile_url);
|
||||
final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
|
||||
startActivity(intent);
|
||||
} else {
|
||||
final Uri uri = LinkCreator.getTwitterUserLink(user.screen_name);
|
||||
final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
||||
@UserFragment.Referral
|
||||
protected String getUserReferral() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onUserLongClick(UserViewHolder holder, int position) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected abstract boolean hasMoreData(Data data);
|
||||
|
||||
protected abstract Loader<Data> onCreateUsersLoader(final Context context,
|
||||
@NonNull final Bundle args,
|
||||
final boolean fromUser);
|
||||
|
||||
|
||||
@Override
|
||||
protected void setupRecyclerView(Context context, boolean compact) {
|
||||
super.setupRecyclerView(context, true);
|
||||
}
|
||||
|
||||
}
|
@ -25,7 +25,6 @@ import android.support.annotation.NonNull;
|
||||
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.mariotaku.twidere.adapter.AbsUsersAdapter;
|
||||
import org.mariotaku.twidere.adapter.ParcelableUsersAdapter;
|
||||
import org.mariotaku.twidere.adapter.iface.IUsersAdapter;
|
||||
import org.mariotaku.twidere.loader.support.IDsUsersLoader;
|
||||
@ -70,7 +69,7 @@ public class IncomingFriendshipsFragment extends CursorSupportUsersListFragment
|
||||
|
||||
@Override
|
||||
public void onAcceptClicked(UserViewHolder holder, int position) {
|
||||
final AbsUsersAdapter<List<ParcelableUser>> adapter = getAdapter();
|
||||
final ParcelableUsersAdapter adapter = getAdapter();
|
||||
final ParcelableUser user = adapter.getUser(position);
|
||||
if (user == null) return;
|
||||
mTwitterWrapper.acceptFriendshipAsync(user.account_key, user.key);
|
||||
@ -78,7 +77,7 @@ public class IncomingFriendshipsFragment extends CursorSupportUsersListFragment
|
||||
|
||||
@Override
|
||||
public void onDenyClicked(UserViewHolder holder, int position) {
|
||||
final AbsUsersAdapter<List<ParcelableUser>> adapter = getAdapter();
|
||||
final ParcelableUsersAdapter adapter = getAdapter();
|
||||
final ParcelableUser user = adapter.getUser(position);
|
||||
if (user == null) return;
|
||||
mTwitterWrapper.denyFriendshipAsync(user.account_key, user.key);
|
||||
|
@ -23,35 +23,93 @@ import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import org.mariotaku.twidere.adapter.AbsGroupsAdapter;
|
||||
import org.mariotaku.twidere.adapter.AbsUserListsAdapter;
|
||||
import org.mariotaku.twidere.adapter.ParcelableGroupsAdapter;
|
||||
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosition;
|
||||
import org.mariotaku.twidere.loader.iface.IExtendedLoader;
|
||||
import org.mariotaku.twidere.loader.support.iface.ICursorSupportLoader;
|
||||
import org.mariotaku.twidere.model.ParcelableGroup;
|
||||
import org.mariotaku.twidere.model.ParcelableUserList;
|
||||
import org.mariotaku.twidere.util.IntentUtils;
|
||||
import org.mariotaku.twidere.model.UserKey;
|
||||
import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
|
||||
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback;
|
||||
import org.mariotaku.twidere.util.RecyclerViewNavigationHelper;
|
||||
import org.mariotaku.twidere.view.holder.GroupViewHolder;
|
||||
import org.mariotaku.twidere.view.holder.UserListViewHolder;
|
||||
|
||||
abstract class AbsGroupsFragment<Data> extends AbsContentListRecyclerViewFragment<AbsGroupsAdapter<Data>>
|
||||
implements LoaderCallbacks<Data>, AbsGroupsAdapter.GroupAdapterListener, KeyboardShortcutCallback {
|
||||
import java.util.List;
|
||||
|
||||
public abstract class ParcelableGroupsFragment extends AbsContentListRecyclerViewFragment<AbsGroupsAdapter<List<ParcelableGroup>>>
|
||||
implements LoaderManager.LoaderCallbacks<List<ParcelableGroup>>, AbsGroupsAdapter.GroupAdapterListener,
|
||||
KeyboardShortcutsHandler.KeyboardShortcutCallback {
|
||||
|
||||
private RecyclerViewNavigationHelper mNavigationHelper;
|
||||
|
||||
private long mNextCursor;
|
||||
private long mPrevCursor;
|
||||
|
||||
public final Data getData() {
|
||||
@Override
|
||||
public boolean isRefreshing() {
|
||||
if (getContext() == null || isDetached()) return false;
|
||||
final LoaderManager lm = getLoaderManager();
|
||||
return lm.hasRunningLoaders();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected final ParcelableGroupsAdapter onCreateAdapter(Context context, boolean compact) {
|
||||
return new ParcelableGroupsAdapter(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setupRecyclerView(Context context, boolean compact) {
|
||||
super.setupRecyclerView(context, true);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected UserKey getAccountKey() {
|
||||
final Bundle args = getArguments();
|
||||
return args.getParcelable(EXTRA_ACCOUNT_KEY);
|
||||
}
|
||||
|
||||
protected boolean hasMoreData(List<ParcelableGroup> data) {
|
||||
return data == null || !data.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(Loader<List<ParcelableGroup>> loader, List<ParcelableGroup> data) {
|
||||
final AbsGroupsAdapter<List<ParcelableGroup>> adapter = getAdapter();
|
||||
adapter.setData(data);
|
||||
if (!(loader instanceof IExtendedLoader) || ((IExtendedLoader) loader).isFromUser()) {
|
||||
adapter.setLoadMoreSupportedPosition(hasMoreData(data) ? IndicatorPosition.END : IndicatorPosition.NONE);
|
||||
setRefreshEnabled(true);
|
||||
}
|
||||
if (loader instanceof IExtendedLoader) {
|
||||
((IExtendedLoader) loader).setFromUser(false);
|
||||
}
|
||||
setRefreshEnabled(true);
|
||||
setRefreshing(false);
|
||||
setLoadMoreIndicatorPosition(IndicatorPosition.NONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadMoreContents(@IndicatorPosition int position) {
|
||||
// Only supports load from end, skip START flag
|
||||
if ((position & IndicatorPosition.START) != 0) return;
|
||||
super.onLoadMoreContents(position);
|
||||
if (position == 0) return;
|
||||
final Bundle loaderArgs = new Bundle(getArguments());
|
||||
loaderArgs.putBoolean(EXTRA_FROM_USER, true);
|
||||
loaderArgs.putLong(EXTRA_NEXT_CURSOR, getNextCursor());
|
||||
getLoaderManager().restartLoader(0, loaderArgs, this);
|
||||
}
|
||||
|
||||
protected void removeUsers(long... ids) {
|
||||
//TODO remove from adapter
|
||||
}
|
||||
|
||||
public final List<ParcelableGroup> getData() {
|
||||
return getAdapter().getData();
|
||||
}
|
||||
|
||||
@ -73,7 +131,7 @@ abstract class AbsGroupsFragment<Data> extends AbsContentListRecyclerViewFragmen
|
||||
@Override
|
||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
final AbsGroupsAdapter<Data> adapter = getAdapter();
|
||||
final AbsGroupsAdapter<List<ParcelableGroup>> adapter = getAdapter();
|
||||
final RecyclerView recyclerView = getRecyclerView();
|
||||
final LinearLayoutManager layoutManager = getLayoutManager();
|
||||
adapter.setListener(this);
|
||||
@ -86,32 +144,14 @@ abstract class AbsGroupsFragment<Data> extends AbsContentListRecyclerViewFragmen
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Loader<Data> onCreateLoader(int id, Bundle args) {
|
||||
public final Loader<List<ParcelableGroup>> onCreateLoader(int id, Bundle args) {
|
||||
final boolean fromUser = args.getBoolean(EXTRA_FROM_USER);
|
||||
args.remove(EXTRA_FROM_USER);
|
||||
return onCreateUserListsLoader(getActivity(), args, fromUser);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(Loader<Data> loader, Data data) {
|
||||
final AbsGroupsAdapter<Data> adapter = getAdapter();
|
||||
adapter.setData(data);
|
||||
if (!(loader instanceof IExtendedLoader) || ((IExtendedLoader) loader).isFromUser()) {
|
||||
adapter.setLoadMoreSupportedPosition(hasMoreData(data) ? IndicatorPosition.END : IndicatorPosition.NONE);
|
||||
setRefreshEnabled(true);
|
||||
}
|
||||
if (loader instanceof IExtendedLoader) {
|
||||
((IExtendedLoader) loader).setFromUser(false);
|
||||
}
|
||||
if (loader instanceof ICursorSupportLoader) {
|
||||
mNextCursor = ((ICursorSupportLoader) loader).getNextCursor();
|
||||
mPrevCursor = ((ICursorSupportLoader) loader).getNextCursor();
|
||||
}
|
||||
showContent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<Data> loader) {
|
||||
public void onLoaderReset(Loader<List<ParcelableGroup>> loader) {
|
||||
if (loader instanceof IExtendedLoader) {
|
||||
((IExtendedLoader) loader).setFromUser(false);
|
||||
}
|
||||
@ -135,14 +175,5 @@ abstract class AbsGroupsFragment<Data> extends AbsContentListRecyclerViewFragmen
|
||||
return mNextCursor;
|
||||
}
|
||||
|
||||
|
||||
protected ParcelableUserList getSelectedUserList() {
|
||||
//TODO return selected
|
||||
return null;
|
||||
}
|
||||
|
||||
protected abstract boolean hasMoreData(Data data);
|
||||
|
||||
protected abstract Loader<Data> onCreateUserListsLoader(Context context, Bundle args, boolean fromUser);
|
||||
|
||||
protected abstract Loader<List<ParcelableGroup>> onCreateUserListsLoader(Context context, Bundle args, boolean fromUser);
|
||||
}
|
@ -20,17 +20,37 @@
|
||||
package org.mariotaku.twidere.fragment.support;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import org.mariotaku.twidere.adapter.ParcelableUsersAdapter;
|
||||
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosition;
|
||||
import org.mariotaku.twidere.adapter.iface.IUsersAdapter;
|
||||
import org.mariotaku.twidere.loader.iface.IExtendedLoader;
|
||||
import org.mariotaku.twidere.model.ParcelableUser;
|
||||
import org.mariotaku.twidere.model.util.UserKeyUtils;
|
||||
import org.mariotaku.twidere.util.IntentUtils;
|
||||
import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
|
||||
import org.mariotaku.twidere.util.LinkCreator;
|
||||
import org.mariotaku.twidere.util.RecyclerViewNavigationHelper;
|
||||
import org.mariotaku.twidere.view.holder.UserViewHolder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class ParcelableUsersFragment extends AbsUsersFragment<List<ParcelableUser>> {
|
||||
public abstract class ParcelableUsersFragment extends AbsContentListRecyclerViewFragment<ParcelableUsersAdapter>
|
||||
implements LoaderManager.LoaderCallbacks<List<ParcelableUser>>, IUsersAdapter.UserAdapterListener,
|
||||
KeyboardShortcutsHandler.KeyboardShortcutCallback {
|
||||
|
||||
private RecyclerViewNavigationHelper mNavigationHelper;
|
||||
|
||||
@Override
|
||||
public boolean isRefreshing() {
|
||||
@ -48,17 +68,24 @@ public abstract class ParcelableUsersFragment extends AbsUsersFragment<List<Parc
|
||||
@NonNull
|
||||
@Override
|
||||
public ParcelableUsersAdapter getAdapter() {
|
||||
return (ParcelableUsersAdapter) super.getAdapter();
|
||||
return super.getAdapter();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasMoreData(List<ParcelableUser> data) {
|
||||
return data == null || !data.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(Loader<List<ParcelableUser>> loader, List<ParcelableUser> data) {
|
||||
super.onLoadFinished(loader, data);
|
||||
final ParcelableUsersAdapter adapter = getAdapter();
|
||||
adapter.setData(data);
|
||||
if (!(loader instanceof IExtendedLoader) || ((IExtendedLoader) loader).isFromUser()) {
|
||||
adapter.setLoadMoreSupportedPosition(hasMoreData(data) ? IndicatorPosition.END : IndicatorPosition.NONE);
|
||||
setRefreshEnabled(true);
|
||||
}
|
||||
if (loader instanceof IExtendedLoader) {
|
||||
((IExtendedLoader) loader).setFromUser(false);
|
||||
}
|
||||
showContent();
|
||||
setRefreshEnabled(true);
|
||||
setRefreshing(false);
|
||||
setLoadMoreIndicatorPosition(IndicatorPosition.NONE);
|
||||
@ -68,4 +95,88 @@ public abstract class ParcelableUsersFragment extends AbsUsersFragment<List<Parc
|
||||
//TODO remove from adapter
|
||||
}
|
||||
|
||||
public final List<ParcelableUser> getData() {
|
||||
return getAdapter().getData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleKeyboardShortcutSingle(@NonNull KeyboardShortcutsHandler handler, int keyCode, @NonNull KeyEvent event, int metaState) {
|
||||
return mNavigationHelper.handleKeyboardShortcutSingle(handler, keyCode, event, metaState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleKeyboardShortcutRepeat(@NonNull KeyboardShortcutsHandler handler, int keyCode, int repeatCount, @NonNull KeyEvent event, int metaState) {
|
||||
return mNavigationHelper.handleKeyboardShortcutRepeat(handler, keyCode, repeatCount, event, metaState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isKeyboardShortcutHandled(@NonNull KeyboardShortcutsHandler handler, int keyCode, @NonNull KeyEvent event, int metaState) {
|
||||
return mNavigationHelper.isKeyboardShortcutHandled(handler, keyCode, event, metaState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
final ParcelableUsersAdapter adapter = getAdapter();
|
||||
final RecyclerView recyclerView = getRecyclerView();
|
||||
final LinearLayoutManager layoutManager = getLayoutManager();
|
||||
adapter.setUserAdapterListener(this);
|
||||
|
||||
mNavigationHelper = new RecyclerViewNavigationHelper(recyclerView, layoutManager, adapter,
|
||||
this);
|
||||
final Bundle loaderArgs = new Bundle(getArguments());
|
||||
loaderArgs.putBoolean(EXTRA_FROM_USER, true);
|
||||
getLoaderManager().initLoader(0, loaderArgs, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Loader<List<ParcelableUser>> onCreateLoader(int id, Bundle args) {
|
||||
final boolean fromUser = args.getBoolean(EXTRA_FROM_USER);
|
||||
args.remove(EXTRA_FROM_USER);
|
||||
return onCreateUsersLoader(getActivity(), args, fromUser);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<List<ParcelableUser>> loader) {
|
||||
if (loader instanceof IExtendedLoader) {
|
||||
((IExtendedLoader) loader).setFromUser(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserClick(UserViewHolder holder, int position) {
|
||||
final ParcelableUser user = getAdapter().getUser(position);
|
||||
final FragmentActivity activity = getActivity();
|
||||
if (UserKeyUtils.isSameHost(user.account_key, user.key)) {
|
||||
IntentUtils.openUserProfile(activity, user.account_key, user.key.getId(),
|
||||
user.screen_name, null, true, getUserReferral());
|
||||
} else if (user.extras != null && user.extras.statusnet_profile_url != null) {
|
||||
final Uri uri = Uri.parse(user.extras.statusnet_profile_url);
|
||||
final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
|
||||
startActivity(intent);
|
||||
} else {
|
||||
final Uri uri = LinkCreator.getTwitterUserLink(user.screen_name);
|
||||
final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
||||
@UserFragment.Referral
|
||||
protected String getUserReferral() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onUserLongClick(UserViewHolder holder, int position) {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected abstract Loader<List<ParcelableUser>> onCreateUsersLoader(final Context context,
|
||||
@NonNull final Bundle args,
|
||||
final boolean fromUser);
|
||||
|
||||
@Override
|
||||
protected void setupRecyclerView(Context context, boolean compact) {
|
||||
super.setupRecyclerView(context, true);
|
||||
}
|
||||
}
|
||||
|
@ -807,6 +807,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
mProfileImageView.setOnClickListener(this);
|
||||
mProfileBannerView.setOnClickListener(this);
|
||||
mListedContainer.setOnClickListener(this);
|
||||
mGroupsContainer.setOnClickListener(this);
|
||||
mFollowersContainer.setOnClickListener(this);
|
||||
mFriendsContainer.setOnClickListener(this);
|
||||
mHeaderErrorIcon.setOnClickListener(this);
|
||||
|
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* 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.loader.support;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v4.content.AsyncTaskLoader;
|
||||
import android.util.Log;
|
||||
|
||||
import org.mariotaku.twidere.TwidereConstants;
|
||||
import org.mariotaku.twidere.api.statusnet.model.Group;
|
||||
import org.mariotaku.twidere.api.twitter.Twitter;
|
||||
import org.mariotaku.twidere.api.twitter.TwitterException;
|
||||
import org.mariotaku.twidere.api.twitter.model.CursorSupport;
|
||||
import org.mariotaku.twidere.api.twitter.model.PageableResponseList;
|
||||
import org.mariotaku.twidere.loader.support.iface.ICursorSupportLoader;
|
||||
import org.mariotaku.twidere.model.ParcelableGroup;
|
||||
import org.mariotaku.twidere.model.UserKey;
|
||||
import org.mariotaku.twidere.model.util.ParcelableGroupUtils;
|
||||
import org.mariotaku.twidere.util.TwitterAPIFactory;
|
||||
import org.mariotaku.twidere.util.collection.NoDuplicatesArrayList;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public abstract class BaseGroupsLoader extends AsyncTaskLoader<List<ParcelableGroup>>
|
||||
implements TwidereConstants, ICursorSupportLoader {
|
||||
|
||||
protected final NoDuplicatesArrayList<ParcelableGroup> mData = new NoDuplicatesArrayList<>();
|
||||
protected final UserKey mAccountId;
|
||||
private final long mCursor;
|
||||
|
||||
private long mNextCursor, mPrevCursor;
|
||||
|
||||
public BaseGroupsLoader(final Context context, final UserKey accountKey, final long cursor,
|
||||
final List<ParcelableGroup> data) {
|
||||
super(context);
|
||||
if (data != null) {
|
||||
mData.addAll(data);
|
||||
}
|
||||
mCursor = cursor;
|
||||
mAccountId = accountKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCursor() {
|
||||
return mCursor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getNextCursor() {
|
||||
return mNextCursor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getPrevCursor() {
|
||||
return mPrevCursor;
|
||||
}
|
||||
|
||||
public abstract List<Group> getGroups(final Twitter twitter) throws TwitterException;
|
||||
|
||||
@Override
|
||||
public List<ParcelableGroup> loadInBackground() {
|
||||
final Twitter twitter = TwitterAPIFactory.getTwitterInstance(getContext(), mAccountId, true);
|
||||
List<Group> listLoaded = null;
|
||||
try {
|
||||
listLoaded = getGroups(twitter);
|
||||
} catch (final TwitterException e) {
|
||||
Log.w(LOGTAG, e);
|
||||
}
|
||||
if (listLoaded != null) {
|
||||
final int listSize = listLoaded.size();
|
||||
if (listLoaded instanceof PageableResponseList) {
|
||||
mNextCursor = ((CursorSupport) listLoaded).getNextCursor();
|
||||
mPrevCursor = ((CursorSupport) listLoaded).getPreviousCursor();
|
||||
final int dataSize = mData.size();
|
||||
for (int i = 0; i < listSize; i++) {
|
||||
final Group group = listLoaded.get(i);
|
||||
mData.add(ParcelableGroupUtils.from(group, mAccountId, dataSize + i, isMember(group)));
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < listSize; i++) {
|
||||
final Group list = listLoaded.get(i);
|
||||
mData.add(ParcelableGroupUtils.from(listLoaded.get(i), mAccountId, i, isMember(list)));
|
||||
}
|
||||
}
|
||||
}
|
||||
Collections.sort(mData);
|
||||
return mData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartLoading() {
|
||||
forceLoad();
|
||||
}
|
||||
|
||||
protected boolean isMember(final Group list) {
|
||||
return list.isMember();
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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.loader.support;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.mariotaku.twidere.api.statusnet.model.Group;
|
||||
import org.mariotaku.twidere.api.twitter.Twitter;
|
||||
import org.mariotaku.twidere.api.twitter.TwitterException;
|
||||
import org.mariotaku.twidere.api.twitter.model.ResponseList;
|
||||
import org.mariotaku.twidere.api.twitter.model.UserList;
|
||||
import org.mariotaku.twidere.model.ParcelableGroup;
|
||||
import org.mariotaku.twidere.model.ParcelableUserList;
|
||||
import org.mariotaku.twidere.model.UserKey;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserGroupsLoader extends BaseGroupsLoader {
|
||||
|
||||
private final long mUserId;
|
||||
private final String mScreenName;
|
||||
|
||||
public UserGroupsLoader(final Context context, final UserKey accountKey, final long userId,
|
||||
final String screenName, final List<ParcelableGroup> data) {
|
||||
super(context, accountKey, 0, data);
|
||||
mUserId = userId;
|
||||
mScreenName = screenName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseList<Group> getGroups(final Twitter twitter) throws TwitterException {
|
||||
if (twitter == null) return null;
|
||||
if (mUserId > 0)
|
||||
return twitter.getGroups(mUserId);
|
||||
else if (mScreenName != null) return twitter.getGroups(mScreenName);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isMember(final Group list) {
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package org.mariotaku.twidere.model.util;
|
||||
|
||||
import org.mariotaku.twidere.api.statusnet.model.Group;
|
||||
import org.mariotaku.twidere.model.ParcelableGroup;
|
||||
import org.mariotaku.twidere.model.UserKey;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/3/9.
|
||||
*/
|
||||
public class ParcelableGroupUtils {
|
||||
public static ParcelableGroup from(Group group, UserKey accountKey, int position, boolean member) {
|
||||
ParcelableGroup obj = new ParcelableGroup();
|
||||
obj.account_key = accountKey;
|
||||
obj.member = member;
|
||||
obj.position = position;
|
||||
obj.id = group.getId();
|
||||
obj.nickname = group.getNickname();
|
||||
obj.homepage = group.getHomepage();
|
||||
obj.fullname = group.getFullname();
|
||||
obj.url = group.getUrl();
|
||||
obj.description = group.getDescription();
|
||||
obj.location = group.getLocation();
|
||||
obj.created = getTime(group.getCreated());
|
||||
obj.modified = getTime(group.getModified());
|
||||
obj.admin_count = group.getAdminCount();
|
||||
obj.member_count = group.getMemberCount();
|
||||
obj.original_logo = group.getOriginalLogo();
|
||||
obj.homepage_logo = group.getHomepageLogo();
|
||||
obj.stream_logo = group.getStreamLogo();
|
||||
obj.mini_logo = group.getMiniLogo();
|
||||
obj.blocked = group.isBlocked();
|
||||
obj.id = group.getId();
|
||||
return obj;
|
||||
}
|
||||
|
||||
private static long getTime(Date date) {
|
||||
if (date == null) return -1;
|
||||
return date.getTime();
|
||||
}
|
||||
}
|
@ -68,8 +68,11 @@ public class UserKeyUtils {
|
||||
}
|
||||
|
||||
public static boolean isSameHost(UserKey accountKey, UserKey userKey) {
|
||||
final String a = accountKey.getHost(), b = userKey.getHost();
|
||||
return isSameHost(accountKey.getHost(), userKey.getHost());
|
||||
}
|
||||
|
||||
public static boolean isSameHost(String a, String b) {
|
||||
if (TextUtils.isEmpty(a) || TextUtils.isEmpty(b)) return true;
|
||||
return a.equals(b);
|
||||
return TextUtils.equals(a, b);
|
||||
}
|
||||
}
|
||||
|
@ -29,9 +29,10 @@ import android.widget.TextView;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.iface.IGroupsAdapter;
|
||||
import org.mariotaku.twidere.model.ParcelableGroup;
|
||||
import org.mariotaku.twidere.model.util.UserKeyUtils;
|
||||
import org.mariotaku.twidere.util.MediaLoaderWrapper;
|
||||
import org.mariotaku.twidere.util.UserColorNameManager;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.view.NameView;
|
||||
import org.mariotaku.twidere.view.iface.IColorLabelView;
|
||||
|
||||
import java.util.Locale;
|
||||
@ -45,11 +46,11 @@ public class GroupViewHolder extends ViewHolder implements View.OnClickListener,
|
||||
|
||||
private final IColorLabelView itemContent;
|
||||
private final ImageView profileImageView;
|
||||
private final TextView nameView;
|
||||
private final TextView createdByView;
|
||||
private final NameView nameView;
|
||||
private final TextView externalIndicator;
|
||||
private final TextView descriptionView;
|
||||
private final TextView membersCountView;
|
||||
private final TextView subscribersCountView;
|
||||
private final TextView adminsCountView;
|
||||
|
||||
private IGroupsAdapter.GroupAdapterListener groupClickListener;
|
||||
|
||||
@ -58,22 +59,26 @@ public class GroupViewHolder extends ViewHolder implements View.OnClickListener,
|
||||
itemContent = (IColorLabelView) itemView.findViewById(R.id.item_content);
|
||||
this.adapter = adapter;
|
||||
profileImageView = (ImageView) itemView.findViewById(R.id.profile_image);
|
||||
nameView = (TextView) itemView.findViewById(R.id.name);
|
||||
createdByView = (TextView) itemView.findViewById(R.id.created_by);
|
||||
nameView = (NameView) itemView.findViewById(R.id.name);
|
||||
externalIndicator = (TextView) itemView.findViewById(R.id.external_indicator);
|
||||
descriptionView = (TextView) itemView.findViewById(R.id.description);
|
||||
membersCountView = (TextView) itemView.findViewById(R.id.members_count);
|
||||
subscribersCountView = (TextView) itemView.findViewById(R.id.subscribers_count);
|
||||
adminsCountView = (TextView) itemView.findViewById(R.id.admins_count);
|
||||
}
|
||||
|
||||
public void displayGroup(ParcelableGroup group) {
|
||||
|
||||
final Context context = adapter.getContext();
|
||||
final MediaLoaderWrapper loader = adapter.getMediaLoader();
|
||||
final UserColorNameManager manager = adapter.getUserColorNameManager();
|
||||
|
||||
nameView.setText(group.fullname);
|
||||
final boolean nameFirst = adapter.isNameFirst();
|
||||
|
||||
nameView.setName(group.fullname);
|
||||
nameView.setScreenName("!" + group.nickname);
|
||||
final String groupHost = UserKeyUtils.getUserHost(group.url);
|
||||
if (UserKeyUtils.isSameHost(group.account_key.getHost(), groupHost)) {
|
||||
externalIndicator.setVisibility(View.GONE);
|
||||
} else {
|
||||
externalIndicator.setVisibility(View.VISIBLE);
|
||||
externalIndicator.setText(context.getString(R.string.external_user_host_format,
|
||||
groupHost));
|
||||
}
|
||||
if (adapter.isProfileImageEnabled()) {
|
||||
profileImageView.setVisibility(View.VISIBLE);
|
||||
loader.displayProfileImage(profileImageView, group.homepage_logo);
|
||||
@ -84,7 +89,7 @@ public class GroupViewHolder extends ViewHolder implements View.OnClickListener,
|
||||
descriptionView.setVisibility(TextUtils.isEmpty(group.description) ? View.GONE : View.VISIBLE);
|
||||
descriptionView.setText(group.description);
|
||||
membersCountView.setText(Utils.getLocalizedNumber(Locale.getDefault(), group.member_count));
|
||||
subscribersCountView.setText(Utils.getLocalizedNumber(Locale.getDefault(), group.admin_count));
|
||||
adminsCountView.setText(Utils.getLocalizedNumber(Locale.getDefault(), group.admin_count));
|
||||
}
|
||||
|
||||
public void setOnClickListeners() {
|
||||
@ -124,8 +129,12 @@ public class GroupViewHolder extends ViewHolder implements View.OnClickListener,
|
||||
}
|
||||
|
||||
public void setTextSize(final float textSize) {
|
||||
nameView.setTextSize(textSize);
|
||||
createdByView.setTextSize(textSize * 0.75f);
|
||||
descriptionView.setTextSize(textSize);
|
||||
externalIndicator.setTextSize(textSize);
|
||||
nameView.setPrimaryTextSize(textSize);
|
||||
nameView.setSecondaryTextSize(textSize * 0.75f);
|
||||
membersCountView.setTextSize(textSize);
|
||||
adminsCountView.setTextSize(textSize);
|
||||
}
|
||||
|
||||
}
|
||||
|
123
twidere/src/main/res/layout/card_item_group_compact.xml
Normal file
123
twidere/src/main/res/layout/card_item_group_compact.xml
Normal file
@ -0,0 +1,123 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Twidere - Twitter client for Android
|
||||
~
|
||||
~ Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
~
|
||||
~ This program is free software: you can redistribute it and/or modify
|
||||
~ it under the terms of the GNU General Public License as published by
|
||||
~ the Free Software Foundation, either version 3 of the License, or
|
||||
~ (at your option) any later version.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
~ GNU General Public License for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License
|
||||
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<org.mariotaku.twidere.view.ColorLabelRelativeLayout
|
||||
android:id="@+id/item_content"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackground"
|
||||
android:padding="@dimen/element_spacing_normal"
|
||||
app:ignorePadding="true"
|
||||
tools:context=".adapter.ParcelableUsersAdapter">
|
||||
|
||||
<org.mariotaku.twidere.view.ProfileImageView
|
||||
android:id="@+id/profile_image"
|
||||
style="?profileImageStyle"
|
||||
android:layout_width="@dimen/icon_size_card_list_item"
|
||||
android:layout_height="@dimen/icon_size_card_list_item"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginEnd="@dimen/element_spacing_normal"
|
||||
android:layout_marginRight="@dimen/element_spacing_normal"
|
||||
android:contentDescription="@string/profile_image"
|
||||
android:scaleType="fitCenter"
|
||||
tools:src="@mipmap/ic_launcher"/>
|
||||
|
||||
|
||||
<org.mariotaku.twidere.view.NameView
|
||||
android:id="@+id/name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignWithParentIfMissing="true"
|
||||
android:layout_toEndOf="@id/profile_image"
|
||||
android:layout_toRightOf="@id/profile_image"
|
||||
android:gravity="center_vertical"
|
||||
app:nv_primaryTextColor="?android:textColorPrimary"
|
||||
app:nv_primaryTextStyle="bold"
|
||||
app:nv_secondaryTextColor="?android:textColorSecondary"
|
||||
app:nv_twoLine="false"/>
|
||||
|
||||
|
||||
<org.mariotaku.twidere.view.ActionIconThemedTextView
|
||||
android:id="@+id/external_indicator"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignLeft="@+id/name"
|
||||
android:layout_alignStart="@+id/name"
|
||||
android:layout_below="@+id/name"
|
||||
android:paddingTop="@dimen/element_spacing_small"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textStyle="italic"
|
||||
tools:text="External group at gnu.io"/>
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:id="@+id/description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignLeft="@+id/name"
|
||||
android:layout_alignStart="@+id/name"
|
||||
android:layout_below="@+id/external_indicator"
|
||||
android:paddingTop="@dimen/element_spacing_small"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
tools:text="@string/sample_status_text"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignLeft="@+id/name"
|
||||
android:layout_alignStart="@+id/name"
|
||||
android:layout_below="@+id/description"
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="@dimen/element_spacing_small">
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:id="@+id/members_count"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:drawableLeft="@drawable/ic_indicator_followers"
|
||||
android:drawablePadding="4dp"
|
||||
android:drawableStart="@drawable/ic_indicator_followers"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
tools:text="255"/>
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:id="@+id/admins_count"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:drawableLeft="@drawable/ic_indicator_followers"
|
||||
android:drawablePadding="4dp"
|
||||
android:drawableStart="@drawable/ic_indicator_followers"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
tools:text="255"/>
|
||||
</LinearLayout>
|
||||
|
||||
</org.mariotaku.twidere.view.ColorLabelRelativeLayout>
|
@ -757,4 +757,5 @@
|
||||
<string name="uploader_version_incompatible">Incompatible media uploader</string>
|
||||
<string name="groups">Groups</string>
|
||||
<string name="external_user_host_format">External user at <xliff:g id="host">%s</xliff:g></string>
|
||||
<string name="external_group_host_format">External group at <xliff:g id="host">%s</xliff:g></string>
|
||||
</resources>
|
Loading…
x
Reference in New Issue
Block a user