mirror of
https://github.com/TwidereProject/Twidere-Android
synced 2025-02-14 18:50:39 +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.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
import com.bluelinelabs.logansquare.annotation.JsonField;
|
import com.bluelinelabs.logansquare.annotation.JsonField;
|
||||||
import com.bluelinelabs.logansquare.annotation.JsonObject;
|
import com.bluelinelabs.logansquare.annotation.JsonObject;
|
||||||
import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease;
|
import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease;
|
||||||
import com.hannesdorfmann.parcelableplease.annotation.ParcelableThisPlease;
|
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.
|
* Created by mariotaku on 16/3/9.
|
||||||
*/
|
*/
|
||||||
@ParcelablePlease
|
@ParcelablePlease
|
||||||
@JsonObject
|
@JsonObject
|
||||||
public class ParcelableGroup implements Parcelable {
|
public class ParcelableGroup implements Parcelable, Comparable<ParcelableGroup> {
|
||||||
|
|
||||||
@ParcelableThisPlease
|
@ParcelableThisPlease
|
||||||
@JsonField(name = "account_key")
|
@JsonField(name = "account_key")
|
||||||
@ -45,6 +42,10 @@ public class ParcelableGroup implements Parcelable {
|
|||||||
@JsonField(name = "location")
|
@JsonField(name = "location")
|
||||||
public String location;
|
public String location;
|
||||||
|
|
||||||
|
@ParcelableThisPlease
|
||||||
|
@JsonField(name = "position")
|
||||||
|
public long position;
|
||||||
|
|
||||||
@ParcelableThisPlease
|
@ParcelableThisPlease
|
||||||
@JsonField(name = "created")
|
@JsonField(name = "created")
|
||||||
public long created;
|
public long created;
|
||||||
@ -123,4 +124,9 @@ public class ParcelableGroup implements Parcelable {
|
|||||||
return new ParcelableGroup[size];
|
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
|
@Override
|
||||||
public int compareTo(@NonNull final ParcelableUserList another) {
|
public int compareTo(@NonNull final ParcelableUserList another) {
|
||||||
final long diff = position - another.position;
|
return (int) (position - another.position);
|
||||||
if (diff > Integer.MAX_VALUE) return Integer.MAX_VALUE;
|
|
||||||
if (diff < Integer.MIN_VALUE) return Integer.MIN_VALUE;
|
|
||||||
return (int) diff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,9 +1,24 @@
|
|||||||
package org.mariotaku.twidere.fragment.support;
|
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.
|
* 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);
|
setTitle(R.string.user_lists);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case LINK_ID_USER_GROUPS: {
|
||||||
|
setTitle(R.string.groups);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case LINK_ID_USER_LIST_TIMELINE: {
|
case LINK_ID_USER_LIST_TIMELINE: {
|
||||||
setTitle(R.string.list_timeline);
|
setTitle(R.string.list_timeline);
|
||||||
break;
|
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;
|
package org.mariotaku.twidere.adapter;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v7.widget.RecyclerView;
|
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.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 org.mariotaku.twidere.view.holder.UserViewHolder;
|
||||||
|
|
||||||
import java.util.List;
|
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 List<ParcelableUser> mData;
|
||||||
|
private UserAdapterListener mUserAdapterListener;
|
||||||
|
private RequestClickListener mRequestClickListener;
|
||||||
|
|
||||||
|
|
||||||
public ParcelableUsersAdapter(Context context) {
|
public ParcelableUsersAdapter(Context context) {
|
||||||
super(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() {
|
public List<ParcelableUser> getData() {
|
||||||
return mData;
|
return mData;
|
||||||
}
|
}
|
||||||
@ -49,7 +76,6 @@ public class ParcelableUsersAdapter extends AbsUsersAdapter<List<ParcelableUser>
|
|||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void bindUser(UserViewHolder holder, int position) {
|
protected void bindUser(UserViewHolder holder, int position) {
|
||||||
holder.displayUser(getUser(position));
|
holder.displayUser(getUser(position));
|
||||||
}
|
}
|
||||||
@ -114,4 +140,89 @@ public class ParcelableUsersAdapter extends AbsUsersAdapter<List<ParcelableUser>
|
|||||||
return RecyclerView.NO_POSITION;
|
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 com.squareup.otto.Subscribe;
|
||||||
|
|
||||||
import org.mariotaku.twidere.adapter.AbsUsersAdapter;
|
|
||||||
import org.mariotaku.twidere.adapter.ParcelableUsersAdapter;
|
import org.mariotaku.twidere.adapter.ParcelableUsersAdapter;
|
||||||
import org.mariotaku.twidere.adapter.iface.IUsersAdapter;
|
import org.mariotaku.twidere.adapter.iface.IUsersAdapter;
|
||||||
import org.mariotaku.twidere.loader.support.IDsUsersLoader;
|
import org.mariotaku.twidere.loader.support.IDsUsersLoader;
|
||||||
@ -70,7 +69,7 @@ public class IncomingFriendshipsFragment extends CursorSupportUsersListFragment
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAcceptClicked(UserViewHolder holder, int position) {
|
public void onAcceptClicked(UserViewHolder holder, int position) {
|
||||||
final AbsUsersAdapter<List<ParcelableUser>> adapter = getAdapter();
|
final ParcelableUsersAdapter adapter = getAdapter();
|
||||||
final ParcelableUser user = adapter.getUser(position);
|
final ParcelableUser user = adapter.getUser(position);
|
||||||
if (user == null) return;
|
if (user == null) return;
|
||||||
mTwitterWrapper.acceptFriendshipAsync(user.account_key, user.key);
|
mTwitterWrapper.acceptFriendshipAsync(user.account_key, user.key);
|
||||||
@ -78,7 +77,7 @@ public class IncomingFriendshipsFragment extends CursorSupportUsersListFragment
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDenyClicked(UserViewHolder holder, int position) {
|
public void onDenyClicked(UserViewHolder holder, int position) {
|
||||||
final AbsUsersAdapter<List<ParcelableUser>> adapter = getAdapter();
|
final ParcelableUsersAdapter adapter = getAdapter();
|
||||||
final ParcelableUser user = adapter.getUser(position);
|
final ParcelableUser user = adapter.getUser(position);
|
||||||
if (user == null) return;
|
if (user == null) return;
|
||||||
mTwitterWrapper.denyFriendshipAsync(user.account_key, user.key);
|
mTwitterWrapper.denyFriendshipAsync(user.account_key, user.key);
|
||||||
|
@ -23,35 +23,93 @@ import android.content.Context;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
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.v4.content.Loader;
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
|
|
||||||
import org.mariotaku.twidere.adapter.AbsGroupsAdapter;
|
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.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosition;
|
||||||
import org.mariotaku.twidere.loader.iface.IExtendedLoader;
|
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.ParcelableGroup;
|
||||||
import org.mariotaku.twidere.model.ParcelableUserList;
|
import org.mariotaku.twidere.model.UserKey;
|
||||||
import org.mariotaku.twidere.util.IntentUtils;
|
|
||||||
import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
|
import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
|
||||||
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback;
|
|
||||||
import org.mariotaku.twidere.util.RecyclerViewNavigationHelper;
|
import org.mariotaku.twidere.util.RecyclerViewNavigationHelper;
|
||||||
import org.mariotaku.twidere.view.holder.GroupViewHolder;
|
import org.mariotaku.twidere.view.holder.GroupViewHolder;
|
||||||
import org.mariotaku.twidere.view.holder.UserListViewHolder;
|
|
||||||
|
|
||||||
abstract class AbsGroupsFragment<Data> extends AbsContentListRecyclerViewFragment<AbsGroupsAdapter<Data>>
|
import java.util.List;
|
||||||
implements LoaderCallbacks<Data>, AbsGroupsAdapter.GroupAdapterListener, KeyboardShortcutCallback {
|
|
||||||
|
public abstract class ParcelableGroupsFragment extends AbsContentListRecyclerViewFragment<AbsGroupsAdapter<List<ParcelableGroup>>>
|
||||||
|
implements LoaderManager.LoaderCallbacks<List<ParcelableGroup>>, AbsGroupsAdapter.GroupAdapterListener,
|
||||||
|
KeyboardShortcutsHandler.KeyboardShortcutCallback {
|
||||||
|
|
||||||
private RecyclerViewNavigationHelper mNavigationHelper;
|
private RecyclerViewNavigationHelper mNavigationHelper;
|
||||||
|
|
||||||
private long mNextCursor;
|
private long mNextCursor;
|
||||||
private long mPrevCursor;
|
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();
|
return getAdapter().getData();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +131,7 @@ abstract class AbsGroupsFragment<Data> extends AbsContentListRecyclerViewFragmen
|
|||||||
@Override
|
@Override
|
||||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||||
super.onActivityCreated(savedInstanceState);
|
super.onActivityCreated(savedInstanceState);
|
||||||
final AbsGroupsAdapter<Data> adapter = getAdapter();
|
final AbsGroupsAdapter<List<ParcelableGroup>> adapter = getAdapter();
|
||||||
final RecyclerView recyclerView = getRecyclerView();
|
final RecyclerView recyclerView = getRecyclerView();
|
||||||
final LinearLayoutManager layoutManager = getLayoutManager();
|
final LinearLayoutManager layoutManager = getLayoutManager();
|
||||||
adapter.setListener(this);
|
adapter.setListener(this);
|
||||||
@ -86,32 +144,14 @@ abstract class AbsGroupsFragment<Data> extends AbsContentListRecyclerViewFragmen
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
final boolean fromUser = args.getBoolean(EXTRA_FROM_USER);
|
||||||
args.remove(EXTRA_FROM_USER);
|
args.remove(EXTRA_FROM_USER);
|
||||||
return onCreateUserListsLoader(getActivity(), args, fromUser);
|
return onCreateUserListsLoader(getActivity(), args, fromUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoadFinished(Loader<Data> loader, Data data) {
|
public void onLoaderReset(Loader<List<ParcelableGroup>> loader) {
|
||||||
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) {
|
|
||||||
if (loader instanceof IExtendedLoader) {
|
if (loader instanceof IExtendedLoader) {
|
||||||
((IExtendedLoader) loader).setFromUser(false);
|
((IExtendedLoader) loader).setFromUser(false);
|
||||||
}
|
}
|
||||||
@ -135,14 +175,5 @@ abstract class AbsGroupsFragment<Data> extends AbsContentListRecyclerViewFragmen
|
|||||||
return mNextCursor;
|
return mNextCursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract Loader<List<ParcelableGroup>> onCreateUserListsLoader(Context context, Bundle args, boolean fromUser);
|
||||||
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);
|
|
||||||
|
|
||||||
}
|
}
|
@ -20,17 +20,37 @@
|
|||||||
package org.mariotaku.twidere.fragment.support;
|
package org.mariotaku.twidere.fragment.support;
|
||||||
|
|
||||||
import android.content.Context;
|
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.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.v4.app.FragmentActivity;
|
||||||
import android.support.v4.app.LoaderManager;
|
import android.support.v4.app.LoaderManager;
|
||||||
import android.support.v4.content.Loader;
|
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.ParcelableUsersAdapter;
|
||||||
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosition;
|
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.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;
|
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
|
@Override
|
||||||
public boolean isRefreshing() {
|
public boolean isRefreshing() {
|
||||||
@ -48,17 +68,24 @@ public abstract class ParcelableUsersFragment extends AbsUsersFragment<List<Parc
|
|||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public ParcelableUsersAdapter getAdapter() {
|
public ParcelableUsersAdapter getAdapter() {
|
||||||
return (ParcelableUsersAdapter) super.getAdapter();
|
return super.getAdapter();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean hasMoreData(List<ParcelableUser> data) {
|
protected boolean hasMoreData(List<ParcelableUser> data) {
|
||||||
return data == null || !data.isEmpty();
|
return data == null || !data.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoadFinished(Loader<List<ParcelableUser>> loader, List<ParcelableUser> data) {
|
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);
|
setRefreshEnabled(true);
|
||||||
setRefreshing(false);
|
setRefreshing(false);
|
||||||
setLoadMoreIndicatorPosition(IndicatorPosition.NONE);
|
setLoadMoreIndicatorPosition(IndicatorPosition.NONE);
|
||||||
@ -68,4 +95,88 @@ public abstract class ParcelableUsersFragment extends AbsUsersFragment<List<Parc
|
|||||||
//TODO remove from adapter
|
//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);
|
mProfileImageView.setOnClickListener(this);
|
||||||
mProfileBannerView.setOnClickListener(this);
|
mProfileBannerView.setOnClickListener(this);
|
||||||
mListedContainer.setOnClickListener(this);
|
mListedContainer.setOnClickListener(this);
|
||||||
|
mGroupsContainer.setOnClickListener(this);
|
||||||
mFollowersContainer.setOnClickListener(this);
|
mFollowersContainer.setOnClickListener(this);
|
||||||
mFriendsContainer.setOnClickListener(this);
|
mFriendsContainer.setOnClickListener(this);
|
||||||
mHeaderErrorIcon.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) {
|
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;
|
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.R;
|
||||||
import org.mariotaku.twidere.adapter.iface.IGroupsAdapter;
|
import org.mariotaku.twidere.adapter.iface.IGroupsAdapter;
|
||||||
import org.mariotaku.twidere.model.ParcelableGroup;
|
import org.mariotaku.twidere.model.ParcelableGroup;
|
||||||
|
import org.mariotaku.twidere.model.util.UserKeyUtils;
|
||||||
import org.mariotaku.twidere.util.MediaLoaderWrapper;
|
import org.mariotaku.twidere.util.MediaLoaderWrapper;
|
||||||
import org.mariotaku.twidere.util.UserColorNameManager;
|
|
||||||
import org.mariotaku.twidere.util.Utils;
|
import org.mariotaku.twidere.util.Utils;
|
||||||
|
import org.mariotaku.twidere.view.NameView;
|
||||||
import org.mariotaku.twidere.view.iface.IColorLabelView;
|
import org.mariotaku.twidere.view.iface.IColorLabelView;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@ -45,11 +46,11 @@ public class GroupViewHolder extends ViewHolder implements View.OnClickListener,
|
|||||||
|
|
||||||
private final IColorLabelView itemContent;
|
private final IColorLabelView itemContent;
|
||||||
private final ImageView profileImageView;
|
private final ImageView profileImageView;
|
||||||
private final TextView nameView;
|
private final NameView nameView;
|
||||||
private final TextView createdByView;
|
private final TextView externalIndicator;
|
||||||
private final TextView descriptionView;
|
private final TextView descriptionView;
|
||||||
private final TextView membersCountView;
|
private final TextView membersCountView;
|
||||||
private final TextView subscribersCountView;
|
private final TextView adminsCountView;
|
||||||
|
|
||||||
private IGroupsAdapter.GroupAdapterListener groupClickListener;
|
private IGroupsAdapter.GroupAdapterListener groupClickListener;
|
||||||
|
|
||||||
@ -58,22 +59,26 @@ public class GroupViewHolder extends ViewHolder implements View.OnClickListener,
|
|||||||
itemContent = (IColorLabelView) itemView.findViewById(R.id.item_content);
|
itemContent = (IColorLabelView) itemView.findViewById(R.id.item_content);
|
||||||
this.adapter = adapter;
|
this.adapter = adapter;
|
||||||
profileImageView = (ImageView) itemView.findViewById(R.id.profile_image);
|
profileImageView = (ImageView) itemView.findViewById(R.id.profile_image);
|
||||||
nameView = (TextView) itemView.findViewById(R.id.name);
|
nameView = (NameView) itemView.findViewById(R.id.name);
|
||||||
createdByView = (TextView) itemView.findViewById(R.id.created_by);
|
externalIndicator = (TextView) itemView.findViewById(R.id.external_indicator);
|
||||||
descriptionView = (TextView) itemView.findViewById(R.id.description);
|
descriptionView = (TextView) itemView.findViewById(R.id.description);
|
||||||
membersCountView = (TextView) itemView.findViewById(R.id.members_count);
|
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) {
|
public void displayGroup(ParcelableGroup group) {
|
||||||
|
|
||||||
final Context context = adapter.getContext();
|
final Context context = adapter.getContext();
|
||||||
final MediaLoaderWrapper loader = adapter.getMediaLoader();
|
final MediaLoaderWrapper loader = adapter.getMediaLoader();
|
||||||
final UserColorNameManager manager = adapter.getUserColorNameManager();
|
nameView.setName(group.fullname);
|
||||||
|
nameView.setScreenName("!" + group.nickname);
|
||||||
nameView.setText(group.fullname);
|
final String groupHost = UserKeyUtils.getUserHost(group.url);
|
||||||
final boolean nameFirst = adapter.isNameFirst();
|
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()) {
|
if (adapter.isProfileImageEnabled()) {
|
||||||
profileImageView.setVisibility(View.VISIBLE);
|
profileImageView.setVisibility(View.VISIBLE);
|
||||||
loader.displayProfileImage(profileImageView, group.homepage_logo);
|
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.setVisibility(TextUtils.isEmpty(group.description) ? View.GONE : View.VISIBLE);
|
||||||
descriptionView.setText(group.description);
|
descriptionView.setText(group.description);
|
||||||
membersCountView.setText(Utils.getLocalizedNumber(Locale.getDefault(), group.member_count));
|
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() {
|
public void setOnClickListeners() {
|
||||||
@ -124,8 +129,12 @@ public class GroupViewHolder extends ViewHolder implements View.OnClickListener,
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setTextSize(final float textSize) {
|
public void setTextSize(final float textSize) {
|
||||||
nameView.setTextSize(textSize);
|
descriptionView.setTextSize(textSize);
|
||||||
createdByView.setTextSize(textSize * 0.75f);
|
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="uploader_version_incompatible">Incompatible media uploader</string>
|
||||||
<string name="groups">Groups</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_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>
|
</resources>
|
Loading…
x
Reference in New Issue
Block a user