mirror of
https://github.com/TwidereProject/Twidere-Android
synced 2024-12-18 03:28:55 +01:00
used my CircularImageView implementation
This commit is contained in:
parent
49742e7446
commit
22351c2916
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -10,3 +10,6 @@
|
||||
[submodule "libraries/RefreshNow"]
|
||||
path = libraries/RefreshNow
|
||||
url = https://github.com/mariotaku/RefreshNow-Android
|
||||
[submodule "libraries/PullToRefresh"]
|
||||
path = libraries/PullToRefresh
|
||||
url = https://github.com/mariotaku/Android-PullToRefresh-Gradle.git
|
||||
|
10
build.gradle
10
build.gradle
@ -1,11 +1,12 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
apply plugin: 'idea'
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:0.12.+'
|
||||
classpath 'com.android.tools.build:gradle:0.13.2'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
@ -17,3 +18,10 @@ allprojects {
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
idea {
|
||||
module {
|
||||
downloadJavadoc = true
|
||||
downloadSources = true
|
||||
}
|
||||
}
|
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,6 +1,6 @@
|
||||
#Wed Apr 10 15:27:10 PDT 2013
|
||||
#Thu Nov 20 21:01:22 CST 2014
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.1-all.zip
|
||||
|
1
libraries/PullToRefresh
Submodule
1
libraries/PullToRefresh
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 5ca6a6cfb871ad4a273abeee8b97d8cc046b7f19
|
@ -1,7 +1,8 @@
|
||||
include ':twidere', ':twidere.wear'
|
||||
include ':SlidingMenu', ':DragSortListView', ':MenuComponent', ':RefreshNow'
|
||||
include ':SlidingMenu', ':DragSortListView', ':MenuComponent', ':RefreshNow', ':PullToRefresh'
|
||||
|
||||
project(':SlidingMenu').projectDir = file('libraries/SlidingMenu/library')
|
||||
project(':DragSortListView').projectDir = file('libraries/DragSortListView/library')
|
||||
project(':MenuComponent').projectDir = file('libraries/MenuComponent/library')
|
||||
project(':RefreshNow').projectDir = file('libraries/RefreshNow/library')
|
||||
project(':RefreshNow').projectDir = file('libraries/RefreshNow/library')
|
||||
project(':PullToRefresh').projectDir = file('libraries/PullToRefresh/library')
|
@ -93,7 +93,7 @@ dependencies {
|
||||
compile 'ch.acra:acra:4.5.0'
|
||||
compile 'com.google.android.apps.dashclock:dashclock-api:2.0.0'
|
||||
compile 'me.grantland:autofittextview:0.2.0'
|
||||
compile 'com.pkmmte.view:circularimageview:1.1'
|
||||
// compile 'com.pkmmte.view:circularimageview:1.1'
|
||||
googleCompile 'com.google.android.gms:play-services:6.1.71'
|
||||
fdroidCompile 'org.osmdroid:osmdroid-android:4.2'
|
||||
fdroidCompile 'org.slf4j:slf4j-simple:1.6.1'
|
||||
@ -101,5 +101,6 @@ dependencies {
|
||||
compile project(':DragSortListView')
|
||||
compile project(':MenuComponent')
|
||||
compile project(':RefreshNow')
|
||||
compile project(':PullToRefresh')
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ package org.mariotaku.twidere;
|
||||
public interface Constants extends TwidereConstants {
|
||||
|
||||
public static final String DATABASES_NAME = "twidere.sqlite";
|
||||
public static final int DATABASES_VERSION = 70;
|
||||
public static final int DATABASES_VERSION = 71;
|
||||
|
||||
public static final int MENU_GROUP_STATUS_EXTENSION = 10;
|
||||
public static final int MENU_GROUP_COMPOSE_EXTENSION = 11;
|
||||
|
@ -108,7 +108,7 @@ import org.mariotaku.twidere.util.accessor.ViewAccessor;
|
||||
import org.mariotaku.twidere.view.ColorLabelFrameLayout;
|
||||
import org.mariotaku.twidere.view.StatusTextCountView;
|
||||
import org.mariotaku.twidere.view.TwidereMenuBar;
|
||||
import org.mariotaku.twidere.view.holder.StatusViewHolder;
|
||||
import org.mariotaku.twidere.view.holder.StatusListViewHolder;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
@ -1187,7 +1187,7 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa
|
||||
|
||||
public static class ViewStatusDialogFragment extends BaseSupportDialogFragment {
|
||||
|
||||
private StatusViewHolder mHolder;
|
||||
private StatusListViewHolder mHolder;
|
||||
|
||||
public ViewStatusDialogFragment() {
|
||||
setStyle(STYLE_NO_TITLE, 0);
|
||||
@ -1268,7 +1268,7 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa
|
||||
@Override
|
||||
public View onCreateView(final LayoutInflater inflater, final ViewGroup parent, final Bundle savedInstanceState) {
|
||||
final ScrollView view = (ScrollView) inflater.inflate(R.layout.dialog_scrollable_status, parent, false);
|
||||
mHolder = new StatusViewHolder(view.getChildAt(0));
|
||||
mHolder = new StatusListViewHolder(view.getChildAt(0));
|
||||
return view;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,111 @@
|
||||
package org.mariotaku.twidere.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v7.widget.RecyclerView.Adapter;
|
||||
import android.support.v7.widget.RecyclerView.ViewHolder;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.iface.IStatusesAdapter;
|
||||
import org.mariotaku.twidere.app.TwidereApplication;
|
||||
import org.mariotaku.twidere.view.holder.LoadIndicatorViewHolder;
|
||||
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
||||
import org.mariotaku.twidere.util.ImageLoadingHandler;
|
||||
import org.mariotaku.twidere.view.holder.StatusViewHolder;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/11/19.
|
||||
*/
|
||||
public abstract class AbsStatusesAdapter extends Adapter<ViewHolder> implements IStatusesAdapter {
|
||||
|
||||
private static final int ITEM_VIEW_TYPE_STATUS = 1;
|
||||
private static final int ITEM_VIEW_TYPE_LOAD_INDICATOR = 2;
|
||||
|
||||
private final Context mContext;
|
||||
private final LayoutInflater mInflater;
|
||||
private final ImageLoaderWrapper mImageLoader;
|
||||
private final ImageLoadingHandler mLoadingHandler;
|
||||
private final int mCardLayoutResource;
|
||||
private boolean mLoadMoreIndicatorEnabled;
|
||||
|
||||
public AbsStatusesAdapter(Context context, boolean compact) {
|
||||
mContext = context;
|
||||
mInflater = LayoutInflater.from(context);
|
||||
mImageLoader = TwidereApplication.getInstance(context).getImageLoaderWrapper();
|
||||
mLoadingHandler = new ImageLoadingHandler(R.id.media_preview_progress);
|
||||
if (compact) {
|
||||
mCardLayoutResource = R.layout.card_item_list_status_compat;
|
||||
} else {
|
||||
mCardLayoutResource = R.layout.card_item_list_status;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
switch (viewType) {
|
||||
case ITEM_VIEW_TYPE_STATUS: {
|
||||
final View view = mInflater.inflate(mCardLayoutResource, parent, false);
|
||||
return new StatusViewHolder(this, view);
|
||||
}
|
||||
case ITEM_VIEW_TYPE_LOAD_INDICATOR: {
|
||||
final View view = mInflater.inflate(R.layout.card_item_load_indicator, parent, false);
|
||||
return new LoadIndicatorViewHolder(view);
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("Unknown view type " + viewType);
|
||||
}
|
||||
|
||||
public void setLoadMoreIndicatorEnabled(boolean enabled) {
|
||||
if (mLoadMoreIndicatorEnabled == enabled) return;
|
||||
mLoadMoreIndicatorEnabled = enabled;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public boolean hasLoadMoreIndicator() {
|
||||
return mLoadMoreIndicatorEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(ViewHolder holder, int position) {
|
||||
switch (holder.getItemViewType()) {
|
||||
case ITEM_VIEW_TYPE_STATUS: {
|
||||
bindStatus(((StatusViewHolder) holder), position);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void bindStatus(StatusViewHolder holder, int position);
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if (position == getItemCount() - 1) {
|
||||
return ITEM_VIEW_TYPE_LOAD_INDICATOR;
|
||||
}
|
||||
return ITEM_VIEW_TYPE_STATUS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getItemCount() {
|
||||
return getStatusCount() + (mLoadMoreIndicatorEnabled ? 1 : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageLoaderWrapper getImageLoader() {
|
||||
return mImageLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context getContext() {
|
||||
return mContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageLoadingHandler getImageLoadingHandler() {
|
||||
return mLoadingHandler;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -38,7 +38,7 @@ import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.model.ParcelableUser;
|
||||
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
||||
import org.mariotaku.twidere.util.MultiSelectManager;
|
||||
import org.mariotaku.twidere.view.holder.ActivityViewHolder;
|
||||
import org.mariotaku.twidere.view.holder.ActivityListViewHolder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -67,7 +67,7 @@ public abstract class BaseParcelableActivitiesAdapter extends BaseArrayAdapter<P
|
||||
configBaseCardAdapter(context, this);
|
||||
}
|
||||
|
||||
public abstract void bindView(final int position, final ActivityViewHolder holder, final ParcelableActivity item);
|
||||
public abstract void bindView(final int position, final ActivityListViewHolder holder, final ParcelableActivity item);
|
||||
|
||||
@Override
|
||||
public ImageLoaderWrapper getImageLoader() {
|
||||
@ -84,9 +84,9 @@ public abstract class BaseParcelableActivitiesAdapter extends BaseArrayAdapter<P
|
||||
public View getView(final int position, final View convertView, final ViewGroup parent) {
|
||||
final View view = super.getView(position, convertView, parent);
|
||||
final Object tag = view.getTag();
|
||||
final ActivityViewHolder holder = tag instanceof ActivityViewHolder ? (ActivityViewHolder) tag
|
||||
: new ActivityViewHolder(view);
|
||||
if (!(tag instanceof ActivityViewHolder)) {
|
||||
final ActivityListViewHolder holder = tag instanceof ActivityListViewHolder ? (ActivityListViewHolder) tag
|
||||
: new ActivityListViewHolder(view);
|
||||
if (!(tag instanceof ActivityListViewHolder)) {
|
||||
if (mPlainList) {
|
||||
((View) holder.content).setPadding(0, 0, 0, 0);
|
||||
holder.content.setItemBackground(null);
|
||||
@ -149,7 +149,7 @@ public abstract class BaseParcelableActivitiesAdapter extends BaseArrayAdapter<P
|
||||
}
|
||||
}
|
||||
|
||||
protected void displayActivityUserProfileImages(final ActivityViewHolder holder, final ParcelableStatus[] statuses) {
|
||||
protected void displayActivityUserProfileImages(final ActivityListViewHolder holder, final ParcelableStatus[] statuses) {
|
||||
if (statuses == null) {
|
||||
displayActivityUserProfileImages(holder, new String[0]);
|
||||
} else {
|
||||
@ -161,7 +161,7 @@ public abstract class BaseParcelableActivitiesAdapter extends BaseArrayAdapter<P
|
||||
}
|
||||
}
|
||||
|
||||
protected void displayActivityUserProfileImages(final ActivityViewHolder holder, final ParcelableUser[] users) {
|
||||
protected void displayActivityUserProfileImages(final ActivityListViewHolder holder, final ParcelableUser[] users) {
|
||||
if (users == null) {
|
||||
displayActivityUserProfileImages(holder, new String[0]);
|
||||
} else {
|
||||
@ -205,7 +205,7 @@ public abstract class BaseParcelableActivitiesAdapter extends BaseArrayAdapter<P
|
||||
return isDisplayProfileImage();
|
||||
}
|
||||
|
||||
private void displayActivityUserProfileImages(final ActivityViewHolder holder, final String[] urls) {
|
||||
private void displayActivityUserProfileImages(final ActivityListViewHolder holder, final String[] urls) {
|
||||
final int length = urls != null ? Math.min(holder.activity_profile_images.length, urls.length) : 0;
|
||||
final boolean shouldDisplayImages = isDisplayProfileImage() && length > 0;
|
||||
holder.activity_profile_images_container.setVisibility(shouldDisplayImages ? View.VISIBLE : View.GONE);
|
||||
|
@ -43,7 +43,7 @@ import org.mariotaku.twidere.util.ImageLoadingHandler;
|
||||
import org.mariotaku.twidere.util.MultiSelectManager;
|
||||
import org.mariotaku.twidere.util.TwidereLinkify;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.view.holder.StatusViewHolder;
|
||||
import org.mariotaku.twidere.view.holder.StatusListViewHolder;
|
||||
import org.mariotaku.twidere.view.iface.ICardItemView.OnOverflowIconClickListener;
|
||||
|
||||
import java.util.Locale;
|
||||
@ -105,7 +105,7 @@ public class CursorStatusesAdapter extends BaseCursorAdapter implements IStatuse
|
||||
@Override
|
||||
public void bindView(final View view, final Context context, final Cursor cursor) {
|
||||
final int position = cursor.getPosition();
|
||||
final StatusViewHolder holder = (StatusViewHolder) view.getTag();
|
||||
final StatusListViewHolder holder = (StatusListViewHolder) view.getTag();
|
||||
|
||||
final boolean isGap = cursor.getShort(mIndices.is_gap) == 1;
|
||||
final boolean showGap = isGap && !mGapDisallowed && position != getCount() - 1;
|
||||
@ -263,7 +263,7 @@ public class CursorStatusesAdapter extends BaseCursorAdapter implements IStatuse
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getActualCount() {
|
||||
public int getStatusCount() {
|
||||
return super.getCount();
|
||||
}
|
||||
|
||||
@ -293,6 +293,16 @@ public class CursorStatusesAdapter extends BaseCursorAdapter implements IStatuse
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context getContext() {
|
||||
return mContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageLoadingHandler getImageLoadingHandler() {
|
||||
return mImageLoadingHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelableStatus getStatus(final int position) {
|
||||
final Cursor c = getCursor();
|
||||
@ -312,9 +322,9 @@ public class CursorStatusesAdapter extends BaseCursorAdapter implements IStatuse
|
||||
final View view = super.getView(position, convertView, parent);
|
||||
final Object tag = view.getTag();
|
||||
// animate the item
|
||||
if (tag instanceof StatusViewHolder && position > mMaxAnimationPosition) {
|
||||
if (tag instanceof StatusListViewHolder && position > mMaxAnimationPosition) {
|
||||
if (mAnimationEnabled) {
|
||||
view.startAnimation(((StatusViewHolder) tag).item_animation);
|
||||
view.startAnimation(((StatusListViewHolder) tag).item_animation);
|
||||
}
|
||||
mMaxAnimationPosition = position;
|
||||
}
|
||||
@ -330,8 +340,8 @@ public class CursorStatusesAdapter extends BaseCursorAdapter implements IStatuse
|
||||
public View newView(final Context context, final Cursor cursor, final ViewGroup parent) {
|
||||
final View view = super.newView(context, cursor, parent);
|
||||
final Object tag = view.getTag();
|
||||
if (!(tag instanceof StatusViewHolder)) {
|
||||
final StatusViewHolder holder = new StatusViewHolder(view);
|
||||
if (!(tag instanceof StatusListViewHolder)) {
|
||||
final StatusListViewHolder holder = new StatusListViewHolder(view);
|
||||
holder.profile_image.setOnClickListener(this);
|
||||
holder.my_profile_image.setOnClickListener(this);
|
||||
holder.image_preview.setOnClickListener(this);
|
||||
@ -374,8 +384,8 @@ public class CursorStatusesAdapter extends BaseCursorAdapter implements IStatuse
|
||||
public void onOverflowIconClick(final View view) {
|
||||
if (mMultiSelectManager.isActive()) return;
|
||||
final Object tag = view.getTag();
|
||||
if (tag instanceof StatusViewHolder) {
|
||||
final StatusViewHolder holder = (StatusViewHolder) tag;
|
||||
if (tag instanceof StatusListViewHolder) {
|
||||
final StatusListViewHolder holder = (StatusListViewHolder) tag;
|
||||
final int position = holder.position;
|
||||
if (position == -1 || mListener == null) return;
|
||||
mListener.onMenuButtonClick(view, position, getItemId(position));
|
||||
|
@ -38,7 +38,7 @@ import org.mariotaku.twidere.model.ParcelableUserList;
|
||||
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
||||
import org.mariotaku.twidere.util.ImageLoadingHandler;
|
||||
import org.mariotaku.twidere.util.TwidereLinkify;
|
||||
import org.mariotaku.twidere.view.holder.ActivityViewHolder;
|
||||
import org.mariotaku.twidere.view.holder.ActivityListViewHolder;
|
||||
|
||||
public class ParcelableActivitiesAboutMeAdapter extends BaseParcelableActivitiesAdapter {
|
||||
|
||||
@ -56,7 +56,7 @@ public class ParcelableActivitiesAboutMeAdapter extends BaseParcelableActivities
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindView(final int position, final ActivityViewHolder holder, final ParcelableActivity item) {
|
||||
public void bindView(final int position, final ActivityListViewHolder holder, final ParcelableActivity item) {
|
||||
if (item == null) return;
|
||||
final ParcelableUser[] sources = item.sources;
|
||||
if (sources == null || sources.length == 0) return;
|
||||
@ -196,7 +196,7 @@ public class ParcelableActivitiesAboutMeAdapter extends BaseParcelableActivities
|
||||
}
|
||||
}
|
||||
|
||||
private void displayStatus(final ParcelableStatus status, final ActivityViewHolder holder, final int position) {
|
||||
private void displayStatus(final ParcelableStatus status, final ActivityListViewHolder holder, final int position) {
|
||||
|
||||
final boolean showGap = status.is_gap && !mGapDisallowed && position != getCount() - 1;
|
||||
final boolean displayProfileImage = isDisplayProfileImage();
|
||||
|
@ -30,7 +30,7 @@ import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.model.ParcelableUser;
|
||||
import org.mariotaku.twidere.model.ParcelableUserList;
|
||||
import org.mariotaku.twidere.util.TwidereLinkify;
|
||||
import org.mariotaku.twidere.view.holder.ActivityViewHolder;
|
||||
import org.mariotaku.twidere.view.holder.ActivityListViewHolder;
|
||||
|
||||
public class ParcelableActivitiesByFriendsAdapter extends BaseParcelableActivitiesAdapter {
|
||||
|
||||
@ -40,7 +40,7 @@ public class ParcelableActivitiesByFriendsAdapter extends BaseParcelableActiviti
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindView(final int position, final ActivityViewHolder holder, final ParcelableActivity item) {
|
||||
public void bindView(final int position, final ActivityListViewHolder holder, final ParcelableActivity item) {
|
||||
if (item == null) return;
|
||||
final ParcelableUser[] sources = item.sources;
|
||||
final ParcelableStatus[] targetStatuses = item.target_statuses;
|
||||
|
@ -1,445 +1,46 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.adapter;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.text.Html;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView.ScaleType;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.iface.IStatusesListAdapter;
|
||||
import org.mariotaku.twidere.app.TwidereApplication;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.model.ParcelableUserMention;
|
||||
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
||||
import org.mariotaku.twidere.util.ImageLoadingHandler;
|
||||
import org.mariotaku.twidere.util.MultiSelectManager;
|
||||
import org.mariotaku.twidere.util.TwidereLinkify;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.view.holder.StatusViewHolder;
|
||||
import org.mariotaku.twidere.view.iface.ICardItemView.OnOverflowIconClickListener;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static org.mariotaku.twidere.model.ParcelableLocation.isValidLocation;
|
||||
import static org.mariotaku.twidere.util.UserColorNicknameUtils.getUserColor;
|
||||
import static org.mariotaku.twidere.util.UserColorNicknameUtils.getUserNickname;
|
||||
import static org.mariotaku.twidere.util.Utils.configBaseCardAdapter;
|
||||
import static org.mariotaku.twidere.util.Utils.getAccountColor;
|
||||
import static org.mariotaku.twidere.util.Utils.getCardHighlightColor;
|
||||
import static org.mariotaku.twidere.util.Utils.getCardHighlightOptionInt;
|
||||
import static org.mariotaku.twidere.util.Utils.isFiltered;
|
||||
import static org.mariotaku.twidere.util.Utils.openImage;
|
||||
import static org.mariotaku.twidere.util.Utils.openUserProfile;
|
||||
/**
|
||||
* Created by mariotaku on 14/11/19.
|
||||
*/
|
||||
public class ParcelableStatusesAdapter extends AbsStatusesAdapter {
|
||||
|
||||
public class ParcelableStatusesAdapter extends BaseArrayAdapter<ParcelableStatus> implements
|
||||
IStatusesListAdapter<List<ParcelableStatus>>, OnClickListener, OnOverflowIconClickListener {
|
||||
private List<ParcelableStatus> mData;
|
||||
|
||||
private final Context mContext;
|
||||
private final MultiSelectManager mMultiSelectManager;
|
||||
private final SQLiteDatabase mDatabase;
|
||||
private final ImageLoadingHandler mImageLoadingHandler;
|
||||
|
||||
private MenuButtonClickListener mListener;
|
||||
|
||||
private final boolean mPlainList;
|
||||
|
||||
private boolean mDisplayImagePreview, mGapDisallowed, mMentionsHighlightDisabled, mFavoritesHighlightDisabled,
|
||||
mDisplaySensitiveContents, mIndicateMyStatusDisabled, mIsLastItemFiltered, mFiltersEnabled,
|
||||
mAnimationEnabled;
|
||||
private boolean mFilterIgnoreUser, mFilterIgnoreSource, mFilterIgnoreTextHtml, mFilterIgnoreTextPlain,
|
||||
mFilterRetweetedById;
|
||||
private int mMaxAnimationPosition, mCardHighlightOption;
|
||||
private ScaleType mImagePreviewScaleType;
|
||||
private String[] mHighlightKeywords;
|
||||
|
||||
public ParcelableStatusesAdapter(final Context context) {
|
||||
this(context, Utils.isCompactCards(context), Utils.isPlainListStyle(context));
|
||||
}
|
||||
|
||||
public ParcelableStatusesAdapter(final Context context, final boolean compactCards, final boolean plainList) {
|
||||
super(context, getItemResource(compactCards));
|
||||
mPlainList = plainList;
|
||||
mContext = context;
|
||||
final TwidereApplication app = TwidereApplication.getInstance(context);
|
||||
mMultiSelectManager = app.getMultiSelectManager();
|
||||
mDatabase = app.getSQLiteDatabase();
|
||||
mImageLoadingHandler = new ImageLoadingHandler();
|
||||
configBaseCardAdapter(context, this);
|
||||
setMaxAnimationPosition(-1);
|
||||
public ParcelableStatusesAdapter(Context context, boolean compact) {
|
||||
super(context, compact);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int findPositionByStatusId(final long status_id) {
|
||||
for (int i = 0, count = getCount(); i < count; i++) {
|
||||
if (getItem(i).id == status_id) return i;
|
||||
}
|
||||
return -1;
|
||||
protected void bindStatus(StatusViewHolder holder, int position) {
|
||||
holder.displayStatus(getStatus(position));
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getAccountId(final int position) {
|
||||
if (position >= 0 && position < getCount()) {
|
||||
final ParcelableStatus status = getItem(position);
|
||||
return status != null ? status.account_id : -1;
|
||||
}
|
||||
return -1;
|
||||
public ParcelableStatus getStatus(int position) {
|
||||
if (hasLoadMoreIndicator() && position == getStatusCount() - 1) return null;
|
||||
return mData.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getActualCount() {
|
||||
return super.getCount();
|
||||
public int getStatusCount() {
|
||||
if (mData == null) return 0;
|
||||
return mData.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
final int count = super.getCount();
|
||||
return mFiltersEnabled && mIsLastItemFiltered && count > 0 ? count - 1 : count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(final int position) {
|
||||
final ParcelableStatus item = getItem(position);
|
||||
return item != null ? item.id : -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelableStatus getLastStatus() {
|
||||
if (super.getCount() == 0) return null;
|
||||
return getItem(super.getCount() - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastStatusId() {
|
||||
if (super.getCount() == 0) return -1;
|
||||
return getItem(super.getCount() - 1).id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelableStatus getStatus(final int position) {
|
||||
return getItem(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getStatusId(final int position) {
|
||||
if (position >= 0 && position < getCount()) {
|
||||
final ParcelableStatus status = getItem(position);
|
||||
return status != null ? status.id : -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(final int position, final View convertView, final ViewGroup parent) {
|
||||
final View view = super.getView(position, convertView, parent);
|
||||
final Object tag = view.getTag();
|
||||
final StatusViewHolder holder;
|
||||
|
||||
if (tag instanceof StatusViewHolder) {
|
||||
holder = (StatusViewHolder) tag;
|
||||
} else {
|
||||
holder = new StatusViewHolder(view);
|
||||
holder.profile_image.setOnClickListener(this);
|
||||
holder.my_profile_image.setOnClickListener(this);
|
||||
holder.image_preview.setOnClickListener(this);
|
||||
holder.content.setOnOverflowIconClickListener(this);
|
||||
if (mPlainList) {
|
||||
((View) holder.content).setPadding(0, 0, 0, 0);
|
||||
holder.content.setItemBackground(null);
|
||||
}
|
||||
view.setTag(holder);
|
||||
}
|
||||
|
||||
final ParcelableStatus status = getItem(position);
|
||||
|
||||
final boolean showGap = status.is_gap && !mGapDisallowed && position != getCount() - 1;
|
||||
|
||||
holder.position = position;
|
||||
holder.setShowAsGap(showGap);
|
||||
holder.setDisplayProfileImage(isDisplayProfileImage());
|
||||
holder.setCardHighlightOption(mCardHighlightOption);
|
||||
|
||||
final ImageLoaderWrapper loader = getImageLoader();
|
||||
if (!showGap) {
|
||||
final TwidereLinkify linkify = getLinkify();
|
||||
final int highlightOption = getLinkHighlightOption();
|
||||
final boolean mShowAccountColor = isShowAccountColor();
|
||||
|
||||
holder.setAccountColorEnabled(mShowAccountColor);
|
||||
|
||||
if (highlightOption != VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE) {
|
||||
holder.text.setText(Utils.getKeywordBoldedText(Html.fromHtml(status.text_html), mHighlightKeywords));
|
||||
linkify.applyAllLinks(holder.text, status.account_id, status.is_possibly_sensitive);
|
||||
holder.text.setMovementMethod(null);
|
||||
} else {
|
||||
if (mHighlightKeywords == null || mHighlightKeywords.length == 0) {
|
||||
holder.text.setText(status.text_unescaped);
|
||||
} else {
|
||||
holder.text.setText(Utils.getKeywordBoldedText(status.text_unescaped, mHighlightKeywords));
|
||||
}
|
||||
}
|
||||
|
||||
if (mShowAccountColor) {
|
||||
holder.setAccountColor(getAccountColor(mContext, status.account_id));
|
||||
}
|
||||
|
||||
final boolean isMention = ParcelableUserMention.hasMention(status.mentions, status.account_id);
|
||||
final boolean isMyStatus = status.account_id == status.user_id;
|
||||
final boolean hasMedia = status.first_media != null;
|
||||
if (status.is_retweet) {
|
||||
holder.setUserColor(getUserColor(mContext, status.user_id),
|
||||
getUserColor(mContext, status.retweeted_by_id));
|
||||
} else {
|
||||
holder.setUserColor(getUserColor(mContext, status.user_id));
|
||||
}
|
||||
holder.setHighlightColor(getCardHighlightColor(!mMentionsHighlightDisabled && isMention,
|
||||
!mFavoritesHighlightDisabled && status.is_favorite, status.is_retweet));
|
||||
holder.setTextSize(getTextSize());
|
||||
|
||||
holder.setIsMyStatus(isMyStatus && !mIndicateMyStatusDisabled);
|
||||
|
||||
holder.setUserType(status.user_is_verified, status.user_is_protected);
|
||||
holder.setDisplayNameFirst(isDisplayNameFirst());
|
||||
holder.setNicknameOnly(isNicknameOnly());
|
||||
final String nick = getUserNickname(mContext, status.user_id);
|
||||
holder.name.setText(TextUtils.isEmpty(nick) ? status.user_name : isNicknameOnly() ? nick : mContext
|
||||
.getString(R.string.name_with_nickname, status.user_name, nick));
|
||||
holder.screen_name.setText("@" + status.user_screen_name);
|
||||
if (highlightOption != VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE) {
|
||||
linkify.applyUserProfileLinkNoHighlight(holder.name, status.account_id, status.user_id,
|
||||
status.user_screen_name);
|
||||
linkify.applyUserProfileLinkNoHighlight(holder.screen_name, status.account_id, status.user_id,
|
||||
status.user_screen_name);
|
||||
holder.name.setMovementMethod(null);
|
||||
holder.screen_name.setMovementMethod(null);
|
||||
}
|
||||
holder.time.setTime(status.retweet_timestamp > 0 ? status.retweet_timestamp : status.timestamp);
|
||||
holder.setStatusType(!mFavoritesHighlightDisabled && status.is_favorite, isValidLocation(status.location),
|
||||
hasMedia, status.is_possibly_sensitive);
|
||||
holder.setIsReplyRetweet(status.in_reply_to_status_id > 0, status.is_retweet);
|
||||
if (status.is_retweet) {
|
||||
holder.setRetweetedBy(status.retweet_count, status.retweeted_by_id, status.retweeted_by_name,
|
||||
status.retweeted_by_screen_name);
|
||||
} else if (status.in_reply_to_status_id > 0) {
|
||||
holder.setReplyTo(status.in_reply_to_user_id, status.in_reply_to_name, status.in_reply_to_screen_name);
|
||||
}
|
||||
if (isDisplayProfileImage()) {
|
||||
loader.displayProfileImage(holder.my_profile_image, status.user_profile_image_url);
|
||||
loader.displayProfileImage(holder.profile_image, status.user_profile_image_url);
|
||||
holder.profile_image.setTag(position);
|
||||
holder.my_profile_image.setTag(position);
|
||||
} else {
|
||||
loader.cancelDisplayTask(holder.profile_image);
|
||||
loader.cancelDisplayTask(holder.my_profile_image);
|
||||
holder.profile_image.setVisibility(View.GONE);
|
||||
holder.my_profile_image.setVisibility(View.GONE);
|
||||
}
|
||||
final boolean hasPreview = mDisplayImagePreview && hasMedia;
|
||||
holder.image_preview_container.setVisibility(hasPreview ? View.VISIBLE : View.GONE);
|
||||
if (hasPreview) {
|
||||
if (mImagePreviewScaleType != null) {
|
||||
holder.image_preview.setScaleType(mImagePreviewScaleType);
|
||||
}
|
||||
if (status.is_possibly_sensitive && !mDisplaySensitiveContents) {
|
||||
holder.image_preview.setImageDrawable(null);
|
||||
holder.image_preview.setBackgroundResource(R.drawable.image_preview_nsfw);
|
||||
holder.image_preview_progress.setVisibility(View.GONE);
|
||||
} else if (!status.first_media.equals(mImageLoadingHandler.getLoadingUri(holder.image_preview))) {
|
||||
holder.image_preview.setBackgroundResource(0);
|
||||
loader.displayPreviewImage(holder.image_preview, status.first_media, mImageLoadingHandler);
|
||||
}
|
||||
final Resources res = mContext.getResources();
|
||||
final int count = status.media.length;
|
||||
holder.image_preview_count.setText(res.getQuantityString(R.plurals.N_media, count, count));
|
||||
holder.image_preview.setTag(position);
|
||||
} else {
|
||||
loader.cancelDisplayTask(holder.image_preview);
|
||||
}
|
||||
} else {
|
||||
loader.cancelDisplayTask(holder.profile_image);
|
||||
loader.cancelDisplayTask(holder.my_profile_image);
|
||||
loader.cancelDisplayTask(holder.image_preview);
|
||||
}
|
||||
if (position > mMaxAnimationPosition) {
|
||||
if (mAnimationEnabled) {
|
||||
view.startAnimation(holder.item_animation);
|
||||
}
|
||||
mMaxAnimationPosition = position;
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLastItemFiltered() {
|
||||
return mIsLastItemFiltered;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(final View view) {
|
||||
if (mMultiSelectManager.isActive()) return;
|
||||
final Object tag = view.getTag();
|
||||
final int position = tag instanceof Integer ? (Integer) tag : -1;
|
||||
if (position == -1) return;
|
||||
switch (view.getId()) {
|
||||
case R.id.image_preview: {
|
||||
final ParcelableStatus status = getStatus(position);
|
||||
if (status == null || status.first_media == null) return;
|
||||
openImage(mContext, status.account_id, status.first_media, status.is_possibly_sensitive);
|
||||
break;
|
||||
}
|
||||
case R.id.my_profile_image:
|
||||
case R.id.profile_image: {
|
||||
final ParcelableStatus status = getStatus(position);
|
||||
if (status == null) return;
|
||||
if (mContext instanceof Activity) {
|
||||
openUserProfile((Activity) mContext, status.account_id, status.user_id, status.user_screen_name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOverflowIconClick(final View view) {
|
||||
if (mMultiSelectManager.isActive()) return;
|
||||
final Object tag = view.getTag();
|
||||
if (tag instanceof StatusViewHolder) {
|
||||
final StatusViewHolder holder = (StatusViewHolder) tag;
|
||||
final int position = holder.position;
|
||||
if (position == -1 || mListener == null) return;
|
||||
mListener.onMenuButtonClick(view, position, getItemId(position));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAnimationEnabled(final boolean anim) {
|
||||
mAnimationEnabled = anim;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCardHighlightOption(final String option) {
|
||||
mCardHighlightOption = getCardHighlightOptionInt(option);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(final List<ParcelableStatus> data) {
|
||||
clear();
|
||||
if (data != null && !data.isEmpty()) {
|
||||
addAll(data);
|
||||
}
|
||||
rebuildFilterInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDisplayImagePreview(final boolean display) {
|
||||
mDisplayImagePreview = display;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDisplaySensitiveContents(final boolean display) {
|
||||
mDisplaySensitiveContents = display;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFavoritesHightlightDisabled(final boolean disable) {
|
||||
mFavoritesHighlightDisabled = disable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFiltersEnabled(final boolean enabled) {
|
||||
if (mFiltersEnabled == enabled) return;
|
||||
mFiltersEnabled = enabled;
|
||||
rebuildFilterInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGapDisallowed(final boolean disallowed) {
|
||||
mGapDisallowed = disallowed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHighlightKeyword(final String... keywords) {
|
||||
mHighlightKeywords = keywords;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIgnoredFilterFields(final boolean user, final boolean textPlain, final boolean textHtml,
|
||||
final boolean source, final boolean retweetedById) {
|
||||
mFilterIgnoreTextPlain = textPlain;
|
||||
mFilterIgnoreTextHtml = textHtml;
|
||||
mFilterIgnoreUser = user;
|
||||
mFilterIgnoreSource = source;
|
||||
mFilterRetweetedById = retweetedById;
|
||||
rebuildFilterInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImagePreviewScaleType(final String scaleTypeString) {
|
||||
final ScaleType scaleType = ScaleType.valueOf(scaleTypeString.toUpperCase(Locale.US));
|
||||
mImagePreviewScaleType = scaleType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIndicateMyStatusDisabled(final boolean disable) {
|
||||
mIndicateMyStatusDisabled = disable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxAnimationPosition(final int position) {
|
||||
mMaxAnimationPosition = position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMentionsHightlightDisabled(final boolean disable) {
|
||||
mMentionsHighlightDisabled = disable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMenuButtonClickListener(final MenuButtonClickListener listener) {
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
private void rebuildFilterInfo() {
|
||||
if (!isEmpty()) {
|
||||
final ParcelableStatus last = getItem(super.getCount() - 1);
|
||||
final long user_id = mFilterIgnoreUser ? -1 : last.user_id;
|
||||
final String text_plain = mFilterIgnoreTextPlain ? null : last.text_plain;
|
||||
final String text_html = mFilterIgnoreTextHtml ? null : last.text_html;
|
||||
final String source = mFilterIgnoreSource ? null : last.source;
|
||||
final long retweeted_by_id = mFilterRetweetedById ? -1 : last.retweeted_by_id;
|
||||
mIsLastItemFiltered = isFiltered(mDatabase, user_id, text_plain, text_html, source, retweeted_by_id);
|
||||
} else {
|
||||
mIsLastItemFiltered = false;
|
||||
}
|
||||
public void setData(List<ParcelableStatus> data) {
|
||||
mData = data;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private static int getItemResource(final boolean compactCards) {
|
||||
return compactCards ? R.layout.card_item_status_compact : R.layout.card_item_status;
|
||||
public List<ParcelableStatus> getData() {
|
||||
return mData;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,450 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.adapter;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.text.Html;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView.ScaleType;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.iface.IStatusesListAdapter;
|
||||
import org.mariotaku.twidere.app.TwidereApplication;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.model.ParcelableUserMention;
|
||||
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
||||
import org.mariotaku.twidere.util.ImageLoadingHandler;
|
||||
import org.mariotaku.twidere.util.MultiSelectManager;
|
||||
import org.mariotaku.twidere.util.TwidereLinkify;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.view.holder.StatusListViewHolder;
|
||||
import org.mariotaku.twidere.view.iface.ICardItemView.OnOverflowIconClickListener;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static org.mariotaku.twidere.model.ParcelableLocation.isValidLocation;
|
||||
import static org.mariotaku.twidere.util.UserColorNicknameUtils.getUserColor;
|
||||
import static org.mariotaku.twidere.util.UserColorNicknameUtils.getUserNickname;
|
||||
import static org.mariotaku.twidere.util.Utils.configBaseCardAdapter;
|
||||
import static org.mariotaku.twidere.util.Utils.getAccountColor;
|
||||
import static org.mariotaku.twidere.util.Utils.getCardHighlightColor;
|
||||
import static org.mariotaku.twidere.util.Utils.getCardHighlightOptionInt;
|
||||
import static org.mariotaku.twidere.util.Utils.isFiltered;
|
||||
import static org.mariotaku.twidere.util.Utils.openImage;
|
||||
import static org.mariotaku.twidere.util.Utils.openUserProfile;
|
||||
|
||||
public class ParcelableStatusesListAdapter extends BaseArrayAdapter<ParcelableStatus> implements
|
||||
IStatusesListAdapter<List<ParcelableStatus>>, OnClickListener, OnOverflowIconClickListener {
|
||||
|
||||
private final Context mContext;
|
||||
private final MultiSelectManager mMultiSelectManager;
|
||||
private final SQLiteDatabase mDatabase;
|
||||
private final ImageLoadingHandler mImageLoadingHandler;
|
||||
|
||||
private MenuButtonClickListener mListener;
|
||||
|
||||
private final boolean mPlainList;
|
||||
|
||||
private boolean mDisplayImagePreview, mGapDisallowed, mMentionsHighlightDisabled, mFavoritesHighlightDisabled,
|
||||
mDisplaySensitiveContents, mIndicateMyStatusDisabled, mIsLastItemFiltered, mFiltersEnabled,
|
||||
mAnimationEnabled;
|
||||
private boolean mFilterIgnoreUser, mFilterIgnoreSource, mFilterIgnoreTextHtml, mFilterIgnoreTextPlain,
|
||||
mFilterRetweetedById;
|
||||
private int mMaxAnimationPosition, mCardHighlightOption;
|
||||
private ScaleType mImagePreviewScaleType;
|
||||
private String[] mHighlightKeywords;
|
||||
|
||||
public ParcelableStatusesListAdapter(final Context context) {
|
||||
this(context, Utils.isCompactCards(context), Utils.isPlainListStyle(context));
|
||||
}
|
||||
|
||||
public ParcelableStatusesListAdapter(final Context context, final boolean compactCards, final boolean plainList) {
|
||||
super(context, getItemResource(compactCards));
|
||||
mPlainList = plainList;
|
||||
mContext = context;
|
||||
final TwidereApplication app = TwidereApplication.getInstance(context);
|
||||
mMultiSelectManager = app.getMultiSelectManager();
|
||||
mDatabase = app.getSQLiteDatabase();
|
||||
mImageLoadingHandler = new ImageLoadingHandler();
|
||||
configBaseCardAdapter(context, this);
|
||||
setMaxAnimationPosition(-1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int findPositionByStatusId(final long status_id) {
|
||||
for (int i = 0, count = getCount(); i < count; i++) {
|
||||
if (getItem(i).id == status_id) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getAccountId(final int position) {
|
||||
if (position >= 0 && position < getCount()) {
|
||||
final ParcelableStatus status = getItem(position);
|
||||
return status != null ? status.account_id : -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatusCount() {
|
||||
return super.getCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
final int count = super.getCount();
|
||||
return mFiltersEnabled && mIsLastItemFiltered && count > 0 ? count - 1 : count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(final int position) {
|
||||
final ParcelableStatus item = getItem(position);
|
||||
return item != null ? item.id : -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelableStatus getLastStatus() {
|
||||
if (super.getCount() == 0) return null;
|
||||
return getItem(super.getCount() - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastStatusId() {
|
||||
if (super.getCount() == 0) return -1;
|
||||
return getItem(super.getCount() - 1).id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageLoadingHandler getImageLoadingHandler() {
|
||||
return mImageLoadingHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelableStatus getStatus(final int position) {
|
||||
return getItem(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getStatusId(final int position) {
|
||||
if (position >= 0 && position < getCount()) {
|
||||
final ParcelableStatus status = getItem(position);
|
||||
return status != null ? status.id : -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(final int position, final View convertView, final ViewGroup parent) {
|
||||
final View view = super.getView(position, convertView, parent);
|
||||
final Object tag = view.getTag();
|
||||
final StatusListViewHolder holder;
|
||||
|
||||
if (tag instanceof StatusListViewHolder) {
|
||||
holder = (StatusListViewHolder) tag;
|
||||
} else {
|
||||
holder = new StatusListViewHolder(view);
|
||||
holder.profile_image.setOnClickListener(this);
|
||||
holder.my_profile_image.setOnClickListener(this);
|
||||
holder.image_preview.setOnClickListener(this);
|
||||
holder.content.setOnOverflowIconClickListener(this);
|
||||
if (mPlainList) {
|
||||
((View) holder.content).setPadding(0, 0, 0, 0);
|
||||
holder.content.setItemBackground(null);
|
||||
}
|
||||
view.setTag(holder);
|
||||
}
|
||||
|
||||
final ParcelableStatus status = getItem(position);
|
||||
|
||||
final boolean showGap = status.is_gap && !mGapDisallowed && position != getCount() - 1;
|
||||
|
||||
holder.position = position;
|
||||
holder.setShowAsGap(showGap);
|
||||
holder.setDisplayProfileImage(isDisplayProfileImage());
|
||||
holder.setCardHighlightOption(mCardHighlightOption);
|
||||
|
||||
final ImageLoaderWrapper loader = getImageLoader();
|
||||
if (!showGap) {
|
||||
final TwidereLinkify linkify = getLinkify();
|
||||
final int highlightOption = getLinkHighlightOption();
|
||||
final boolean mShowAccountColor = isShowAccountColor();
|
||||
|
||||
holder.setAccountColorEnabled(mShowAccountColor);
|
||||
|
||||
if (highlightOption != VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE) {
|
||||
holder.text.setText(Utils.getKeywordBoldedText(Html.fromHtml(status.text_html), mHighlightKeywords));
|
||||
linkify.applyAllLinks(holder.text, status.account_id, status.is_possibly_sensitive);
|
||||
holder.text.setMovementMethod(null);
|
||||
} else {
|
||||
if (mHighlightKeywords == null || mHighlightKeywords.length == 0) {
|
||||
holder.text.setText(status.text_unescaped);
|
||||
} else {
|
||||
holder.text.setText(Utils.getKeywordBoldedText(status.text_unescaped, mHighlightKeywords));
|
||||
}
|
||||
}
|
||||
|
||||
if (mShowAccountColor) {
|
||||
holder.setAccountColor(getAccountColor(mContext, status.account_id));
|
||||
}
|
||||
|
||||
final boolean isMention = ParcelableUserMention.hasMention(status.mentions, status.account_id);
|
||||
final boolean isMyStatus = status.account_id == status.user_id;
|
||||
final boolean hasMedia = status.first_media != null;
|
||||
if (status.is_retweet) {
|
||||
holder.setUserColor(getUserColor(mContext, status.user_id),
|
||||
getUserColor(mContext, status.retweeted_by_id));
|
||||
} else {
|
||||
holder.setUserColor(getUserColor(mContext, status.user_id));
|
||||
}
|
||||
holder.setHighlightColor(getCardHighlightColor(!mMentionsHighlightDisabled && isMention,
|
||||
!mFavoritesHighlightDisabled && status.is_favorite, status.is_retweet));
|
||||
holder.setTextSize(getTextSize());
|
||||
|
||||
holder.setIsMyStatus(isMyStatus && !mIndicateMyStatusDisabled);
|
||||
|
||||
holder.setUserType(status.user_is_verified, status.user_is_protected);
|
||||
holder.setDisplayNameFirst(isDisplayNameFirst());
|
||||
holder.setNicknameOnly(isNicknameOnly());
|
||||
final String nick = getUserNickname(mContext, status.user_id);
|
||||
holder.name.setText(TextUtils.isEmpty(nick) ? status.user_name : isNicknameOnly() ? nick : mContext
|
||||
.getString(R.string.name_with_nickname, status.user_name, nick));
|
||||
holder.screen_name.setText("@" + status.user_screen_name);
|
||||
if (highlightOption != VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE) {
|
||||
linkify.applyUserProfileLinkNoHighlight(holder.name, status.account_id, status.user_id,
|
||||
status.user_screen_name);
|
||||
linkify.applyUserProfileLinkNoHighlight(holder.screen_name, status.account_id, status.user_id,
|
||||
status.user_screen_name);
|
||||
holder.name.setMovementMethod(null);
|
||||
holder.screen_name.setMovementMethod(null);
|
||||
}
|
||||
holder.time.setTime(status.retweet_timestamp > 0 ? status.retweet_timestamp : status.timestamp);
|
||||
holder.setStatusType(!mFavoritesHighlightDisabled && status.is_favorite, isValidLocation(status.location),
|
||||
hasMedia, status.is_possibly_sensitive);
|
||||
holder.setIsReplyRetweet(status.in_reply_to_status_id > 0, status.is_retweet);
|
||||
if (status.is_retweet) {
|
||||
holder.setRetweetedBy(status.retweet_count, status.retweeted_by_id, status.retweeted_by_name,
|
||||
status.retweeted_by_screen_name);
|
||||
} else if (status.in_reply_to_status_id > 0) {
|
||||
holder.setReplyTo(status.in_reply_to_user_id, status.in_reply_to_name, status.in_reply_to_screen_name);
|
||||
}
|
||||
if (isDisplayProfileImage()) {
|
||||
loader.displayProfileImage(holder.my_profile_image, status.user_profile_image_url);
|
||||
loader.displayProfileImage(holder.profile_image, status.user_profile_image_url);
|
||||
holder.profile_image.setTag(position);
|
||||
holder.my_profile_image.setTag(position);
|
||||
} else {
|
||||
loader.cancelDisplayTask(holder.profile_image);
|
||||
loader.cancelDisplayTask(holder.my_profile_image);
|
||||
holder.profile_image.setVisibility(View.GONE);
|
||||
holder.my_profile_image.setVisibility(View.GONE);
|
||||
}
|
||||
final boolean hasPreview = mDisplayImagePreview && hasMedia;
|
||||
holder.image_preview_container.setVisibility(hasPreview ? View.VISIBLE : View.GONE);
|
||||
if (hasPreview) {
|
||||
if (mImagePreviewScaleType != null) {
|
||||
holder.image_preview.setScaleType(mImagePreviewScaleType);
|
||||
}
|
||||
if (status.is_possibly_sensitive && !mDisplaySensitiveContents) {
|
||||
holder.image_preview.setImageDrawable(null);
|
||||
holder.image_preview.setBackgroundResource(R.drawable.image_preview_nsfw);
|
||||
holder.image_preview_progress.setVisibility(View.GONE);
|
||||
} else if (!status.first_media.equals(mImageLoadingHandler.getLoadingUri(holder.image_preview))) {
|
||||
holder.image_preview.setBackgroundResource(0);
|
||||
loader.displayPreviewImage(holder.image_preview, status.first_media, mImageLoadingHandler);
|
||||
}
|
||||
final Resources res = mContext.getResources();
|
||||
final int count = status.media.length;
|
||||
holder.image_preview_count.setText(res.getQuantityString(R.plurals.N_media, count, count));
|
||||
holder.image_preview.setTag(position);
|
||||
} else {
|
||||
loader.cancelDisplayTask(holder.image_preview);
|
||||
}
|
||||
} else {
|
||||
loader.cancelDisplayTask(holder.profile_image);
|
||||
loader.cancelDisplayTask(holder.my_profile_image);
|
||||
loader.cancelDisplayTask(holder.image_preview);
|
||||
}
|
||||
if (position > mMaxAnimationPosition) {
|
||||
if (mAnimationEnabled) {
|
||||
view.startAnimation(holder.item_animation);
|
||||
}
|
||||
mMaxAnimationPosition = position;
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLastItemFiltered() {
|
||||
return mIsLastItemFiltered;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(final View view) {
|
||||
if (mMultiSelectManager.isActive()) return;
|
||||
final Object tag = view.getTag();
|
||||
final int position = tag instanceof Integer ? (Integer) tag : -1;
|
||||
if (position == -1) return;
|
||||
switch (view.getId()) {
|
||||
case R.id.image_preview: {
|
||||
final ParcelableStatus status = getStatus(position);
|
||||
if (status == null || status.first_media == null) return;
|
||||
openImage(mContext, status.account_id, status.first_media, status.is_possibly_sensitive);
|
||||
break;
|
||||
}
|
||||
case R.id.my_profile_image:
|
||||
case R.id.profile_image: {
|
||||
final ParcelableStatus status = getStatus(position);
|
||||
if (status == null) return;
|
||||
if (mContext instanceof Activity) {
|
||||
openUserProfile((Activity) mContext, status.account_id, status.user_id, status.user_screen_name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOverflowIconClick(final View view) {
|
||||
if (mMultiSelectManager.isActive()) return;
|
||||
final Object tag = view.getTag();
|
||||
if (tag instanceof StatusListViewHolder) {
|
||||
final StatusListViewHolder holder = (StatusListViewHolder) tag;
|
||||
final int position = holder.position;
|
||||
if (position == -1 || mListener == null) return;
|
||||
mListener.onMenuButtonClick(view, position, getItemId(position));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAnimationEnabled(final boolean anim) {
|
||||
mAnimationEnabled = anim;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCardHighlightOption(final String option) {
|
||||
mCardHighlightOption = getCardHighlightOptionInt(option);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(final List<ParcelableStatus> data) {
|
||||
clear();
|
||||
if (data != null && !data.isEmpty()) {
|
||||
addAll(data);
|
||||
}
|
||||
rebuildFilterInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDisplayImagePreview(final boolean display) {
|
||||
mDisplayImagePreview = display;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDisplaySensitiveContents(final boolean display) {
|
||||
mDisplaySensitiveContents = display;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFavoritesHightlightDisabled(final boolean disable) {
|
||||
mFavoritesHighlightDisabled = disable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFiltersEnabled(final boolean enabled) {
|
||||
if (mFiltersEnabled == enabled) return;
|
||||
mFiltersEnabled = enabled;
|
||||
rebuildFilterInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGapDisallowed(final boolean disallowed) {
|
||||
mGapDisallowed = disallowed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHighlightKeyword(final String... keywords) {
|
||||
mHighlightKeywords = keywords;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIgnoredFilterFields(final boolean user, final boolean textPlain, final boolean textHtml,
|
||||
final boolean source, final boolean retweetedById) {
|
||||
mFilterIgnoreTextPlain = textPlain;
|
||||
mFilterIgnoreTextHtml = textHtml;
|
||||
mFilterIgnoreUser = user;
|
||||
mFilterIgnoreSource = source;
|
||||
mFilterRetweetedById = retweetedById;
|
||||
rebuildFilterInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImagePreviewScaleType(final String scaleTypeString) {
|
||||
final ScaleType scaleType = ScaleType.valueOf(scaleTypeString.toUpperCase(Locale.US));
|
||||
mImagePreviewScaleType = scaleType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIndicateMyStatusDisabled(final boolean disable) {
|
||||
mIndicateMyStatusDisabled = disable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxAnimationPosition(final int position) {
|
||||
mMaxAnimationPosition = position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMentionsHightlightDisabled(final boolean disable) {
|
||||
mMentionsHighlightDisabled = disable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMenuButtonClickListener(final MenuButtonClickListener listener) {
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
private void rebuildFilterInfo() {
|
||||
if (!isEmpty()) {
|
||||
final ParcelableStatus last = getItem(super.getCount() - 1);
|
||||
final long user_id = mFilterIgnoreUser ? -1 : last.user_id;
|
||||
final String text_plain = mFilterIgnoreTextPlain ? null : last.text_plain;
|
||||
final String text_html = mFilterIgnoreTextHtml ? null : last.text_html;
|
||||
final String source = mFilterIgnoreSource ? null : last.source;
|
||||
final long retweeted_by_id = mFilterRetweetedById ? -1 : last.retweeted_by_id;
|
||||
mIsLastItemFiltered = isFiltered(mDatabase, user_id, text_plain, text_html, source, retweeted_by_id);
|
||||
} else {
|
||||
mIsLastItemFiltered = false;
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private static int getItemResource(final boolean compactCards) {
|
||||
return compactCards ? R.layout.card_item_status_compact : R.layout.card_item_status;
|
||||
}
|
||||
}
|
@ -1,11 +1,23 @@
|
||||
package org.mariotaku.twidere.adapter.iface;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
||||
import org.mariotaku.twidere.util.ImageLoadingHandler;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/11/18.
|
||||
*/
|
||||
public interface IStatusesAdapter {
|
||||
|
||||
public ParcelableStatus getStatus(int position);
|
||||
ImageLoaderWrapper getImageLoader();
|
||||
|
||||
Context getContext();
|
||||
|
||||
ImageLoadingHandler getImageLoadingHandler();
|
||||
|
||||
ParcelableStatus getStatus(int position);
|
||||
|
||||
int getStatusCount();
|
||||
}
|
||||
|
@ -27,8 +27,6 @@ public interface IStatusesListAdapter<Data> extends IBaseCardAdapter, IStatusesA
|
||||
|
||||
public long getAccountId(final int position);
|
||||
|
||||
public int getActualCount();
|
||||
|
||||
public ParcelableStatus getLastStatus();
|
||||
|
||||
public long getLastStatusId();
|
||||
|
@ -53,7 +53,7 @@ import org.mariotaku.twidere.util.PositionManager;
|
||||
import org.mariotaku.twidere.util.TwitterWrapper;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.util.collection.NoDuplicatesCopyOnWriteArrayList;
|
||||
import org.mariotaku.twidere.view.holder.StatusViewHolder;
|
||||
import org.mariotaku.twidere.view.holder.StatusListViewHolder;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@ -161,8 +161,8 @@ abstract class BaseStatusesListFragment<Data> extends BasePullToRefreshListFragm
|
||||
@Override
|
||||
public boolean onItemLongClick(final AdapterView<?> parent, final View view, final int position, final long id) {
|
||||
final Object tag = view.getTag();
|
||||
if (tag instanceof StatusViewHolder) {
|
||||
final StatusViewHolder holder = (StatusViewHolder) tag;
|
||||
if (tag instanceof StatusListViewHolder) {
|
||||
final StatusListViewHolder holder = (StatusListViewHolder) tag;
|
||||
final ParcelableStatus status = mAdapter.getStatus(position - mListView.getHeaderViewsCount());
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
if (twitter != null) {
|
||||
@ -196,7 +196,7 @@ abstract class BaseStatusesListFragment<Data> extends BasePullToRefreshListFragm
|
||||
@Override
|
||||
public void onListItemClick(final ListView l, final View v, final int position, final long id) {
|
||||
final Object tag = v.getTag();
|
||||
if (tag instanceof StatusViewHolder) {
|
||||
if (tag instanceof StatusListViewHolder) {
|
||||
final int pos = position - l.getHeaderViewsCount();
|
||||
final ParcelableStatus status = mAdapter.getStatus(pos);
|
||||
if (status == null) return;
|
||||
@ -204,8 +204,8 @@ abstract class BaseStatusesListFragment<Data> extends BasePullToRefreshListFragm
|
||||
if (twitter != null) {
|
||||
TwitterWrapper.removeUnreadCounts(getActivity(), getTabPosition(), status.account_id, status.id);
|
||||
}
|
||||
if (((StatusViewHolder) tag).show_as_gap) {
|
||||
final long since_id = position + 1 < mAdapter.getActualCount() ? mAdapter.getStatus(pos + 1).id : -1;
|
||||
if (((StatusListViewHolder) tag).show_as_gap) {
|
||||
final long since_id = position + 1 < mAdapter.getStatusCount() ? mAdapter.getStatus(pos + 1).id : -1;
|
||||
getStatuses(new long[]{status.account_id}, new long[]{status.id}, new long[]{since_id});
|
||||
mListView.setItemChecked(position, false);
|
||||
} else {
|
||||
|
@ -62,7 +62,7 @@ import org.mariotaku.twidere.util.PositionManager;
|
||||
import org.mariotaku.twidere.util.TwitterWrapper;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.util.collection.NoDuplicatesCopyOnWriteArrayList;
|
||||
import org.mariotaku.twidere.view.holder.StatusViewHolder;
|
||||
import org.mariotaku.twidere.view.holder.StatusListViewHolder;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@ -152,8 +152,8 @@ abstract class BaseStatusesStaggeredGridFragment<Data> extends BasePullToRefresh
|
||||
@Override
|
||||
public boolean onItemLongClick(final AdapterView<?> parent, final View view, final int position, final long id) {
|
||||
final Object tag = view.getTag();
|
||||
if (tag instanceof StatusViewHolder) {
|
||||
final StatusViewHolder holder = (StatusViewHolder) tag;
|
||||
if (tag instanceof StatusListViewHolder) {
|
||||
final StatusListViewHolder holder = (StatusListViewHolder) tag;
|
||||
final ParcelableStatus status = mAdapter.getStatus(position - mListView.getHeaderViewsCount());
|
||||
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
||||
if (twitter != null) {
|
||||
@ -187,7 +187,7 @@ abstract class BaseStatusesStaggeredGridFragment<Data> extends BasePullToRefresh
|
||||
@Override
|
||||
public void onListItemClick(final StaggeredGridView l, final View v, final int position, final long id) {
|
||||
final Object tag = v.getTag();
|
||||
if (tag instanceof StatusViewHolder) {
|
||||
if (tag instanceof StatusListViewHolder) {
|
||||
final int pos = position - l.getHeaderViewsCount();
|
||||
final ParcelableStatus status = mAdapter.getStatus(pos);
|
||||
if (status == null) return;
|
||||
@ -195,8 +195,8 @@ abstract class BaseStatusesStaggeredGridFragment<Data> extends BasePullToRefresh
|
||||
if (twitter != null) {
|
||||
TwitterWrapper.removeUnreadCounts(getActivity(), getTabPosition(), status.account_id, status.id);
|
||||
}
|
||||
if (((StatusViewHolder) tag).show_as_gap) {
|
||||
final long since_id = position + 1 < mAdapter.getActualCount() ? mAdapter.getStatus(pos + 1).id : -1;
|
||||
if (((StatusListViewHolder) tag).show_as_gap) {
|
||||
final long since_id = position + 1 < mAdapter.getStatusCount() ? mAdapter.getStatus(pos + 1).id : -1;
|
||||
getStatuses(new long[] { status.account_id }, new long[] { status.id }, new long[] { since_id });
|
||||
mListView.setItemChecked(position, false);
|
||||
} else {
|
||||
|
@ -28,7 +28,7 @@ import android.os.Bundle;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.Loader;
|
||||
|
||||
import org.mariotaku.twidere.adapter.ParcelableStatusesAdapter;
|
||||
import org.mariotaku.twidere.adapter.ParcelableStatusesListAdapter;
|
||||
import org.mariotaku.twidere.adapter.iface.IStatusesListAdapter;
|
||||
import org.mariotaku.twidere.loader.support.DummyParcelableStatusesLoader;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
@ -149,7 +149,7 @@ public abstract class ParcelableStatusesListFragment extends BaseStatusesListFra
|
||||
public void onSaveInstanceState(final Bundle outState) {
|
||||
final List<ParcelableStatus> data = getData();
|
||||
if (data != null) {
|
||||
outState.putParcelableArrayList(EXTRA_DATA, new ArrayList<ParcelableStatus>(data));
|
||||
outState.putParcelableArrayList(EXTRA_DATA, new ArrayList<>(data));
|
||||
}
|
||||
super.onSaveInstanceState(outState);
|
||||
}
|
||||
@ -208,8 +208,8 @@ public abstract class ParcelableStatusesListFragment extends BaseStatusesListFra
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ParcelableStatusesAdapter newAdapterInstance(final boolean compact, final boolean plain) {
|
||||
return new ParcelableStatusesAdapter(getActivity(), compact, plain);
|
||||
protected ParcelableStatusesListAdapter newAdapterInstance(final boolean compact, final boolean plain) {
|
||||
return new ParcelableStatusesListAdapter(getActivity(), compact, plain);
|
||||
}
|
||||
|
||||
protected abstract Loader<List<ParcelableStatus>> newLoaderInstance(Context context, Bundle args);
|
||||
|
@ -71,7 +71,7 @@ import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.activity.support.AccountSelectorActivity;
|
||||
import org.mariotaku.twidere.activity.support.ColorPickerDialogActivity;
|
||||
import org.mariotaku.twidere.activity.support.LinkHandlerActivity;
|
||||
import org.mariotaku.twidere.adapter.ParcelableStatusesAdapter;
|
||||
import org.mariotaku.twidere.adapter.ParcelableStatusesListAdapter;
|
||||
import org.mariotaku.twidere.adapter.iface.IStatusesListAdapter;
|
||||
import org.mariotaku.twidere.app.TwidereApplication;
|
||||
import org.mariotaku.twidere.model.Account;
|
||||
@ -882,7 +882,7 @@ public class StatusFragment extends ParcelableStatusesListFragment implements On
|
||||
final List<ParcelableStatus> data = getData();
|
||||
if (data == null) return;
|
||||
data.add(status);
|
||||
final ParcelableStatusesAdapter adapter = (ParcelableStatusesAdapter) getListAdapter();
|
||||
final ParcelableStatusesListAdapter adapter = (ParcelableStatusesListAdapter) getListAdapter();
|
||||
adapter.setData(data);
|
||||
if (!mLoadMoreAutomatically && mShouldScroll) {
|
||||
setSelection(0);
|
||||
|
@ -47,7 +47,7 @@ import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.model.SingleResponse;
|
||||
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.view.holder.StatusViewHolder;
|
||||
import org.mariotaku.twidere.view.holder.StatusListViewHolder;
|
||||
|
||||
import twitter4j.TranslationResult;
|
||||
import twitter4j.Twitter;
|
||||
@ -56,7 +56,7 @@ import twitter4j.TwitterException;
|
||||
public class StatusTranslateDialogFragment extends BaseSupportDialogFragment implements
|
||||
LoaderCallbacks<SingleResponse<TranslationResult>> {
|
||||
|
||||
private StatusViewHolder mHolder;
|
||||
private StatusListViewHolder mHolder;
|
||||
private ProgressBar mProgressBar;
|
||||
private TextView mMessageView;
|
||||
private View mProgressContainer;
|
||||
@ -95,7 +95,7 @@ public class StatusTranslateDialogFragment extends BaseSupportDialogFragment imp
|
||||
mProgressBar = (ProgressBar) mProgressContainer.findViewById(android.R.id.progress);
|
||||
mMessageView = (TextView) mProgressContainer.findViewById(android.R.id.message);
|
||||
mStatusContainer = view.findViewById(R.id.status_container);
|
||||
mHolder = new StatusViewHolder(mStatusContainer);
|
||||
mHolder = new StatusListViewHolder(mStatusContainer);
|
||||
mHolder.setShowAsGap(false);
|
||||
mHolder.setAccountColorEnabled(true);
|
||||
((View) mHolder.content).setPadding(0, 0, 0, 0);
|
||||
|
@ -1,24 +1,25 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment.support;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.ActionBar;
|
||||
import android.app.Activity;
|
||||
import android.content.ActivityNotFoundException;
|
||||
@ -32,10 +33,14 @@ import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Outline;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.graphics.drawable.ShapeDrawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
@ -94,10 +99,10 @@ import org.mariotaku.twidere.util.TwidereLinkify;
|
||||
import org.mariotaku.twidere.util.TwidereLinkify.OnLinkClickListener;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.util.menu.TwidereMenuInfo;
|
||||
import org.mariotaku.twidere.view.CircularImageView;
|
||||
import org.mariotaku.twidere.view.ColorLabelLinearLayout;
|
||||
import org.mariotaku.twidere.view.ExtendedFrameLayout;
|
||||
import org.mariotaku.twidere.view.ProfileBannerImageView;
|
||||
import org.mariotaku.twidere.view.ProfileImageView;
|
||||
import org.mariotaku.twidere.view.TwidereMenuBar;
|
||||
import org.mariotaku.twidere.view.iface.IExtendedView.OnSizeChangedListener;
|
||||
|
||||
@ -153,7 +158,7 @@ public class UserProfileFragmentOld extends BaseSupportListFragment implements O
|
||||
private ImageLoaderWrapper mProfileImageLoader;
|
||||
private SharedPreferences mPreferences;
|
||||
|
||||
private ProfileImageView mProfileImageView;
|
||||
private CircularImageView mProfileImageView;
|
||||
private ProfileBannerImageView mProfileBannerView;
|
||||
private TextView mNameView, mScreenNameView, mDescriptionView, mLocationView, mURLView, mCreatedAtView,
|
||||
mTweetCount, mFollowersCount, mFriendsCount, mErrorMessageView;
|
||||
@ -180,6 +185,7 @@ public class UserProfileFragmentOld extends BaseSupportListFragment implements O
|
||||
|
||||
private int mBannerWidth;
|
||||
|
||||
private Drawable mActionBarShadow;
|
||||
private Drawable mActionBarBackground;
|
||||
|
||||
private final BroadcastReceiver mStatusReceiver = new BroadcastReceiver() {
|
||||
@ -344,7 +350,7 @@ public class UserProfileFragmentOld extends BaseSupportListFragment implements O
|
||||
final String nick = getUserNickname(getActivity(), user.id, true);
|
||||
mNameView
|
||||
.setText(TextUtils.isEmpty(nick) ? user.name : getString(R.string.name_with_nickname, user.name, nick));
|
||||
mProfileImageView.setUserType(user.is_verified, user.is_protected);
|
||||
// mProfileImageView.setUserType(user.is_verified, user.is_protected);
|
||||
mScreenNameView.setText("@" + user.screen_name);
|
||||
mDescriptionContainer.setVisibility(userIsMe || !isEmpty(user.description_html) ? View.VISIBLE : View.GONE);
|
||||
mDescriptionView.setText(user.description_html != null ? Html.fromHtml(user.description_html) : null);
|
||||
@ -501,11 +507,18 @@ public class UserProfileFragmentOld extends BaseSupportListFragment implements O
|
||||
final int themeResId = linkHandler.getCurrentThemeResourceId();
|
||||
final boolean isTransparent = ThemeUtils.isTransparentBackground(themeResId);
|
||||
final int actionBarAlpha = isTransparent ? ThemeUtils.getUserThemeBackgroundAlpha(linkHandler) : 0xFF;
|
||||
if (ThemeUtils.isColoredActionBar(themeResId) && useUserActionBar()) {
|
||||
actionBar.setBackgroundDrawable(mActionBarBackground = new ColorDrawable(themeColor));
|
||||
} else {
|
||||
actionBar.setBackgroundDrawable(mActionBarBackground = ThemeUtils.getActionBarBackground(activity, themeResId));
|
||||
mActionBarShadow = activity.getResources().getDrawable(R.drawable.shadow_user_banner_action_bar);
|
||||
if (mActionBarShadow instanceof ShapeDrawable) {
|
||||
final ShapeDrawable sd = (ShapeDrawable) mActionBarBackground;
|
||||
sd.setIntrinsicHeight(actionBar.getHeight());
|
||||
sd.setIntrinsicWidth(activity.getWindowManager().getDefaultDisplay().getWidth());
|
||||
}
|
||||
if (ThemeUtils.isColoredActionBar(themeResId) && useUserActionBar()) {
|
||||
mActionBarBackground = new ColorDrawable(themeColor);
|
||||
} else {
|
||||
mActionBarBackground = ThemeUtils.getActionBarBackground(activity, themeResId);
|
||||
}
|
||||
actionBar.setBackgroundDrawable(new ActionBarDrawable(mActionBarShadow, mActionBarBackground));
|
||||
}
|
||||
|
||||
private boolean useUserActionBar() {
|
||||
@ -722,8 +735,9 @@ public class UserProfileFragmentOld extends BaseSupportListFragment implements O
|
||||
profileBannerView.setTranslationY((headerView.getTop() - listView.getListPaddingTop()) / 2);
|
||||
profileBannerView.setBottomClip(headerScroll);
|
||||
|
||||
if (mActionBarBackground != null) {
|
||||
if (mActionBarShadow != null && mActionBarBackground != null) {
|
||||
final float f = headerScroll / (float) mProfileBannerSpace.getHeight();
|
||||
mActionBarShadow.setAlpha(Math.round(0xFF * MathUtils.clamp(1 - f, 0, 1)));
|
||||
mActionBarBackground.setAlpha(Math.round(0xFF * MathUtils.clamp(f, 0, 1)));
|
||||
}
|
||||
}
|
||||
@ -797,7 +811,7 @@ public class UserProfileFragmentOld extends BaseSupportListFragment implements O
|
||||
mFriendsContainer = mHeaderView.findViewById(R.id.friends_container);
|
||||
mFriendsCount = (TextView) mHeaderView.findViewById(R.id.friends_count);
|
||||
mProfileNameContainer = (ColorLabelLinearLayout) mHeaderView.findViewById(R.id.profile_name_container);
|
||||
mProfileImageView = (ProfileImageView) mHeaderView.findViewById(R.id.profile_image);
|
||||
mProfileImageView = (CircularImageView) mHeaderView.findViewById(R.id.profile_image);
|
||||
mDescriptionContainer = mHeaderView.findViewById(R.id.description_container);
|
||||
mLocationContainer = mHeaderView.findViewById(R.id.location_container);
|
||||
mURLContainer = mHeaderView.findViewById(R.id.url_container);
|
||||
@ -1247,4 +1261,28 @@ public class UserProfileFragmentOld extends BaseSupportListFragment implements O
|
||||
}
|
||||
}
|
||||
|
||||
private static class ActionBarDrawable extends LayerDrawable {
|
||||
private final Drawable mBackgroundDrawable;
|
||||
|
||||
public ActionBarDrawable(Drawable shadow, Drawable background) {
|
||||
super(new Drawable[]{shadow, background});
|
||||
mBackgroundDrawable = background;
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
@Override
|
||||
public void getOutline(Outline outline) {
|
||||
mBackgroundDrawable.getOutline(outline);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicWidth() {
|
||||
return mBackgroundDrawable.getIntrinsicWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicHeight() {
|
||||
return mBackgroundDrawable.getIntrinsicHeight();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,94 +1,139 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment.support;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.support.v4.widget.SwipeRefreshLayout;
|
||||
import android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.RecyclerView.OnScrollListener;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import org.mariotaku.twidere.adapter.iface.IStatusesListAdapter;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.ParcelableStatusesAdapter;
|
||||
import org.mariotaku.twidere.adapter.decorator.DividerItemDecoration;
|
||||
import org.mariotaku.twidere.loader.support.UserTimelineLoader;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.mariotaku.twidere.util.Utils.getAccountId;
|
||||
import static org.mariotaku.twidere.util.Utils.getAccountScreenName;
|
||||
/**
|
||||
* Created by mariotaku on 14/11/5.
|
||||
*/
|
||||
public class UserTimelineFragment extends BaseSupportFragment
|
||||
implements LoaderCallbacks<List<ParcelableStatus>>, OnRefreshListener {
|
||||
|
||||
public class UserTimelineFragment extends ParcelableStatusesListFragment {
|
||||
private SwipeRefreshLayout mSwipeRefreshLayout;
|
||||
private RecyclerView mRecyclerView;
|
||||
|
||||
private ParcelableStatusesAdapter mAdapter;
|
||||
private OnScrollListener mOnScrollListener = new OnScrollListener() {
|
||||
@Override
|
||||
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
|
||||
super.onScrollStateChanged(recyclerView, newState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
||||
final LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
|
||||
final LoaderManager lm = getLoaderManager();
|
||||
if (lm.hasRunningLoaders()) return;
|
||||
if (layoutManager.findLastVisibleItemPosition() == mAdapter.getItemCount() - 1) {
|
||||
getStatuses(mAdapter.getStatus(mAdapter.getStatusCount() - 1).id, 0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public Loader<List<ParcelableStatus>> newLoaderInstance(final Context context, final Bundle args) {
|
||||
if (args == null) return null;
|
||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
final View view = getView();
|
||||
assert view != null;
|
||||
final Context context = view.getContext();
|
||||
final boolean compact = Utils.isCompactCards(context);
|
||||
mSwipeRefreshLayout.setOnRefreshListener(this);
|
||||
mSwipeRefreshLayout.setColorSchemeColors(Color.RED, Color.GREEN, Color.BLUE);
|
||||
mAdapter = new ParcelableStatusesAdapter(context, compact);
|
||||
final LinearLayoutManager layoutManager = new LinearLayoutManager(context);
|
||||
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
|
||||
mRecyclerView.setLayoutManager(layoutManager);
|
||||
if (compact) {
|
||||
mRecyclerView.addItemDecoration(new DividerItemDecoration(context, layoutManager.getOrientation()));
|
||||
}
|
||||
mRecyclerView.setAdapter(mAdapter);
|
||||
mRecyclerView.setOnScrollListener(mOnScrollListener);
|
||||
getLoaderManager().initLoader(0, getArguments(), this);
|
||||
}
|
||||
|
||||
|
||||
public int getStatuses(final long maxId, final long sinceId) {
|
||||
final Bundle args = new Bundle(getArguments());
|
||||
args.putLong(EXTRA_MAX_ID, maxId);
|
||||
args.putLong(EXTRA_SINCE_ID, sinceId);
|
||||
getLoaderManager().restartLoader(0, args, this);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_layout);
|
||||
mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fitSystemWindows(Rect insets) {
|
||||
super.fitSystemWindows(insets);
|
||||
mRecyclerView.setClipToPadding(false);
|
||||
mRecyclerView.setPadding(insets.left, insets.top, insets.right, insets.bottom);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.fragment_recycler_view, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loader<List<ParcelableStatus>> onCreateLoader(int id, Bundle args) {
|
||||
mSwipeRefreshLayout.setRefreshing(true);
|
||||
final List<ParcelableStatus> data = mAdapter.getData();
|
||||
final Context context = getActivity();
|
||||
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
final long maxId = args.getLong(EXTRA_MAX_ID, -1);
|
||||
final long sinceId = args.getLong(EXTRA_SINCE_ID, -1);
|
||||
final long userId = args.getLong(EXTRA_USER_ID, -1);
|
||||
final String screenName = args.getString(EXTRA_SCREEN_NAME);
|
||||
final int tabPosition = args.getInt(EXTRA_TAB_POSITION, -1);
|
||||
return new UserTimelineLoader(context, accountId, userId, screenName, maxId, sinceId, getData(),
|
||||
getSavedStatusesFileArgs(), tabPosition);
|
||||
return new UserTimelineLoader(context, accountId, userId, screenName, maxId, sinceId, data,
|
||||
null, tabPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
final Bundle args = getArguments();
|
||||
final long accountId = args != null ? args.getLong(EXTRA_ACCOUNT_ID, -1) : -1;
|
||||
final long userId = args != null ? args.getLong(EXTRA_USER_ID, -1) : -1;
|
||||
final String screenName = args != null ? args.getString(EXTRA_SCREEN_NAME) : null;
|
||||
final boolean isMyTimeline = userId > 0 ? accountId == userId : accountId == getAccountId(getActivity(),
|
||||
screenName);
|
||||
final IStatusesListAdapter<List<ParcelableStatus>> adapter = getListAdapter();
|
||||
adapter.setIndicateMyStatusDisabled(isMyTimeline);
|
||||
adapter.setFiltersEnabled(!isMyTimeline);
|
||||
adapter.setIgnoredFilterFields(true, false, false, false, false);
|
||||
public void onLoadFinished(Loader<List<ParcelableStatus>> loader, List<ParcelableStatus> data) {
|
||||
mSwipeRefreshLayout.setRefreshing(false);
|
||||
mAdapter.setData(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] getSavedStatusesFileArgs() {
|
||||
final Bundle args = getArguments();
|
||||
if (args == null) return null;
|
||||
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
final long userId = args.getLong(EXTRA_USER_ID, -1);
|
||||
final String screenName = args.getString(EXTRA_SCREEN_NAME);
|
||||
return new String[]{AUTHORITY_USER_TIMELINE, "account" + accountId, "user" + userId + "name" + screenName};
|
||||
public void onLoaderReset(Loader<List<ParcelableStatus>> loader) {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean isMyTimeline() {
|
||||
final Bundle args = getArguments();
|
||||
if (args != null) {
|
||||
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
final long userId = args.getLong(EXTRA_USER_ID, -1);
|
||||
final String screenName = args.getString(EXTRA_SCREEN_NAME);
|
||||
if (accountId == userId || screenName != null
|
||||
&& screenName.equals(getAccountScreenName(getActivity(), accountId)))
|
||||
return true;
|
||||
public void onRefresh() {
|
||||
if (mAdapter.getStatusCount() > 0) {
|
||||
getStatuses(0, mAdapter.getStatus(0).id);
|
||||
} else {
|
||||
getStatuses(0, 0);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldShowAccountColor() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,339 +0,0 @@
|
||||
package org.mariotaku.twidere.fragment.support;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
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.support.v7.widget.RecyclerView.Adapter;
|
||||
import android.support.v7.widget.RecyclerView.OnScrollListener;
|
||||
import android.support.v7.widget.RecyclerView.ViewHolder;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.pkmmte.view.CircularImageView;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.decorator.DividerItemDecoration;
|
||||
import org.mariotaku.twidere.adapter.iface.IStatusesAdapter;
|
||||
import org.mariotaku.twidere.app.TwidereApplication;
|
||||
import org.mariotaku.twidere.loader.support.UserTimelineLoader;
|
||||
import org.mariotaku.twidere.model.ParcelableMedia;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
||||
import org.mariotaku.twidere.util.ImageLoadingHandler;
|
||||
import org.mariotaku.twidere.util.ThemeUtils;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.view.ShortTimeView;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/11/5.
|
||||
*/
|
||||
public class UserTimelineFragment2 extends BaseSupportFragment
|
||||
implements LoaderCallbacks<List<ParcelableStatus>> {
|
||||
|
||||
private RecyclerView mRecyclerView;
|
||||
private ProgressBar mProgress;
|
||||
|
||||
private ParcelableTimelineAdapter mAdapter;
|
||||
private OnScrollListener mOnScrollListener = new OnScrollListener() {
|
||||
@Override
|
||||
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
final View view = getView();
|
||||
assert view != null;
|
||||
final Context context = view.getContext();
|
||||
final boolean compact = Utils.isCompactCards(context);
|
||||
mAdapter = new ParcelableTimelineAdapter(context, compact);
|
||||
final LinearLayoutManager layoutManager = new LinearLayoutManager(context);
|
||||
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
|
||||
mRecyclerView.setLayoutManager(layoutManager);
|
||||
if (compact) {
|
||||
mRecyclerView.addItemDecoration(new DividerItemDecoration(context, layoutManager.getOrientation()));
|
||||
}
|
||||
mRecyclerView.setAdapter(mAdapter);
|
||||
mRecyclerView.setOnScrollListener(mOnScrollListener);
|
||||
getLoaderManager().initLoader(0, getArguments(), this);
|
||||
setListShown(false);
|
||||
}
|
||||
|
||||
public void setListShown(boolean shown) {
|
||||
mRecyclerView.setVisibility(shown ? View.VISIBLE : View.GONE);
|
||||
mProgress.setVisibility(shown ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
|
||||
public int getStatuses(final long maxId, final long sinceId) {
|
||||
final Bundle args = new Bundle(getArguments());
|
||||
args.putLong(EXTRA_MAX_ID, maxId);
|
||||
args.putLong(EXTRA_SINCE_ID, sinceId);
|
||||
getLoaderManager().restartLoader(0, args, this);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
mRecyclerView = (RecyclerView) view.findViewById(android.R.id.list);
|
||||
mProgress = (ProgressBar) view.findViewById(android.R.id.progress);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fitSystemWindows(Rect insets) {
|
||||
super.fitSystemWindows(insets);
|
||||
mRecyclerView.setClipToPadding(false);
|
||||
mRecyclerView.setPadding(insets.left, insets.top, insets.right, insets.bottom);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.fragment_recycler_view, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loader<List<ParcelableStatus>> onCreateLoader(int id, Bundle args) {
|
||||
final Context context = getActivity();
|
||||
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
final long maxId = args.getLong(EXTRA_MAX_ID, -1);
|
||||
final long sinceId = args.getLong(EXTRA_SINCE_ID, -1);
|
||||
final long userId = args.getLong(EXTRA_USER_ID, -1);
|
||||
final String screenName = args.getString(EXTRA_SCREEN_NAME);
|
||||
final int tabPosition = args.getInt(EXTRA_TAB_POSITION, -1);
|
||||
return new UserTimelineLoader(context, accountId, userId, screenName, maxId, sinceId, null,
|
||||
null, tabPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(Loader<List<ParcelableStatus>> loader, List<ParcelableStatus> data) {
|
||||
mAdapter.setData(data);
|
||||
setListShown(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<List<ParcelableStatus>> loader) {
|
||||
mAdapter.setData(null);
|
||||
}
|
||||
|
||||
private static class ParcelableTimelineAdapter extends Adapter<ViewHolder> implements IStatusesAdapter, OnClickListener {
|
||||
|
||||
private static final int ITEM_VIEW_TYPE_STATUS = 1;
|
||||
private static final int ITEM_VIEW_TYPE_LOAD_INDICATOR = 2;
|
||||
|
||||
private final Context mContext;
|
||||
private final LayoutInflater mInflater;
|
||||
private final ImageLoaderWrapper mImageLoader;
|
||||
private final ImageLoadingHandler mLoadingHandler;
|
||||
private final int mCardLayoutResource;
|
||||
private List<ParcelableStatus> mData;
|
||||
private boolean mHasMoreItem;
|
||||
|
||||
ParcelableTimelineAdapter(Context context, boolean compact) {
|
||||
mContext = context;
|
||||
mInflater = LayoutInflater.from(context);
|
||||
mImageLoader = TwidereApplication.getInstance(context).getImageLoaderWrapper();
|
||||
mLoadingHandler = new ImageLoadingHandler(R.id.media_preview_progress);
|
||||
if (compact) {
|
||||
mCardLayoutResource = R.layout.card_item_list_status_compat;
|
||||
} else {
|
||||
mCardLayoutResource = R.layout.card_item_list_status;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
switch (viewType) {
|
||||
case ITEM_VIEW_TYPE_STATUS: {
|
||||
final View view = mInflater.inflate(mCardLayoutResource, parent, false);
|
||||
return new MediaTimelineViewHolder(this, view);
|
||||
}
|
||||
case ITEM_VIEW_TYPE_LOAD_INDICATOR: {
|
||||
final View view = mInflater.inflate(R.layout.card_item_load_indicator, parent, false);
|
||||
return new LoadIndicatorViewHolder(view);
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("Unknown view type " + viewType);
|
||||
}
|
||||
|
||||
public void setHasMoreItem(boolean hasMoreItem) {
|
||||
if (mHasMoreItem == hasMoreItem) return;
|
||||
mHasMoreItem = hasMoreItem;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(ViewHolder holder, int position) {
|
||||
if (mData == null) return;
|
||||
if (holder instanceof MediaTimelineViewHolder) {
|
||||
((MediaTimelineViewHolder) holder).displayStatus(this, getStatus(position));
|
||||
}
|
||||
}
|
||||
|
||||
public void setData(List<ParcelableStatus> data) {
|
||||
mData = data;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if (position == getItemCount() - 1) {
|
||||
return ITEM_VIEW_TYPE_LOAD_INDICATOR;
|
||||
}
|
||||
return ITEM_VIEW_TYPE_STATUS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
if (mData == null) return mHasMoreItem ? 1 : 0;
|
||||
return mData.size() + (mHasMoreItem ? 1 : 0);
|
||||
}
|
||||
|
||||
public ImageLoaderWrapper getImageLoader() {
|
||||
return mImageLoader;
|
||||
}
|
||||
|
||||
public Context getContext() {
|
||||
return mContext;
|
||||
}
|
||||
|
||||
public ImageLoadingHandler getImageLoadingHandler() {
|
||||
return mLoadingHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ParcelableStatus getStatus(int position) {
|
||||
if (mData == null || (mHasMoreItem && position == mData.size() - 1)) return null;
|
||||
return mData.get(position);
|
||||
}
|
||||
}
|
||||
|
||||
private static class LoadIndicatorViewHolder extends ViewHolder {
|
||||
public LoadIndicatorViewHolder(View view) {
|
||||
super(view);
|
||||
}
|
||||
}
|
||||
|
||||
private static class MediaTimelineViewHolder extends ViewHolder implements OnClickListener {
|
||||
|
||||
private final IStatusesAdapter adapter;
|
||||
|
||||
private final ImageView mediaPreviewView;
|
||||
private final CircularImageView profileImageView;
|
||||
private final TextView textView;
|
||||
private final TextView nameView;
|
||||
private final ShortTimeView timeView;
|
||||
private final View mediaPreviewContainer;
|
||||
private final View replyIndicator, retweetIndicator, favoriteIndicator;
|
||||
private final TextView replyCountView, retweetCountView, favoriteCountView;
|
||||
|
||||
public MediaTimelineViewHolder(IStatusesAdapter adapter, View itemView) {
|
||||
super(itemView);
|
||||
this.adapter = adapter;
|
||||
itemView.findViewById(R.id.item_content).setOnClickListener(this);
|
||||
profileImageView = (CircularImageView) itemView.findViewById(R.id.profile_image);
|
||||
textView = (TextView) itemView.findViewById(R.id.text);
|
||||
nameView = (TextView) itemView.findViewById(R.id.name);
|
||||
timeView = (ShortTimeView) itemView.findViewById(R.id.time);
|
||||
|
||||
mediaPreviewContainer = itemView.findViewById(R.id.media_preview_container);
|
||||
mediaPreviewView = (ImageView) itemView.findViewById(R.id.media_preview);
|
||||
|
||||
replyIndicator = itemView.findViewById(R.id.reply_indicator);
|
||||
retweetIndicator = itemView.findViewById(R.id.retweet_indicator);
|
||||
favoriteIndicator = itemView.findViewById(R.id.favorite_indicator);
|
||||
|
||||
replyCountView = (TextView) itemView.findViewById(R.id.reply_count);
|
||||
retweetCountView = (TextView) itemView.findViewById(R.id.retweet_count);
|
||||
favoriteCountView = (TextView) itemView.findViewById(R.id.favorite_count);
|
||||
|
||||
profileImageView.setSelectorColor(ThemeUtils.getUserHighlightColor(itemView.getContext()));
|
||||
|
||||
itemView.setOnClickListener(this);
|
||||
profileImageView.setOnClickListener(this);
|
||||
mediaPreviewContainer.setOnClickListener(this);
|
||||
replyIndicator.setOnClickListener(this);
|
||||
retweetIndicator.setOnClickListener(this);
|
||||
favoriteIndicator.setOnClickListener(this);
|
||||
}
|
||||
|
||||
public void displayStatus(ParcelableTimelineAdapter adapter, ParcelableStatus status) {
|
||||
final ImageLoaderWrapper loader = adapter.getImageLoader();
|
||||
final Context context = adapter.getContext();
|
||||
final ParcelableMedia[] media = status.media;
|
||||
|
||||
nameView.setText(status.user_name);
|
||||
timeView.setTime(status.timestamp);
|
||||
loader.displayProfileImage(profileImageView, status.user_profile_image_url);
|
||||
|
||||
// profileImageView.setBorderColor(UserColorNicknameUtils.getUserColor(context, status.user_id));
|
||||
if (media != null && media.length > 0) {
|
||||
final ParcelableMedia firstMedia = media[0];
|
||||
if (status.text_plain.codePointCount(0, status.text_plain.length()) == firstMedia.end) {
|
||||
textView.setText(status.text_unescaped.substring(0, firstMedia.start));
|
||||
} else {
|
||||
textView.setText(status.text_unescaped);
|
||||
}
|
||||
loader.displayPreviewImageWithCredentials(mediaPreviewView, firstMedia.media_url,
|
||||
status.account_id, adapter.getImageLoadingHandler());
|
||||
mediaPreviewContainer.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
loader.cancelDisplayTask(mediaPreviewView);
|
||||
textView.setText(status.text_unescaped);
|
||||
mediaPreviewContainer.setVisibility(View.GONE);
|
||||
}
|
||||
retweetIndicator.setActivated(status.is_retweet);
|
||||
favoriteIndicator.setActivated(status.is_favorite);
|
||||
|
||||
replyCountView.setVisibility(status.reply_count > 0 ? View.VISIBLE : View.INVISIBLE);
|
||||
retweetCountView.setVisibility(status.retweet_count > 0 ? View.VISIBLE : View.INVISIBLE);
|
||||
favoriteCountView.setVisibility(status.favorite_count > 0 ? View.VISIBLE : View.INVISIBLE);
|
||||
replyCountView.setText(Utils.getLocalizedNumber(Locale.getDefault(), status.reply_count));
|
||||
retweetCountView.setText(Utils.getLocalizedNumber(Locale.getDefault(), status.retweet_count));
|
||||
favoriteCountView.setText(Utils.getLocalizedNumber(Locale.getDefault(), status.favorite_count));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
final Context context = itemView.getContext();
|
||||
final ParcelableStatus status = adapter.getStatus(getPosition());
|
||||
switch (v.getId()) {
|
||||
case R.id.item_content: {
|
||||
Utils.openStatus(context, status);
|
||||
break;
|
||||
}
|
||||
case R.id.profile_image: {
|
||||
Utils.openUserProfile(context, status.account_id, status.user_id, status.user_screen_name);
|
||||
break;
|
||||
}
|
||||
case R.id.reply_indicator: {
|
||||
final Intent intent = new Intent(INTENT_ACTION_REPLY);
|
||||
intent.setPackage(context.getPackageName());
|
||||
intent.putExtra(EXTRA_STATUS, status);
|
||||
context.startActivity(intent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment.support;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.content.Loader;
|
||||
|
||||
import org.mariotaku.twidere.adapter.iface.IStatusesListAdapter;
|
||||
import org.mariotaku.twidere.loader.support.UserTimelineLoader;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.mariotaku.twidere.util.Utils.getAccountId;
|
||||
import static org.mariotaku.twidere.util.Utils.getAccountScreenName;
|
||||
|
||||
public class UserTimelineFragmentOld extends ParcelableStatusesListFragment {
|
||||
|
||||
@Override
|
||||
public Loader<List<ParcelableStatus>> newLoaderInstance(final Context context, final Bundle args) {
|
||||
if (args == null) return null;
|
||||
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
final long maxId = args.getLong(EXTRA_MAX_ID, -1);
|
||||
final long sinceId = args.getLong(EXTRA_SINCE_ID, -1);
|
||||
final long userId = args.getLong(EXTRA_USER_ID, -1);
|
||||
final String screenName = args.getString(EXTRA_SCREEN_NAME);
|
||||
final int tabPosition = args.getInt(EXTRA_TAB_POSITION, -1);
|
||||
return new UserTimelineLoader(context, accountId, userId, screenName, maxId, sinceId, getData(),
|
||||
getSavedStatusesFileArgs(), tabPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
final Bundle args = getArguments();
|
||||
final long accountId = args != null ? args.getLong(EXTRA_ACCOUNT_ID, -1) : -1;
|
||||
final long userId = args != null ? args.getLong(EXTRA_USER_ID, -1) : -1;
|
||||
final String screenName = args != null ? args.getString(EXTRA_SCREEN_NAME) : null;
|
||||
final boolean isMyTimeline = userId > 0 ? accountId == userId : accountId == getAccountId(getActivity(),
|
||||
screenName);
|
||||
final IStatusesListAdapter<List<ParcelableStatus>> adapter = getListAdapter();
|
||||
adapter.setIndicateMyStatusDisabled(isMyTimeline);
|
||||
adapter.setFiltersEnabled(!isMyTimeline);
|
||||
adapter.setIgnoredFilterFields(true, false, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] getSavedStatusesFileArgs() {
|
||||
final Bundle args = getArguments();
|
||||
if (args == null) return null;
|
||||
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
final long userId = args.getLong(EXTRA_USER_ID, -1);
|
||||
final String screenName = args.getString(EXTRA_SCREEN_NAME);
|
||||
return new String[]{AUTHORITY_USER_TIMELINE, "account" + accountId, "user" + userId + "name" + screenName};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isMyTimeline() {
|
||||
final Bundle args = getArguments();
|
||||
if (args != null) {
|
||||
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
final long userId = args.getLong(EXTRA_USER_ID, -1);
|
||||
final String screenName = args.getString(EXTRA_SCREEN_NAME);
|
||||
if (accountId == userId || screenName != null
|
||||
&& screenName.equals(getAccountScreenName(getActivity(), accountId)))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldShowAccountColor() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -30,62 +30,62 @@ import java.util.List;
|
||||
|
||||
public abstract class ParcelableStatusesLoader extends AsyncTaskLoader<List<ParcelableStatus>> implements Constants {
|
||||
|
||||
private final List<ParcelableStatus> mData = new NoDuplicatesArrayList<ParcelableStatus>();
|
||||
private final boolean mFirstLoad;
|
||||
private final int mTabPosition;
|
||||
private final List<ParcelableStatus> mData = new NoDuplicatesArrayList<>();
|
||||
private final boolean mFirstLoad;
|
||||
private final int mTabPosition;
|
||||
|
||||
private Long mLastViewedId;
|
||||
private Long mLastViewedId;
|
||||
|
||||
public ParcelableStatusesLoader(final Context context, final List<ParcelableStatus> data, final int tab_position) {
|
||||
super(context);
|
||||
mFirstLoad = data == null;
|
||||
if (data != null) {
|
||||
mData.addAll(data);
|
||||
}
|
||||
mTabPosition = tab_position;
|
||||
}
|
||||
public ParcelableStatusesLoader(final Context context, final List<ParcelableStatus> data, final int tab_position) {
|
||||
super(context);
|
||||
mFirstLoad = data == null;
|
||||
if (data != null) {
|
||||
mData.addAll(data);
|
||||
}
|
||||
mTabPosition = tab_position;
|
||||
}
|
||||
|
||||
public Long getLastViewedId() {
|
||||
return mLastViewedId;
|
||||
}
|
||||
public Long getLastViewedId() {
|
||||
return mLastViewedId;
|
||||
}
|
||||
|
||||
protected boolean containsStatus(final long status_id) {
|
||||
for (final ParcelableStatus status : mData) {
|
||||
if (status.id == status_id) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
protected boolean containsStatus(final long status_id) {
|
||||
for (final ParcelableStatus status : mData) {
|
||||
if (status.id == status_id) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean deleteStatus(final List<ParcelableStatus> statuses, final long status_id) {
|
||||
if (statuses == null || statuses.isEmpty()) return false;
|
||||
boolean result = false;
|
||||
for (final ParcelableStatus status : statuses.toArray(new ParcelableStatus[statuses.size()])) {
|
||||
if (status.id == status_id) {
|
||||
result |= statuses.remove(status);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
protected boolean deleteStatus(final List<ParcelableStatus> statuses, final long status_id) {
|
||||
if (statuses == null || statuses.isEmpty()) return false;
|
||||
boolean result = false;
|
||||
for (final ParcelableStatus status : statuses.toArray(new ParcelableStatus[statuses.size()])) {
|
||||
if (status.id == status_id) {
|
||||
result |= statuses.remove(status);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected List<ParcelableStatus> getData() {
|
||||
return mData;
|
||||
}
|
||||
protected List<ParcelableStatus> getData() {
|
||||
return mData;
|
||||
}
|
||||
|
||||
protected int getTabPosition() {
|
||||
return mTabPosition;
|
||||
}
|
||||
protected int getTabPosition() {
|
||||
return mTabPosition;
|
||||
}
|
||||
|
||||
protected boolean isFirstLoad() {
|
||||
return mFirstLoad;
|
||||
}
|
||||
protected boolean isFirstLoad() {
|
||||
return mFirstLoad;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStartLoading() {
|
||||
forceLoad();
|
||||
}
|
||||
@Override
|
||||
protected void onStartLoading() {
|
||||
forceLoad();
|
||||
}
|
||||
|
||||
protected void setLastViewedId(final Long id) {
|
||||
mLastViewedId = id;
|
||||
}
|
||||
protected void setLastViewedId(final Long id) {
|
||||
mLastViewedId = id;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -55,16 +55,16 @@ public abstract class Twitter4JStatusesLoader extends ParcelableStatusesLoader {
|
||||
private final Object[] mSavedStatusesFileArgs;
|
||||
|
||||
public Twitter4JStatusesLoader(final Context context, final long account_id, final long max_id,
|
||||
final long since_id, final List<ParcelableStatus> data, final String[] saved_statuses_args,
|
||||
final int tab_position) {
|
||||
super(context, data, tab_position);
|
||||
final long since_id, final List<ParcelableStatus> data, final String[] savedStatusesArgs,
|
||||
final int tabPosition) {
|
||||
super(context, data, tabPosition);
|
||||
mContext = context;
|
||||
mAccountId = account_id;
|
||||
mMaxId = max_id;
|
||||
mSinceId = since_id;
|
||||
mDatabase = TwidereApplication.getInstance(context).getSQLiteDatabase();
|
||||
mHandler = new Handler();
|
||||
mSavedStatusesFileArgs = saved_statuses_args;
|
||||
mSavedStatusesFileArgs = savedStatusesArgs;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@ -118,7 +118,7 @@ public abstract class Twitter4JStatusesLoader extends ParcelableStatusesLoader {
|
||||
}
|
||||
}
|
||||
saveCachedData(serializationFile, data);
|
||||
return new CopyOnWriteArrayList<ParcelableStatus>(data);
|
||||
return new CopyOnWriteArrayList<>(data);
|
||||
}
|
||||
|
||||
protected abstract List<Status> getStatuses(Twitter twitter, Paging paging) throws TwitterException;
|
||||
|
@ -32,7 +32,7 @@ import org.mariotaku.twidere.fragment.support.SearchStatusesFragment;
|
||||
import org.mariotaku.twidere.fragment.support.TrendsSuggectionsFragment;
|
||||
import org.mariotaku.twidere.fragment.support.UserFavoritesFragment;
|
||||
import org.mariotaku.twidere.fragment.support.UserListTimelineFragment;
|
||||
import org.mariotaku.twidere.fragment.support.UserTimelineFragment;
|
||||
import org.mariotaku.twidere.fragment.support.UserTimelineFragmentOld;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Map.Entry;
|
||||
@ -54,7 +54,7 @@ public enum CustomTabConfiguration2 implements Constants {
|
||||
FAVORITES(UserFavoritesFragment.class, R.string.favorites, R.drawable.ic_action_star,
|
||||
CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_USER, 4),
|
||||
|
||||
USER_TIMELINE(UserTimelineFragment.class, R.string.users_statuses, R.drawable.ic_action_quote,
|
||||
USER_TIMELINE(UserTimelineFragmentOld.class, R.string.users_statuses, R.drawable.ic_action_quote,
|
||||
CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_USER, 5),
|
||||
|
||||
SEARCH_STATUSES(SearchStatusesFragment.class, R.string.search_statuses, R.drawable.ic_action_search,
|
||||
|
@ -99,9 +99,9 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
|
||||
public final boolean is_gap, is_retweet, is_favorite, is_possibly_sensitive, user_is_following, user_is_protected,
|
||||
user_is_verified;
|
||||
|
||||
public final String retweeted_by_name, retweeted_by_screen_name, text_html, text_plain, user_name,
|
||||
user_screen_name, in_reply_to_name, in_reply_to_screen_name, source, user_profile_image_url,
|
||||
text_unescaped, first_media;
|
||||
public final String retweeted_by_name, retweeted_by_screen_name, retweeted_by_profile_image,
|
||||
text_html, text_plain, user_name, user_screen_name, in_reply_to_name, in_reply_to_screen_name,
|
||||
source, user_profile_image_url, text_unescaped, first_media;
|
||||
|
||||
public final ParcelableLocation location;
|
||||
|
||||
@ -135,6 +135,7 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
|
||||
my_retweet_id = getAsLong(values, Statuses.MY_RETWEET_ID, -1);
|
||||
retweeted_by_name = values.getAsString(Statuses.RETWEETED_BY_USER_NAME);
|
||||
retweeted_by_screen_name = values.getAsString(Statuses.RETWEETED_BY_USER_SCREEN_NAME);
|
||||
retweeted_by_profile_image = values.getAsString(Statuses.RETWEETED_BY_USER_PROFILE_IMAGE);
|
||||
source = values.getAsString(Statuses.SOURCE);
|
||||
retweet_count = getAsInteger(values, Statuses.RETWEET_COUNT, 0);
|
||||
favorite_count = getAsInteger(values, Statuses.FAVORITE_COUNT, 0);
|
||||
@ -170,6 +171,8 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
|
||||
retweeted_by_name = idx.retweeted_by_user_name != -1 ? c.getString(idx.retweeted_by_user_name) : null;
|
||||
retweeted_by_screen_name = idx.retweeted_by_user_screen_name != -1 ? c
|
||||
.getString(idx.retweeted_by_user_screen_name) : null;
|
||||
retweeted_by_profile_image = idx.retweeted_by_user_profile_image != -1 ? c
|
||||
.getString(idx.retweeted_by_user_profile_image) : null;
|
||||
text_html = idx.text_html != -1 ? c.getString(idx.text_html) : null;
|
||||
media = ParcelableMedia.fromJSONString(idx.media != -1 ? c.getString(idx.media) : null);
|
||||
text_plain = idx.text_plain != -1 ? c.getString(idx.text_plain) : null;
|
||||
@ -210,6 +213,7 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
|
||||
user_is_verified = in.readBoolean("is_verified");
|
||||
retweeted_by_name = in.readString("retweeted_by_name");
|
||||
retweeted_by_screen_name = in.readString("retweeted_by_screen_name");
|
||||
retweeted_by_profile_image = in.readString("retweeted_by_profile_image");
|
||||
text_html = in.readString("text_html");
|
||||
text_plain = in.readString("text_plain");
|
||||
user_name = in.readString("name");
|
||||
@ -248,6 +252,7 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
|
||||
user_is_verified = in.readInt() == 1;
|
||||
retweeted_by_name = in.readString();
|
||||
retweeted_by_screen_name = in.readString();
|
||||
retweeted_by_profile_image = in.readString();
|
||||
text_html = in.readString();
|
||||
text_plain = in.readString();
|
||||
user_name = in.readString();
|
||||
@ -280,6 +285,8 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
|
||||
retweeted_by_id = retweet_user != null ? retweet_user.getId() : -1;
|
||||
retweeted_by_name = retweet_user != null ? retweet_user.getName() : null;
|
||||
retweeted_by_screen_name = retweet_user != null ? retweet_user.getScreenName() : null;
|
||||
retweeted_by_profile_image = retweet_user != null ?
|
||||
ParseUtils.parseString(retweet_user.getProfileImageUrlHttps()) : null;
|
||||
final Status status = retweeted != null ? retweeted : orig;
|
||||
final User user = status.getUser();
|
||||
user_id = user.getId();
|
||||
@ -343,20 +350,45 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ParcelableStatus{retweet_id=" + retweet_id + ", retweeted_by_id=" + retweeted_by_id + ", id=" + id
|
||||
+ ", account_id=" + account_id + ", user_id=" + user_id + ", timestamp=" + timestamp
|
||||
+ ", retweet_count=" + retweet_count + ", favorite_count=" + favorite_count
|
||||
+ ", in_reply_to_status_id=" + in_reply_to_status_id + ", in_reply_to_user_id=" + in_reply_to_user_id
|
||||
+ ", my_retweet_id=" + my_retweet_id + ", is_gap=" + is_gap + ", is_retweet=" + is_retweet
|
||||
+ ", is_favorite=" + is_favorite + ", is_possibly_sensitive=" + is_possibly_sensitive
|
||||
+ ", user_is_following=" + user_is_following + ", user_is_protected=" + user_is_protected
|
||||
+ ", user_is_verified=" + user_is_verified + ", retweeted_by_name=" + retweeted_by_name
|
||||
+ ", retweeted_by_screen_name=" + retweeted_by_screen_name + ", text_html=" + text_html
|
||||
+ ", text_plain=" + text_plain + ", user_name=" + user_name + ", user_screen_name=" + user_screen_name
|
||||
+ ", in_reply_to_name=" + in_reply_to_name + ", in_reply_to_screen_name=" + in_reply_to_screen_name
|
||||
+ ", source=" + source + ", user_profile_image_url=" + user_profile_image_url + ", text_unescaped="
|
||||
+ text_unescaped + ", first_media=" + first_media + ", location=" + location + ", mentions="
|
||||
+ Arrays.toString(mentions) + ", media=" + Arrays.toString(media) + "}";
|
||||
return "ParcelableStatus{" +
|
||||
"id=" + id +
|
||||
", account_id=" + account_id +
|
||||
", timestamp=" + timestamp +
|
||||
", user_id=" + user_id +
|
||||
", retweet_id=" + retweet_id +
|
||||
", retweeted_by_id=" + retweeted_by_id +
|
||||
", retweet_timestamp=" + retweet_timestamp +
|
||||
", retweet_count=" + retweet_count +
|
||||
", favorite_count=" + favorite_count +
|
||||
", reply_count=" + reply_count +
|
||||
", descendent_reply_count=" + descendent_reply_count +
|
||||
", in_reply_to_status_id=" + in_reply_to_status_id +
|
||||
", in_reply_to_user_id=" + in_reply_to_user_id +
|
||||
", my_retweet_id=" + my_retweet_id +
|
||||
", is_gap=" + is_gap +
|
||||
", is_retweet=" + is_retweet +
|
||||
", is_favorite=" + is_favorite +
|
||||
", is_possibly_sensitive=" + is_possibly_sensitive +
|
||||
", user_is_following=" + user_is_following +
|
||||
", user_is_protected=" + user_is_protected +
|
||||
", user_is_verified=" + user_is_verified +
|
||||
", retweeted_by_name='" + retweeted_by_name + '\'' +
|
||||
", retweeted_by_screen_name='" + retweeted_by_screen_name + '\'' +
|
||||
", retweeted_by_profile_image='" + retweeted_by_profile_image + '\'' +
|
||||
", text_html='" + text_html + '\'' +
|
||||
", text_plain='" + text_plain + '\'' +
|
||||
", user_name='" + user_name + '\'' +
|
||||
", user_screen_name='" + user_screen_name + '\'' +
|
||||
", in_reply_to_name='" + in_reply_to_name + '\'' +
|
||||
", in_reply_to_screen_name='" + in_reply_to_screen_name + '\'' +
|
||||
", source='" + source + '\'' +
|
||||
", user_profile_image_url='" + user_profile_image_url + '\'' +
|
||||
", text_unescaped='" + text_unescaped + '\'' +
|
||||
", first_media='" + first_media + '\'' +
|
||||
", location=" + location +
|
||||
", mentions=" + Arrays.toString(mentions) +
|
||||
", media=" + Arrays.toString(media) +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -381,6 +413,7 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
|
||||
out.writeBoolean("is_verified", user_is_verified);
|
||||
out.writeString("retweeted_by_name", retweeted_by_name);
|
||||
out.writeString("retweeted_by_screen_name", retweeted_by_screen_name);
|
||||
out.writeString("retweeted_by_profile_image", retweeted_by_profile_image);
|
||||
out.writeString("text_html", text_html);
|
||||
out.writeString("text_plain", text_plain);
|
||||
out.writeString("text_unescaped", text_unescaped);
|
||||
@ -419,6 +452,7 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
|
||||
out.writeInt(user_is_verified ? 1 : 0);
|
||||
out.writeString(retweeted_by_name);
|
||||
out.writeString(retweeted_by_screen_name);
|
||||
out.writeString(retweeted_by_profile_image);
|
||||
out.writeString(text_html);
|
||||
out.writeString(text_plain);
|
||||
out.writeString(user_name);
|
||||
@ -447,9 +481,9 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
|
||||
text_html, text_plain, text_unescaped, user_profile_image_url, is_favorite, is_retweet,
|
||||
is_gap, location, is_protected, is_verified, in_reply_to_status_id, in_reply_to_user_id,
|
||||
in_reply_to_user_name, in_reply_to_user_screen_name, my_retweet_id, retweeted_by_user_name,
|
||||
retweeted_by_user_screen_name, retweet_id, retweet_timestamp, retweeted_by_user_id,
|
||||
user_id, source, retweet_count, favorite_count, reply_count, descendent_reply_count,
|
||||
is_possibly_sensitive, is_following, media, first_media, mentions;
|
||||
retweeted_by_user_screen_name, retweeted_by_user_profile_image, retweet_id, retweet_timestamp,
|
||||
retweeted_by_user_id, user_id, source, retweet_count, favorite_count, reply_count,
|
||||
descendent_reply_count, is_possibly_sensitive, is_following, media, first_media, mentions;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
@ -521,6 +555,7 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
|
||||
retweeted_by_user_id = cursor.getColumnIndex(Statuses.RETWEETED_BY_USER_ID);
|
||||
retweeted_by_user_name = cursor.getColumnIndex(Statuses.RETWEETED_BY_USER_NAME);
|
||||
retweeted_by_user_screen_name = cursor.getColumnIndex(Statuses.RETWEETED_BY_USER_SCREEN_NAME);
|
||||
retweeted_by_user_profile_image = cursor.getColumnIndex(Statuses.RETWEETED_BY_USER_PROFILE_IMAGE);
|
||||
user_id = cursor.getColumnIndex(Statuses.USER_ID);
|
||||
source = cursor.getColumnIndex(Statuses.SOURCE);
|
||||
retweet_count = cursor.getColumnIndex(Statuses.RETWEET_COUNT);
|
||||
|
@ -40,14 +40,14 @@ import org.mariotaku.twidere.util.ThemeUtils;
|
||||
import org.mariotaku.twidere.util.TwidereLinkify;
|
||||
import org.mariotaku.twidere.view.CardItemLinearLayout;
|
||||
import org.mariotaku.twidere.view.ForegroundImageView;
|
||||
import org.mariotaku.twidere.view.holder.StatusViewHolder;
|
||||
import org.mariotaku.twidere.view.holder.StatusListViewHolder;
|
||||
|
||||
public class CardPreviewPreference extends Preference implements Constants, OnSharedPreferenceChangeListener {
|
||||
|
||||
private final LayoutInflater mInflater;
|
||||
private final SharedPreferences mPreferences;
|
||||
private final TwidereLinkify mLinkify;
|
||||
private StatusViewHolder mHolder;
|
||||
private StatusListViewHolder mHolder;
|
||||
private boolean mCompactModeChanged;
|
||||
|
||||
public CardPreviewPreference(final Context context) {
|
||||
@ -92,7 +92,7 @@ public class CardPreviewPreference extends Preference implements Constants, OnSh
|
||||
final boolean display_image_preview = mPreferences.getBoolean(KEY_DISPLAY_IMAGE_PREVIEW, false);
|
||||
final boolean display_profile_image = mPreferences.getBoolean(KEY_DISPLAY_PROFILE_IMAGE, true);
|
||||
final boolean nickname_only = mPreferences.getBoolean(KEY_NICKNAME_ONLY, false);
|
||||
mHolder = new StatusViewHolder(view);
|
||||
mHolder = new StatusListViewHolder(view);
|
||||
mLinkify.setHighlightOption(highlightOption);
|
||||
mHolder.setDisplayNameFirst(nameFirst);
|
||||
mHolder.setNicknameOnly(nickname_only);
|
||||
|
@ -700,6 +700,8 @@ public interface TweetStore {
|
||||
|
||||
public static final String RETWEETED_BY_USER_SCREEN_NAME = "retweeted_by_user_screen_name";
|
||||
|
||||
public static final String RETWEETED_BY_USER_PROFILE_IMAGE = "retweeted_by_user_profile_image";
|
||||
|
||||
/**
|
||||
* Timestamp of the status.<br>
|
||||
* Type: INTEGER (long)
|
||||
@ -723,18 +725,18 @@ public interface TweetStore {
|
||||
public static final String[] COLUMNS = new String[]{_ID, ACCOUNT_ID, STATUS_ID, USER_ID,
|
||||
STATUS_TIMESTAMP, TEXT_HTML, TEXT_PLAIN, TEXT_UNESCAPED, USER_NAME, USER_SCREEN_NAME,
|
||||
USER_PROFILE_IMAGE_URL, IN_REPLY_TO_STATUS_ID, IN_REPLY_TO_USER_ID, IN_REPLY_TO_USER_NAME,
|
||||
IN_REPLY_TO_USER_SCREEN_NAME, SOURCE, LOCATION, RETWEET_COUNT, FAVORITE_COUNT,
|
||||
REPLY_COUNT, DESCENDENT_REPLY_COUNT, RETWEET_ID, RETWEET_TIMESTAMP,
|
||||
RETWEETED_BY_USER_ID, RETWEETED_BY_USER_NAME, RETWEETED_BY_USER_SCREEN_NAME,
|
||||
MY_RETWEET_ID, IS_RETWEET, IS_FAVORITE, IS_PROTECTED, IS_VERIFIED, IS_FOLLOWING,
|
||||
IS_GAP, IS_POSSIBLY_SENSITIVE, MEDIA, FIRST_MEDIA, MENTIONS};
|
||||
IN_REPLY_TO_USER_SCREEN_NAME, SOURCE, LOCATION, RETWEET_COUNT, FAVORITE_COUNT, REPLY_COUNT,
|
||||
DESCENDENT_REPLY_COUNT, RETWEET_ID, RETWEET_TIMESTAMP, RETWEETED_BY_USER_ID,
|
||||
RETWEETED_BY_USER_NAME, RETWEETED_BY_USER_SCREEN_NAME, RETWEETED_BY_USER_PROFILE_IMAGE,
|
||||
MY_RETWEET_ID, IS_RETWEET, IS_FAVORITE, IS_PROTECTED, IS_VERIFIED, IS_FOLLOWING, IS_GAP,
|
||||
IS_POSSIBLY_SENSITIVE, MEDIA, FIRST_MEDIA, MENTIONS};
|
||||
|
||||
public static final String[] TYPES = new String[]{TYPE_PRIMARY_KEY, TYPE_INT, TYPE_INT,
|
||||
TYPE_INT, TYPE_INT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT,
|
||||
TYPE_INT, TYPE_INT, TYPE_INT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_INT,
|
||||
TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_TEXT, TYPE_TEXT, TYPE_INT,
|
||||
TYPE_BOOLEAN, TYPE_BOOLEAN, TYPE_BOOLEAN, TYPE_BOOLEAN, TYPE_BOOLEAN, TYPE_BOOLEAN,
|
||||
TYPE_BOOLEAN, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT};
|
||||
TYPE_INT, TYPE_INT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_INT, TYPE_INT,
|
||||
TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_TEXT, TYPE_TEXT,
|
||||
TYPE_TEXT, TYPE_INT, TYPE_BOOLEAN, TYPE_BOOLEAN, TYPE_BOOLEAN, TYPE_BOOLEAN,
|
||||
TYPE_BOOLEAN, TYPE_BOOLEAN, TYPE_BOOLEAN, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT};
|
||||
|
||||
}
|
||||
|
||||
|
@ -255,10 +255,10 @@ public final class ContentValuesCreator implements TwidereConstants {
|
||||
return values;
|
||||
}
|
||||
|
||||
public static ContentValues makeStatusContentValues(final Status orig, final long account_id) {
|
||||
public static ContentValues makeStatusContentValues(final Status orig, final long accountId) {
|
||||
if (orig == null || orig.getId() <= 0) return null;
|
||||
final ContentValues values = new ContentValues();
|
||||
values.put(Statuses.ACCOUNT_ID, account_id);
|
||||
values.put(Statuses.ACCOUNT_ID, accountId);
|
||||
values.put(Statuses.STATUS_ID, orig.getId());
|
||||
values.put(Statuses.STATUS_TIMESTAMP, orig.getCreatedAt().getTime());
|
||||
values.put(Statuses.MY_RETWEET_ID, orig.getCurrentUserRetweet());
|
||||
@ -272,6 +272,7 @@ public final class ContentValuesCreator implements TwidereConstants {
|
||||
values.put(Statuses.RETWEETED_BY_USER_ID, retweetUser.getId());
|
||||
values.put(Statuses.RETWEETED_BY_USER_NAME, retweetUser.getName());
|
||||
values.put(Statuses.RETWEETED_BY_USER_SCREEN_NAME, retweetUser.getScreenName());
|
||||
values.put(Statuses.RETWEETED_BY_USER_PROFILE_IMAGE, ParseUtils.parseString(retweetUser.getProfileImageUrlHttps()));
|
||||
status = retweetedStatus;
|
||||
} else {
|
||||
status = orig;
|
||||
|
@ -46,7 +46,7 @@ import org.mariotaku.twidere.fragment.support.StaggeredHomeTimelineFragment;
|
||||
import org.mariotaku.twidere.fragment.support.TrendsSuggectionsFragment;
|
||||
import org.mariotaku.twidere.fragment.support.UserFavoritesFragment;
|
||||
import org.mariotaku.twidere.fragment.support.UserListTimelineFragment;
|
||||
import org.mariotaku.twidere.fragment.support.UserTimelineFragment;
|
||||
import org.mariotaku.twidere.fragment.support.UserTimelineFragmentOld;
|
||||
import org.mariotaku.twidere.model.CustomTabConfiguration;
|
||||
import org.mariotaku.twidere.model.CustomTabConfiguration.ExtraConfiguration;
|
||||
import org.mariotaku.twidere.model.SupportTabSpec;
|
||||
@ -81,7 +81,7 @@ public class CustomTabUtils implements Constants {
|
||||
R.string.favorites, R.drawable.ic_action_star, CustomTabConfiguration.ACCOUNT_REQUIRED,
|
||||
CustomTabConfiguration.FIELD_TYPE_USER, 4));
|
||||
CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_USER_TIMELINE, new CustomTabConfiguration(
|
||||
UserTimelineFragment.class, R.string.users_statuses, R.drawable.ic_action_quote,
|
||||
UserTimelineFragmentOld.class, R.string.users_statuses, R.drawable.ic_action_quote,
|
||||
CustomTabConfiguration.ACCOUNT_REQUIRED, CustomTabConfiguration.FIELD_TYPE_USER, 5));
|
||||
CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_SEARCH_STATUSES, new CustomTabConfiguration(
|
||||
SearchStatusesFragment.class, R.string.search_statuses, R.drawable.ic_action_search,
|
||||
|
@ -62,7 +62,7 @@ public class ThemeUtils implements Constants {
|
||||
private static final int[] ANIM_CLOSE_STYLE_ATTRS = {android.R.attr.activityCloseEnterAnimation,
|
||||
android.R.attr.activityCloseExitAnimation};
|
||||
|
||||
private static final String[] sClassPrefixList = {"android.widget.", "android.webkit."};
|
||||
private static final String[] sClassPrefixList = {"android.widget.", "android.webkit.", "org.mariotaku.twidere.view"};
|
||||
|
||||
private ThemeUtils() {
|
||||
throw new AssertionError();
|
||||
@ -181,6 +181,9 @@ public class ThemeUtils implements Constants {
|
||||
|
||||
public static RefreshNowConfig buildRefreshNowConfig(final Context context) {
|
||||
final RefreshNowConfig.Builder builder = new RefreshNowConfig.Builder(context);
|
||||
builder.minPullDivisor(2);
|
||||
builder.extraPullDivisor(1);
|
||||
builder.maxOverScrollDistance(72);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,7 @@ import android.os.Bundle;
|
||||
import android.os.SystemClock;
|
||||
import android.provider.BaseColumns;
|
||||
import android.provider.MediaStore;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
@ -143,7 +144,7 @@ import org.mariotaku.twidere.fragment.support.UserListsListFragment;
|
||||
import org.mariotaku.twidere.fragment.support.UserMediaTimelineFragment;
|
||||
import org.mariotaku.twidere.fragment.support.UserMentionsFragment;
|
||||
import org.mariotaku.twidere.fragment.support.UserProfileFragmentOld;
|
||||
import org.mariotaku.twidere.fragment.support.UserTimelineFragment2;
|
||||
import org.mariotaku.twidere.fragment.support.UserTimelineFragment;
|
||||
import org.mariotaku.twidere.fragment.support.UsersListFragment;
|
||||
import org.mariotaku.twidere.graphic.PaddingDrawable;
|
||||
import org.mariotaku.twidere.model.Account;
|
||||
@ -746,7 +747,7 @@ public final class Utils implements Constants, TwitterConstants {
|
||||
break;
|
||||
}
|
||||
case LINK_ID_USER_TIMELINE: {
|
||||
fragment = new UserTimelineFragment2();
|
||||
fragment = new UserTimelineFragment();
|
||||
final String paramScreenName = uri.getQueryParameter(QUERY_PARAM_SCREEN_NAME);
|
||||
final String paramUserId = uri.getQueryParameter(QUERY_PARAM_USER_ID);
|
||||
if (!args.containsKey(EXTRA_SCREEN_NAME)) {
|
||||
@ -1841,14 +1842,14 @@ public final class Utils implements Constants, TwitterConstants {
|
||||
FORMAT_PATTERN_TEXT, text);
|
||||
}
|
||||
|
||||
public static String getInReplyToName(final Status status) {
|
||||
if (status == null) return null;
|
||||
@NonNull
|
||||
public static String getInReplyToName(@NonNull final Status status) {
|
||||
final Status orig = status.isRetweet() ? status.getRetweetedStatus() : status;
|
||||
final long in_reply_to_user_id = status.getInReplyToUserId();
|
||||
final long inReplyToUserId = status.getInReplyToUserId();
|
||||
final UserMentionEntity[] entities = status.getUserMentionEntities();
|
||||
if (entities == null) return orig.getInReplyToScreenName();
|
||||
for (final UserMentionEntity entity : entities) {
|
||||
if (in_reply_to_user_id == entity.getId()) return entity.getName();
|
||||
if (inReplyToUserId == entity.getId()) return entity.getName();
|
||||
}
|
||||
return orig.getInReplyToScreenName();
|
||||
}
|
||||
|
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.view;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.PorterDuff.Mode;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/11/20.
|
||||
*/
|
||||
public class CardActionTextView extends TextView {
|
||||
|
||||
private int mColor;
|
||||
private int mActivatedColor;
|
||||
|
||||
public CardActionTextView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public CardActionTextView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public CardActionTextView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
final TypedArray defaultValues = context.obtainStyledAttributes(
|
||||
new int[]{android.R.attr.colorActivatedHighlight});
|
||||
final int defaultActivatedColor = defaultValues.getColor(0, 0);
|
||||
defaultValues.recycle();
|
||||
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.IconActionButton);
|
||||
mColor = a.getColor(R.styleable.IconActionButton_color, 0);
|
||||
mActivatedColor = a.getColor(R.styleable.IconActionButton_activatedColor, defaultActivatedColor);
|
||||
a.recycle();
|
||||
updateColorFilter();
|
||||
}
|
||||
|
||||
public int getActivatedColor() {
|
||||
return mActivatedColor;
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return mColor != 0 ? mColor : getCurrentTextColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActivated(boolean activated) {
|
||||
super.setActivated(activated);
|
||||
updateColorFilter();
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
|
||||
@Override
|
||||
public void setCompoundDrawablesRelative(Drawable start, Drawable top, Drawable end, Drawable bottom) {
|
||||
super.setCompoundDrawablesRelative(start, top, end, bottom);
|
||||
updateColorFilter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCompoundDrawables(Drawable left, Drawable top, Drawable right, Drawable bottom) {
|
||||
super.setCompoundDrawables(left, top, right, bottom);
|
||||
updateColorFilter();
|
||||
}
|
||||
|
||||
private void updateColorFilter() {
|
||||
for (Drawable d : getCompoundDrawables()) {
|
||||
if (d != null) {
|
||||
d.mutate();
|
||||
d.setColorFilter(isActivated() ? getActivatedColor() : getColor(), Mode.SRC_ATOP);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,331 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.view;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Bitmap.Config;
|
||||
import android.graphics.BitmapShader;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Outline;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuff.Mode;
|
||||
import android.graphics.PorterDuffXfermode;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Shader;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.StateListDrawable;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.ViewOutlineProvider;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
|
||||
/**
|
||||
* An ImageView class with a circle mask so that all images are drawn in a
|
||||
* circle instead of a square.
|
||||
*/
|
||||
public class CircularImageView extends ImageView {
|
||||
|
||||
private static final int SHADOW_START_COLOR = 0x37000000;
|
||||
|
||||
private static final boolean USE_OUTLINE = false && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
|
||||
|
||||
private final Matrix mMatrix;
|
||||
private final RectF mSource;
|
||||
private final RectF mDestination;
|
||||
private final Paint mBitmapPaint;
|
||||
private final Paint mBorderPaint;
|
||||
|
||||
private boolean mBorderEnabled;
|
||||
private Bitmap mShadowBitmap;
|
||||
private float mShadowRadius;
|
||||
private Drawable mBackground;
|
||||
|
||||
public CircularImageView(Context context) {
|
||||
this(context, null, 0);
|
||||
}
|
||||
|
||||
public CircularImageView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public CircularImageView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
|
||||
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircularImageView, defStyle, 0);
|
||||
|
||||
mMatrix = new Matrix();
|
||||
mSource = new RectF();
|
||||
mDestination = new RectF();
|
||||
|
||||
mBitmapPaint = new Paint(Paint.LINEAR_TEXT_FLAG);
|
||||
mBitmapPaint.setFilterBitmap(true);
|
||||
mBitmapPaint.setDither(true);
|
||||
|
||||
mBorderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mBorderPaint.setStyle(Paint.Style.STROKE);
|
||||
|
||||
if (a.hasValue(R.styleable.CircularImageView_border)) {
|
||||
setBorderEnabled(a.getBoolean(R.styleable.CircularImageView_border, false));
|
||||
} else if (a.hasValue(R.styleable.CircularImageView_borderColor)
|
||||
|| a.hasValue(R.styleable.CircularImageView_borderWidth)) {
|
||||
setBorderEnabled(true);
|
||||
}
|
||||
setBorderColor(a.getColor(R.styleable.CircularImageView_borderColor, Color.TRANSPARENT));
|
||||
setBorderWidth(a.getDimensionPixelSize(R.styleable.CircularImageView_borderWidth, 0));
|
||||
|
||||
if (USE_OUTLINE) {
|
||||
if (a.hasValue(R.styleable.CircularImageView_elevation)) {
|
||||
ViewCompat.setElevation(this,
|
||||
a.getDimensionPixelSize(R.styleable.CircularImageView_elevation, 0));
|
||||
}
|
||||
} else {
|
||||
mShadowRadius = a.getDimensionPixelSize(R.styleable.CircularImageView_elevation, 0);
|
||||
}
|
||||
|
||||
a.recycle();
|
||||
|
||||
if (USE_OUTLINE) {
|
||||
initOutlineProvider();
|
||||
}
|
||||
}
|
||||
|
||||
public void setBorderWidth(int width) {
|
||||
mBorderPaint.setStrokeWidth(width);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setBorderEnabled(boolean enabled) {
|
||||
mBorderEnabled = enabled;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setBorderColor(int color) {
|
||||
mBorderPaint.setARGB(Color.alpha(color), Color.red(color), Color.green(color),
|
||||
Color.blue(color));
|
||||
invalidate();
|
||||
}
|
||||
|
||||
private void initOutlineProvider() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
setClipToOutline(true);
|
||||
setOutlineProvider(new CircularOutlineProvider());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
updateShadowBitmap();
|
||||
updateBackgroundPadding();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPadding(int left, int top, int right, int bottom) {
|
||||
super.setPadding(left, top, right, bottom);
|
||||
updateShadowBitmap();
|
||||
updateBackgroundPadding();
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
|
||||
@Override
|
||||
public void setPaddingRelative(int start, int top, int end, int bottom) {
|
||||
super.setPaddingRelative(start, top, end, bottom);
|
||||
updateShadowBitmap();
|
||||
updateBackgroundPadding();
|
||||
}
|
||||
|
||||
private void updateShadowBitmap() {
|
||||
if (USE_OUTLINE) return;
|
||||
final int width = getWidth(), height = getHeight();
|
||||
if (width <= 0 || height <= 0) return;
|
||||
final int contentLeft = getPaddingLeft(), contentTop = getPaddingTop(),
|
||||
contentRight = width - getPaddingRight(),
|
||||
contentBottom = height - getPaddingBottom();
|
||||
final int contentWidth = contentRight - contentLeft,
|
||||
contentHeight = contentBottom - contentTop;
|
||||
final float radius = mShadowRadius, dy = radius * 1.5f / 2;
|
||||
final int size = Math.round(Math.min(contentWidth, contentHeight) + radius * 2);
|
||||
mShadowBitmap = Bitmap.createBitmap(size, Math.round(size + dy), Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(mShadowBitmap);
|
||||
final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
paint.setColor(Color.WHITE);
|
||||
paint.setShadowLayer(radius, 0, radius * 1.5f / 2, SHADOW_START_COLOR);
|
||||
final RectF rect = new RectF(radius, radius, size - radius, size - radius);
|
||||
canvas.drawOval(rect, paint);
|
||||
paint.setShadowLayer(0, 0, 0, 0);
|
||||
paint.setXfermode(new PorterDuffXfermode(Mode.CLEAR));
|
||||
canvas.drawOval(rect, paint);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
if (mBackground != null) {
|
||||
mBackground.draw(canvas);
|
||||
}
|
||||
super.dispatchDraw(canvas);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackgroundDrawable(Drawable background) {
|
||||
if (USE_OUTLINE) {
|
||||
super.setBackgroundDrawable(background);
|
||||
return;
|
||||
}
|
||||
super.setBackgroundDrawable(null);
|
||||
mBackground = background;
|
||||
updateBackgroundPadding();
|
||||
}
|
||||
|
||||
private void updateBackgroundPadding() {
|
||||
if (USE_OUTLINE) return;
|
||||
final Drawable drawable = mBackground;
|
||||
if (drawable == null) return;
|
||||
final int width = getWidth(), height = getHeight();
|
||||
if (width <= 0 || height <= 0) return;
|
||||
final int contentLeft = getPaddingLeft(), contentTop = getPaddingTop(),
|
||||
contentRight = width - getPaddingRight(),
|
||||
contentBottom = height - getPaddingBottom();
|
||||
final int contentWidth = contentRight - contentLeft,
|
||||
contentHeight = contentBottom - contentTop;
|
||||
final int size = Math.min(contentWidth, contentHeight);
|
||||
drawable.setBounds(contentLeft + (contentWidth - size) / 2,
|
||||
contentTop + (contentHeight - size) / 2,
|
||||
contentRight - (contentWidth - size) / 2,
|
||||
contentBottom - (contentHeight - size) / 2);
|
||||
}
|
||||
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
|
||||
@Override
|
||||
public void setBackground(Drawable background) {
|
||||
if (USE_OUTLINE) {
|
||||
super.setBackground(background);
|
||||
return;
|
||||
}
|
||||
super.setBackground(null);
|
||||
mBackground = background;
|
||||
updateBackgroundPadding();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(@NonNull Canvas canvas) {
|
||||
|
||||
mDestination.set(getPaddingLeft(), getPaddingTop(), getWidth() - getPaddingRight(),
|
||||
getHeight() - getPaddingBottom());
|
||||
|
||||
if (USE_OUTLINE) {
|
||||
super.onDraw(canvas);
|
||||
} else {
|
||||
final int contentLeft = getPaddingLeft(), contentTop = getPaddingTop(),
|
||||
contentRight = getWidth() - getPaddingRight(),
|
||||
contentBottom = getHeight() - getPaddingBottom();
|
||||
final int contentWidth = contentRight - contentLeft,
|
||||
contentHeight = contentBottom - contentTop;
|
||||
final int size = Math.min(contentWidth, contentHeight);
|
||||
if (mShadowBitmap != null) {
|
||||
canvas.drawBitmap(mShadowBitmap, contentLeft + (contentWidth - size) / 2 - mShadowRadius,
|
||||
contentTop + (contentHeight - size) / 2 - mShadowRadius, null);
|
||||
}
|
||||
Drawable drawable = getDrawable();
|
||||
BitmapDrawable bitmapDrawable = null;
|
||||
// support state list drawable by getting the current state
|
||||
if (drawable instanceof StateListDrawable) {
|
||||
if (drawable.getCurrent() != null) {
|
||||
bitmapDrawable = (BitmapDrawable) drawable.getCurrent();
|
||||
}
|
||||
} else {
|
||||
bitmapDrawable = (BitmapDrawable) drawable;
|
||||
}
|
||||
|
||||
if (bitmapDrawable == null) {
|
||||
return;
|
||||
}
|
||||
Bitmap bitmap = bitmapDrawable.getBitmap();
|
||||
if (bitmap == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
mSource.set(0, 0, bitmap.getWidth(), bitmap.getHeight());
|
||||
|
||||
drawBitmapWithCircleOnCanvas(bitmap, canvas, mSource, mDestination);
|
||||
}
|
||||
|
||||
// Then draw the border.
|
||||
if (mBorderEnabled) {
|
||||
canvas.drawCircle(mDestination.centerX(), mDestination.centerY(),
|
||||
mDestination.width() / 2f - mBorderPaint.getStrokeWidth() / 2, mBorderPaint);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the source bitmap and a canvas, draws the bitmap through a circular
|
||||
* mask. Only draws a circle with diameter equal to the destination width.
|
||||
*
|
||||
* @param bitmap The source bitmap to draw.
|
||||
* @param canvas The canvas to draw it on.
|
||||
* @param source The source bound of the bitmap.
|
||||
* @param dest The destination bound on the canvas.
|
||||
*/
|
||||
public void drawBitmapWithCircleOnCanvas(Bitmap bitmap, Canvas canvas,
|
||||
RectF source, RectF dest) {
|
||||
// Draw bitmap through shader first.
|
||||
BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP,
|
||||
Shader.TileMode.CLAMP);
|
||||
mMatrix.reset();
|
||||
|
||||
// Fit bitmap to bounds.
|
||||
mMatrix.setRectToRect(source, dest, Matrix.ScaleToFit.FILL);
|
||||
|
||||
shader.setLocalMatrix(mMatrix);
|
||||
mBitmapPaint.setShader(shader);
|
||||
canvas.drawCircle(dest.centerX(), dest.centerY(), Math.min(dest.width(), dest.height()) / 2f,
|
||||
mBitmapPaint);
|
||||
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
private static class CircularOutlineProvider extends ViewOutlineProvider {
|
||||
@Override
|
||||
public void getOutline(View view, Outline outline) {
|
||||
final int contentLeft = view.getPaddingLeft(), contentTop = view.getPaddingTop(),
|
||||
contentRight = view.getWidth() - view.getPaddingRight(),
|
||||
contentBottom = view.getHeight() - view.getPaddingBottom();
|
||||
final int contentWidth = contentRight - contentLeft,
|
||||
contentHeight = contentBottom - contentTop;
|
||||
final int size = Math.min(contentWidth, contentHeight);
|
||||
outline.setOval(contentLeft + (contentWidth - size) / 2,
|
||||
contentTop + (contentHeight - size) / 2,
|
||||
contentRight - (contentWidth - size) / 2,
|
||||
contentBottom - (contentHeight - size) / 2);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package org.mariotaku.twidere.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.IdRes;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.handmark.pulltorefresh.library.PullToRefreshBase;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/11/19.
|
||||
*/
|
||||
public class PullToRefreshVerticalRecyclerView extends PullToRefreshBase<RecyclerView> {
|
||||
|
||||
@IdRes
|
||||
public static final int REFRESHABLE_VIEW_ID = 0x7f200001;
|
||||
|
||||
public PullToRefreshVerticalRecyclerView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public PullToRefreshVerticalRecyclerView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public PullToRefreshVerticalRecyclerView(Context context, Mode mode) {
|
||||
super(context, mode);
|
||||
}
|
||||
|
||||
public PullToRefreshVerticalRecyclerView(Context context, Mode mode, AnimationStyle animStyle) {
|
||||
super(context, mode, animStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Orientation getPullToRefreshScrollDirection() {
|
||||
return Orientation.VERTICAL;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RecyclerView createRefreshableView(Context context, AttributeSet attrs) {
|
||||
final RecyclerView recyclerView = new RecyclerView(context, attrs);
|
||||
recyclerView.setId(REFRESHABLE_VIEW_ID);
|
||||
return recyclerView;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isReadyForPullStart() {
|
||||
final RecyclerView recyclerView = getRefreshableView();
|
||||
if (recyclerView.getChildCount() <= 0)
|
||||
return true;
|
||||
int firstVisiblePosition = recyclerView.getChildPosition(recyclerView.getChildAt(0));
|
||||
if (firstVisiblePosition == 0)
|
||||
return recyclerView.getChildAt(0).getTop() == 0;
|
||||
else
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isReadyForPullEnd() {
|
||||
final RecyclerView recyclerView = getRefreshableView();
|
||||
int lastVisiblePosition = recyclerView.getChildPosition(recyclerView.getChildAt(recyclerView.getChildCount() - 1));
|
||||
if (lastVisiblePosition >= recyclerView.getAdapter().getItemCount() - 1) {
|
||||
return recyclerView.getChildAt(recyclerView.getChildCount() - 1).getBottom() <= recyclerView.getBottom();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -26,7 +26,7 @@ import android.widget.TextView;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
|
||||
public class ActivityViewHolder extends StatusViewHolder {
|
||||
public class ActivityListViewHolder extends StatusListViewHolder {
|
||||
|
||||
public final ImageView activity_profile_image_1, activity_profile_image_2, activity_profile_image_3,
|
||||
activity_profile_image_4, activity_profile_image_5;
|
||||
@ -35,7 +35,7 @@ public class ActivityViewHolder extends StatusViewHolder {
|
||||
public final TextView activity_profile_image_more_number;
|
||||
public final View divider;
|
||||
|
||||
public ActivityViewHolder(final View view) {
|
||||
public ActivityListViewHolder(final View view) {
|
||||
super(view);
|
||||
divider = findViewById(R.id.divider);
|
||||
activity_profile_images_container = (ViewGroup) findViewById(R.id.activity_profile_image_container);
|
@ -0,0 +1,14 @@
|
||||
package org.mariotaku.twidere.view.holder;
|
||||
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.RecyclerView.*;
|
||||
import android.view.View;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/11/19.
|
||||
*/
|
||||
public class LoadIndicatorViewHolder extends RecyclerView.ViewHolder {
|
||||
public LoadIndicatorViewHolder(View view) {
|
||||
super(view);
|
||||
}
|
||||
}
|
@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.view.holder;
|
||||
|
||||
import static org.mariotaku.twidere.util.Utils.getDisplayName;
|
||||
import static org.mariotaku.twidere.util.Utils.getStatusTypeIconRes;
|
||||
import static org.mariotaku.twidere.util.Utils.getUserTypeIconRes;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewGroup.MarginLayoutParams;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.view.ProfileImageView;
|
||||
import org.mariotaku.twidere.view.ShortTimeView;
|
||||
|
||||
public class StatusListViewHolder extends CardViewHolder {
|
||||
|
||||
public final ProfileImageView my_profile_image, profile_image;
|
||||
public final ImageView image_preview;
|
||||
public final ViewGroup image_preview_container;
|
||||
public final ProgressBar image_preview_progress;
|
||||
public final TextView name, screen_name, reply_retweet_status;
|
||||
public final ShortTimeView time;
|
||||
public final TextView text;
|
||||
public final TextView image_preview_count;
|
||||
|
||||
private final float density;
|
||||
private final boolean is_rtl;
|
||||
public boolean show_as_gap;
|
||||
public int position;
|
||||
private boolean account_color_enabled;
|
||||
private float text_size;
|
||||
private boolean nickname_only, name_first;
|
||||
private boolean display_profile_image;
|
||||
private int card_highlight_option;
|
||||
|
||||
public StatusListViewHolder(final View view) {
|
||||
super(view);
|
||||
final Context context = getContext();
|
||||
profile_image = (ProfileImageView) findViewById(R.id.profile_image);
|
||||
my_profile_image = (ProfileImageView) findViewById(R.id.my_profile_image);
|
||||
image_preview = (ImageView) findViewById(R.id.image_preview);
|
||||
image_preview_progress = (ProgressBar) findViewById(R.id.image_preview_progress);
|
||||
image_preview_container = (ViewGroup) findViewById(R.id.image_preview_container);
|
||||
name = (TextView) findViewById(R.id.name);
|
||||
screen_name = (TextView) findViewById(R.id.screen_name);
|
||||
text = (TextView) findViewById(R.id.text);
|
||||
time = (ShortTimeView) findViewById(R.id.time);
|
||||
reply_retweet_status = (TextView) findViewById(R.id.reply_retweet_status);
|
||||
image_preview_count = (TextView) findViewById(R.id.image_preview_count);
|
||||
show_as_gap = content.isGap();
|
||||
is_rtl = Utils.isRTL(context);
|
||||
density = context.getResources().getDisplayMetrics().density;
|
||||
}
|
||||
|
||||
public void setAccountColor(final int color) {
|
||||
content.drawEnd(account_color_enabled && !show_as_gap ? color : Color.TRANSPARENT);
|
||||
}
|
||||
|
||||
public void setAccountColorEnabled(final boolean enabled) {
|
||||
account_color_enabled = enabled && !show_as_gap;
|
||||
if (!account_color_enabled) {
|
||||
content.drawEnd(Color.TRANSPARENT);
|
||||
}
|
||||
}
|
||||
|
||||
public void setCardHighlightOption(final int option) {
|
||||
card_highlight_option = option;
|
||||
}
|
||||
|
||||
public void setDisplayNameFirst(final boolean name_first) {
|
||||
this.name_first = name_first;
|
||||
}
|
||||
|
||||
public void setDisplayProfileImage(final boolean display) {
|
||||
display_profile_image = display;
|
||||
}
|
||||
|
||||
public void setHighlightColor(final int color) {
|
||||
final boolean line = (card_highlight_option & VALUE_CARD_HIGHLIGHT_OPTION_CODE_LINE) != 0;
|
||||
final boolean bg = (card_highlight_option & VALUE_CARD_HIGHLIGHT_OPTION_CODE_BACKGROUND) != 0;
|
||||
content.drawTop(!show_as_gap && line ? color : Color.TRANSPARENT);
|
||||
content.drawBackground(!show_as_gap && bg && color != 0 ? 0x1A000000 | 0x00FFFFFF & color : Color.TRANSPARENT);
|
||||
}
|
||||
|
||||
public void setIsMyStatus(final boolean my_status) {
|
||||
profile_image.setVisibility(my_status ? View.GONE : View.VISIBLE);
|
||||
my_profile_image.setVisibility(my_status ? View.VISIBLE : View.GONE);
|
||||
final MarginLayoutParams lp = (MarginLayoutParams) time.getLayoutParams();
|
||||
if (is_rtl) {
|
||||
lp.leftMargin = (int) (my_status ? 6 * density : 0);
|
||||
} else {
|
||||
lp.rightMargin = (int) (my_status ? 6 * density : 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void setIsReplyRetweet(final boolean is_reply, final boolean is_retweet) {
|
||||
reply_retweet_status.setVisibility(is_retweet || is_reply ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
public void setNicknameOnly(final boolean nickname_only) {
|
||||
this.nickname_only = nickname_only;
|
||||
}
|
||||
|
||||
public void setReplyTo(final long user_id, final String name, final String screen_name) {
|
||||
final String display_name = getDisplayName(getContext(), user_id, name, screen_name, name_first, nickname_only,
|
||||
false);
|
||||
reply_retweet_status.setText(getString(R.string.in_reply_to, display_name));
|
||||
reply_retweet_status.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_indicator_conversation, 0, 0, 0);
|
||||
}
|
||||
|
||||
public void setRetweetedBy(final long count, final long user_id, final String name, final String screen_name) {
|
||||
final String display_name = getDisplayName(getContext(), user_id, name, screen_name, name_first, nickname_only,
|
||||
false);
|
||||
reply_retweet_status.setText(count > 1 ? getString(R.string.retweeted_by_with_count, display_name, count - 1)
|
||||
: getString(R.string.retweeted_by, display_name));
|
||||
reply_retweet_status.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_indicator_retweet, 0, 0, 0);
|
||||
}
|
||||
|
||||
public void setShowAsGap(final boolean show_gap) {
|
||||
show_as_gap = show_gap;
|
||||
if (content != null) {
|
||||
content.setIsGap(show_gap);
|
||||
}
|
||||
// if (item_menu != null) {
|
||||
// item_menu.setVisibility(show_gap ? View.GONE : View.VISIBLE);
|
||||
// }
|
||||
}
|
||||
|
||||
public void setStatusType(final boolean is_favorite, final boolean has_location, final boolean has_media,
|
||||
final boolean is_possibly_sensitive) {
|
||||
final int res = getStatusTypeIconRes(is_favorite, has_location, has_media, is_possibly_sensitive);
|
||||
time.setCompoundDrawablesWithIntrinsicBounds(0, 0, res, 0);
|
||||
}
|
||||
|
||||
public boolean setTextSize(final float text_size) {
|
||||
if (this.text_size == text_size) return false;
|
||||
this.text_size = text_size;
|
||||
text.setTextSize(text_size);
|
||||
name.setTextSize(text_size);
|
||||
screen_name.setTextSize(text_size * 0.75f);
|
||||
time.setTextSize(text_size * 0.65f);
|
||||
reply_retweet_status.setTextSize(text_size * 0.65f);
|
||||
image_preview_count.setTextSize(text_size * 1.25f);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setUserColor(final int... colors) {
|
||||
content.drawStart(show_as_gap ? null : colors);
|
||||
}
|
||||
|
||||
public void setUserType(final boolean isVerified, final boolean isProtected) {
|
||||
// if (display_profile_image) {
|
||||
// profile_image.setUserType(isVerified, isProtected);
|
||||
// my_profile_image.setUserType(isVerified, isProtected);
|
||||
// name.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
|
||||
// } else {
|
||||
// profile_image.setUserType(false, false);
|
||||
// my_profile_image.setUserType(false, false);
|
||||
name.setCompoundDrawablesWithIntrinsicBounds(0, 0, getUserTypeIconRes(isVerified, isProtected), 0);
|
||||
// }
|
||||
}
|
||||
}
|
@ -1,187 +1,187 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.view.holder;
|
||||
|
||||
import static org.mariotaku.twidere.util.Utils.getDisplayName;
|
||||
import static org.mariotaku.twidere.util.Utils.getStatusTypeIconRes;
|
||||
import static org.mariotaku.twidere.util.Utils.getUserTypeIconRes;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewGroup.MarginLayoutParams;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.iface.IStatusesAdapter;
|
||||
import org.mariotaku.twidere.constant.IntentConstants;
|
||||
import org.mariotaku.twidere.fragment.support.StatusMenuDialogFragment;
|
||||
import org.mariotaku.twidere.model.ParcelableMedia;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.view.ProfileImageView;
|
||||
import org.mariotaku.twidere.view.CircularImageView;
|
||||
import org.mariotaku.twidere.view.ShortTimeView;
|
||||
|
||||
public class StatusViewHolder extends CardViewHolder {
|
||||
import java.util.Locale;
|
||||
|
||||
public final ProfileImageView my_profile_image, profile_image;
|
||||
public final ImageView image_preview;
|
||||
public final ViewGroup image_preview_container;
|
||||
public final ProgressBar image_preview_progress;
|
||||
public final TextView name, screen_name, reply_retweet_status;
|
||||
public final ShortTimeView time;
|
||||
public final TextView text;
|
||||
public final TextView image_preview_count;
|
||||
/**
|
||||
* Created by mariotaku on 14/11/19.
|
||||
*/
|
||||
public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClickListener {
|
||||
|
||||
private final float density;
|
||||
private final boolean is_rtl;
|
||||
public boolean show_as_gap;
|
||||
public int position;
|
||||
private boolean account_color_enabled;
|
||||
private float text_size;
|
||||
private boolean nickname_only, name_first;
|
||||
private boolean display_profile_image;
|
||||
private int card_highlight_option;
|
||||
private final IStatusesAdapter adapter;
|
||||
|
||||
public StatusViewHolder(final View view) {
|
||||
super(view);
|
||||
final Context context = getContext();
|
||||
profile_image = (ProfileImageView) findViewById(R.id.profile_image);
|
||||
my_profile_image = (ProfileImageView) findViewById(R.id.my_profile_image);
|
||||
image_preview = (ImageView) findViewById(R.id.image_preview);
|
||||
image_preview_progress = (ProgressBar) findViewById(R.id.image_preview_progress);
|
||||
image_preview_container = (ViewGroup) findViewById(R.id.image_preview_container);
|
||||
name = (TextView) findViewById(R.id.name);
|
||||
screen_name = (TextView) findViewById(R.id.screen_name);
|
||||
text = (TextView) findViewById(R.id.text);
|
||||
time = (ShortTimeView) findViewById(R.id.time);
|
||||
reply_retweet_status = (TextView) findViewById(R.id.reply_retweet_status);
|
||||
image_preview_count = (TextView) findViewById(R.id.image_preview_count);
|
||||
show_as_gap = content.isGap();
|
||||
is_rtl = Utils.isRTL(context);
|
||||
density = context.getResources().getDisplayMetrics().density;
|
||||
}
|
||||
private final ImageView retweetProfileImageView;
|
||||
private final CircularImageView profileImageView;
|
||||
private final ImageView profileTypeView;
|
||||
private final ImageView mediaPreviewView;
|
||||
private final TextView textView;
|
||||
private final TextView nameView, screenNameView;
|
||||
private final TextView replyRetweetView;
|
||||
private final ShortTimeView timeView;
|
||||
private final View mediaPreviewContainer;
|
||||
private final TextView replyCountView, retweetCountView, favoriteCountView;
|
||||
|
||||
public void setAccountColor(final int color) {
|
||||
content.drawEnd(account_color_enabled && !show_as_gap ? color : Color.TRANSPARENT);
|
||||
}
|
||||
public StatusViewHolder(IStatusesAdapter adapter, View itemView) {
|
||||
super(itemView);
|
||||
this.adapter = adapter;
|
||||
itemView.findViewById(R.id.item_content).setOnClickListener(this);
|
||||
itemView.findViewById(R.id.menu).setOnClickListener(this);
|
||||
profileImageView = (CircularImageView) itemView.findViewById(R.id.profile_image);
|
||||
profileTypeView = (ImageView) itemView.findViewById(R.id.profile_type);
|
||||
textView = (TextView) itemView.findViewById(R.id.text);
|
||||
nameView = (TextView) itemView.findViewById(R.id.name);
|
||||
screenNameView = (TextView) itemView.findViewById(R.id.screen_name);
|
||||
retweetProfileImageView = (ImageView) itemView.findViewById(R.id.retweet_profile_image);
|
||||
replyRetweetView = (TextView) itemView.findViewById(R.id.reply_retweet_status);
|
||||
timeView = (ShortTimeView) itemView.findViewById(R.id.time);
|
||||
|
||||
public void setAccountColorEnabled(final boolean enabled) {
|
||||
account_color_enabled = enabled && !show_as_gap;
|
||||
if (!account_color_enabled) {
|
||||
content.drawEnd(Color.TRANSPARENT);
|
||||
}
|
||||
}
|
||||
mediaPreviewContainer = itemView.findViewById(R.id.media_preview_container);
|
||||
mediaPreviewView = (ImageView) itemView.findViewById(R.id.media_preview);
|
||||
|
||||
public void setCardHighlightOption(final int option) {
|
||||
card_highlight_option = option;
|
||||
}
|
||||
replyCountView = (TextView) itemView.findViewById(R.id.reply_count);
|
||||
retweetCountView = (TextView) itemView.findViewById(R.id.retweet_count);
|
||||
favoriteCountView = (TextView) itemView.findViewById(R.id.favorite_count);
|
||||
//TODO
|
||||
// profileImageView.setSelectorColor(ThemeUtils.getUserHighlightColor(itemView.getContext()));
|
||||
|
||||
public void setDisplayNameFirst(final boolean name_first) {
|
||||
this.name_first = name_first;
|
||||
}
|
||||
itemView.setOnClickListener(this);
|
||||
profileImageView.setOnClickListener(this);
|
||||
mediaPreviewContainer.setOnClickListener(this);
|
||||
retweetCountView.setOnClickListener(this);
|
||||
retweetCountView.setOnClickListener(this);
|
||||
favoriteCountView.setOnClickListener(this);
|
||||
}
|
||||
|
||||
public void setDisplayProfileImage(final boolean display) {
|
||||
display_profile_image = display;
|
||||
}
|
||||
public void displayStatus(ParcelableStatus status) {
|
||||
final ImageLoaderWrapper loader = adapter.getImageLoader();
|
||||
final Context context = adapter.getContext();
|
||||
final ParcelableMedia[] media = status.media;
|
||||
|
||||
public void setHighlightColor(final int color) {
|
||||
final boolean line = (card_highlight_option & VALUE_CARD_HIGHLIGHT_OPTION_CODE_LINE) != 0;
|
||||
final boolean bg = (card_highlight_option & VALUE_CARD_HIGHLIGHT_OPTION_CODE_BACKGROUND) != 0;
|
||||
content.drawTop(!show_as_gap && line ? color : Color.TRANSPARENT);
|
||||
content.drawBackground(!show_as_gap && bg && color != 0 ? 0x1A000000 | 0x00FFFFFF & color : Color.TRANSPARENT);
|
||||
}
|
||||
if (status.retweet_id > 0) {
|
||||
replyRetweetView.setText(context.getString(R.string.retweeted_by_name, status.retweeted_by_name));
|
||||
replyRetweetView.setVisibility(View.VISIBLE);
|
||||
replyRetweetView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
|
||||
retweetProfileImageView.setVisibility(View.VISIBLE);
|
||||
loader.displayProfileImage(retweetProfileImageView, status.retweeted_by_profile_image);
|
||||
} else if (status.in_reply_to_user_id > 0) {
|
||||
replyRetweetView.setText(context.getString(R.string.in_reply_to_name, status.in_reply_to_name));
|
||||
replyRetweetView.setVisibility(View.VISIBLE);
|
||||
replyRetweetView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_action_reply, 0, 0, 0);
|
||||
retweetProfileImageView.setVisibility(View.GONE);
|
||||
loader.cancelDisplayTask(retweetProfileImageView);
|
||||
} else {
|
||||
replyRetweetView.setText(null);
|
||||
replyRetweetView.setVisibility(View.GONE);
|
||||
replyRetweetView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
|
||||
retweetProfileImageView.setVisibility(View.GONE);
|
||||
loader.cancelDisplayTask(retweetProfileImageView);
|
||||
}
|
||||
|
||||
public void setIsMyStatus(final boolean my_status) {
|
||||
profile_image.setVisibility(my_status ? View.GONE : View.VISIBLE);
|
||||
my_profile_image.setVisibility(my_status ? View.VISIBLE : View.GONE);
|
||||
final MarginLayoutParams lp = (MarginLayoutParams) time.getLayoutParams();
|
||||
if (is_rtl) {
|
||||
lp.leftMargin = (int) (my_status ? 6 * density : 0);
|
||||
} else {
|
||||
lp.rightMargin = (int) (my_status ? 6 * density : 0);
|
||||
}
|
||||
}
|
||||
if (status.user_is_protected) {
|
||||
profileTypeView.setImageResource(R.drawable.ic_user_type_protected);
|
||||
} else if (status.user_is_verified) {
|
||||
profileTypeView.setImageResource(R.drawable.ic_user_type_verified);
|
||||
} else {
|
||||
profileTypeView.setImageDrawable(null);
|
||||
}
|
||||
|
||||
public void setIsReplyRetweet(final boolean is_reply, final boolean is_retweet) {
|
||||
reply_retweet_status.setVisibility(is_retweet || is_reply ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
nameView.setText(status.user_name);
|
||||
screenNameView.setText("@" + status.user_screen_name);
|
||||
timeView.setTime(status.timestamp);
|
||||
|
||||
public void setNicknameOnly(final boolean nickname_only) {
|
||||
this.nickname_only = nickname_only;
|
||||
}
|
||||
// final int userColor = UserColorNicknameUtils.getUserColor(context, status.user_id);
|
||||
// profileImageView.setBorderColor(userColor);
|
||||
|
||||
public void setReplyTo(final long user_id, final String name, final String screen_name) {
|
||||
final String display_name = getDisplayName(getContext(), user_id, name, screen_name, name_first, nickname_only,
|
||||
false);
|
||||
reply_retweet_status.setText(getString(R.string.in_reply_to, display_name));
|
||||
reply_retweet_status.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_indicator_conversation, 0, 0, 0);
|
||||
}
|
||||
loader.displayProfileImage(profileImageView, status.user_profile_image_url);
|
||||
|
||||
public void setRetweetedBy(final long count, final long user_id, final String name, final String screen_name) {
|
||||
final String display_name = getDisplayName(getContext(), user_id, name, screen_name, name_first, nickname_only,
|
||||
false);
|
||||
reply_retweet_status.setText(count > 1 ? getString(R.string.retweeted_by_with_count, display_name, count - 1)
|
||||
: getString(R.string.retweeted_by, display_name));
|
||||
reply_retweet_status.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_indicator_retweet, 0, 0, 0);
|
||||
}
|
||||
if (media != null && media.length > 0) {
|
||||
final ParcelableMedia firstMedia = media[0];
|
||||
if (status.text_plain.codePointCount(0, status.text_plain.length()) == firstMedia.end) {
|
||||
textView.setText(status.text_unescaped.substring(0, firstMedia.start));
|
||||
} else {
|
||||
textView.setText(status.text_unescaped);
|
||||
}
|
||||
loader.displayPreviewImageWithCredentials(mediaPreviewView, firstMedia.media_url,
|
||||
status.account_id, adapter.getImageLoadingHandler());
|
||||
mediaPreviewContainer.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
loader.cancelDisplayTask(mediaPreviewView);
|
||||
textView.setText(status.text_unescaped);
|
||||
mediaPreviewContainer.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
public void setShowAsGap(final boolean show_gap) {
|
||||
show_as_gap = show_gap;
|
||||
if (content != null) {
|
||||
content.setIsGap(show_gap);
|
||||
}
|
||||
// if (item_menu != null) {
|
||||
// item_menu.setVisibility(show_gap ? View.GONE : View.VISIBLE);
|
||||
// }
|
||||
}
|
||||
if (status.reply_count > 0) {
|
||||
replyCountView.setText(Utils.getLocalizedNumber(Locale.getDefault(), status.reply_count));
|
||||
} else {
|
||||
replyCountView.setText(null);
|
||||
}
|
||||
if (status.retweet_count > 0) {
|
||||
retweetCountView.setText(Utils.getLocalizedNumber(Locale.getDefault(), status.retweet_count));
|
||||
} else {
|
||||
retweetCountView.setText(null);
|
||||
}
|
||||
if (status.favorite_count > 0) {
|
||||
favoriteCountView.setText(Utils.getLocalizedNumber(Locale.getDefault(), status.favorite_count));
|
||||
} else {
|
||||
favoriteCountView.setText(null);
|
||||
}
|
||||
|
||||
public void setStatusType(final boolean is_favorite, final boolean has_location, final boolean has_media,
|
||||
final boolean is_possibly_sensitive) {
|
||||
final int res = getStatusTypeIconRes(is_favorite, has_location, has_media, is_possibly_sensitive);
|
||||
time.setCompoundDrawablesWithIntrinsicBounds(0, 0, res, 0);
|
||||
}
|
||||
retweetCountView.setEnabled(!status.user_is_protected);
|
||||
|
||||
public boolean setTextSize(final float text_size) {
|
||||
if (this.text_size == text_size) return false;
|
||||
this.text_size = text_size;
|
||||
text.setTextSize(text_size);
|
||||
name.setTextSize(text_size);
|
||||
screen_name.setTextSize(text_size * 0.75f);
|
||||
time.setTextSize(text_size * 0.65f);
|
||||
reply_retweet_status.setTextSize(text_size * 0.65f);
|
||||
image_preview_count.setTextSize(text_size * 1.25f);
|
||||
return true;
|
||||
}
|
||||
retweetCountView.setActivated(status.is_retweet);
|
||||
favoriteCountView.setActivated(status.is_favorite);
|
||||
}
|
||||
|
||||
public void setUserColor(final int... colors) {
|
||||
content.drawStart(show_as_gap ? null : colors);
|
||||
}
|
||||
|
||||
public void setUserType(final boolean isVerified, final boolean isProtected) {
|
||||
// if (display_profile_image) {
|
||||
// profile_image.setUserType(isVerified, isProtected);
|
||||
// my_profile_image.setUserType(isVerified, isProtected);
|
||||
// name.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
|
||||
// } else {
|
||||
// profile_image.setUserType(false, false);
|
||||
// my_profile_image.setUserType(false, false);
|
||||
name.setCompoundDrawablesWithIntrinsicBounds(0, 0, getUserTypeIconRes(isVerified, isProtected), 0);
|
||||
// }
|
||||
}
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
final Context context = itemView.getContext();
|
||||
final ParcelableStatus status = adapter.getStatus(getPosition());
|
||||
switch (v.getId()) {
|
||||
case R.id.item_content: {
|
||||
Utils.openStatus(context, status);
|
||||
break;
|
||||
}
|
||||
case R.id.menu: {
|
||||
if (context instanceof FragmentActivity) {
|
||||
final Bundle args = new Bundle();
|
||||
args.putParcelable(IntentConstants.EXTRA_STATUS, status);
|
||||
final StatusMenuDialogFragment f = new StatusMenuDialogFragment();
|
||||
f.setArguments(args);
|
||||
f.show(((FragmentActivity) context).getSupportFragmentManager(), "status_menu");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R.id.profile_image: {
|
||||
Utils.openUserProfile(context, status.account_id, status.user_id, status.user_screen_name);
|
||||
break;
|
||||
}
|
||||
case R.id.reply_count: {
|
||||
final Intent intent = new Intent(IntentConstants.INTENT_ACTION_REPLY);
|
||||
intent.setPackage(context.getPackageName());
|
||||
intent.putExtra(IntentConstants.EXTRA_STATUS, status);
|
||||
context.startActivity(intent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
24
twidere/src/main/res/drawable/bg_oval_black.xml
Normal file
24
twidere/src/main/res/drawable/bg_oval_black.xml
Normal file
@ -0,0 +1,24 @@
|
||||
<?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/>.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
<solid android:color="@android:color/black"/>
|
||||
</shape>
|
5
twidere/src/main/res/drawable/bg_oval_white.xml
Normal file
5
twidere/src/main/res/drawable/bg_oval_white.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
<solid android:color="@android:color/white"/>
|
||||
</shape>
|
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<gradient
|
||||
android:angle="270"
|
||||
android:endColor="#00000000"
|
||||
android:startColor="#A0000000"/>
|
||||
|
||||
</shape>
|
@ -1,15 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<merge xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
>
|
||||
|
||||
<com.pkmmte.view.CircularImageView
|
||||
<org.mariotaku.twidere.view.CircularImageView
|
||||
android:id="@+id/background"
|
||||
android:layout_width="@dimen/float_action_button_size"
|
||||
android:layout_height="@dimen/float_action_button_size"
|
||||
android:layout_gravity="center"
|
||||
app:border="false"
|
||||
app:selector="true"
|
||||
app:shadow="true"/>
|
||||
android:layout_gravity="center"/>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@android:id/progress"
|
||||
|
@ -41,7 +41,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="@dimen/element_spacing_small">
|
||||
|
||||
<com.pkmmte.view.CircularImageView
|
||||
<org.mariotaku.twidere.view.CircularImageView
|
||||
android:id="@+id/media_profile_image"
|
||||
android:layout_width="@dimen/element_size_small"
|
||||
android:layout_height="@dimen/element_size_small"/>
|
||||
|
@ -8,55 +8,107 @@
|
||||
android:layout_marginLeft="@dimen/element_spacing_normal"
|
||||
android:layout_marginRight="@dimen/element_spacing_normal"
|
||||
android:layout_marginTop="@dimen/element_spacing_small"
|
||||
app:cardBackgroundColor="?cardItemBackgroundColor"
|
||||
app:cardCornerRadius="2dp"
|
||||
app:cardElevation="2dp">
|
||||
|
||||
<LinearLayout
|
||||
<RelativeLayout
|
||||
android:id="@+id/item_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
<org.mariotaku.twidere.view.CircularImageView
|
||||
android:id="@+id/retweet_profile_image"
|
||||
android:layout_width="@dimen/element_size_small"
|
||||
android:layout_height="@dimen/element_size_small"
|
||||
android:layout_marginBottom="@dimen/element_spacing_small"
|
||||
android:layout_marginLeft="@dimen/element_spacing_normal"
|
||||
android:layout_marginTop="@dimen/element_spacing_small"
|
||||
android:scaleType="centerCrop"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/reply_retweet_status"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/element_spacing_minus_small"
|
||||
android:layout_marginLeft="@dimen/element_spacing_normal"
|
||||
android:layout_marginRight="@dimen/element_spacing_normal"
|
||||
android:layout_marginTop="@dimen/element_spacing_small"
|
||||
android:layout_toRightOf="@id/retweet_profile_image"
|
||||
android:drawablePadding="@dimen/element_spacing_small"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingBottom="@dimen/element_spacing_normal"
|
||||
android:paddingLeft="@dimen/element_spacing_normal"
|
||||
android:paddingTop="@dimen/element_spacing_normal">
|
||||
android:minHeight="@dimen/element_size_small"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textSize="10sp"/>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/profile_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignLeft="@id/retweet_profile_image"
|
||||
android:layout_below="@id/reply_retweet_status"
|
||||
android:layout_marginTop="@dimen/element_spacing_normal"
|
||||
android:paddingLeft="@dimen/element_spacing_normal">
|
||||
|
||||
<com.pkmmte.view.CircularImageView
|
||||
<org.mariotaku.twidere.view.CircularImageView
|
||||
android:id="@+id/profile_image"
|
||||
android:layout_width="@dimen/icon_size_status_profile_image"
|
||||
android:layout_height="@dimen/icon_size_status_profile_image"
|
||||
android:layout_margin="@dimen/element_spacing_small"
|
||||
android:layout_weight="0"
|
||||
android:layout_centerVertical="true"
|
||||
android:contentDescription="@string/profile_image"
|
||||
android:scaleType="centerCrop"
|
||||
app:border="false"
|
||||
app:selector="true"
|
||||
app:selector_stroke_color="@android:color/transparent"
|
||||
app:selector_stroke_width="0dp"/>
|
||||
android:scaleType="centerCrop"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/profile_type"
|
||||
android:layout_width="@dimen/icon_size_profile_type"
|
||||
android:layout_height="@dimen/icon_size_profile_type"
|
||||
android:layout_alignBottom="@+id/profile_image"
|
||||
android:layout_alignRight="@+id/profile_image"
|
||||
android:layout_marginBottom="@dimen/element_spacing_minus_small"
|
||||
android:layout_marginRight="@dimen/element_spacing_minus_normal"
|
||||
android:scaleType="centerInside"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginLeft="@dimen/element_spacing_normal"
|
||||
android:layout_toLeftOf="@+id/menu"
|
||||
android:layout_toRightOf="@+id/profile_image"
|
||||
android:orientation="vertical">
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/name"
|
||||
android:layout_width="wrap_content"
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="@dimen/element_spacing_xsmall"
|
||||
android:paddingTop="@dimen/element_spacing_small"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textStyle="bold"/>
|
||||
android:layout_marginBottom="@dimen/element_spacing_xsmall"
|
||||
android:layout_marginTop="@dimen/element_spacing_small"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textStyle="bold"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/screen_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/element_spacing_small"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="10sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<org.mariotaku.twidere.view.ShortTimeView
|
||||
android:id="@+id/time"
|
||||
@ -64,24 +116,30 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="@dimen/element_spacing_small"
|
||||
android:paddingTop="@dimen/element_spacing_xsmall"
|
||||
android:textAppearance="?android:textAppearanceSmall"/>
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textSize="10sp"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<org.mariotaku.twidere.view.ActionIconButton
|
||||
android:id="@+id/menu"
|
||||
style="?cardActionButtonStyle"
|
||||
android:layout_width="@dimen/element_size_normal"
|
||||
android:layout_height="@dimen/element_size_normal"
|
||||
android:layout_weight="0"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:src="@drawable/ic_action_more_vertical"/>
|
||||
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
<org.mariotaku.twidere.view.ImagePreviewContainer
|
||||
android:id="@+id/media_preview_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/element_spacing_small"
|
||||
android:layout_alignLeft="@+id/profile_container"
|
||||
android:layout_below="@id/profile_container"
|
||||
android:layout_marginTop="@dimen/element_spacing_normal"
|
||||
android:foreground="?android:selectableItemBackground">
|
||||
|
||||
<ImageView
|
||||
@ -105,75 +163,70 @@
|
||||
android:id="@+id/text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/element_spacing_normal"
|
||||
android:layout_marginRight="@dimen/element_spacing_normal"
|
||||
android:layout_marginTop="@dimen/element_spacing_small"
|
||||
android:layout_alignLeft="@+id/profile_container"
|
||||
android:layout_below="@id/media_preview_container"
|
||||
android:layout_marginTop="@dimen/element_spacing_normal"
|
||||
android:paddingLeft="@dimen/element_spacing_normal"
|
||||
android:paddingRight="@dimen/element_spacing_normal"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:attr/textColorPrimary"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
<HorizontalScrollView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignLeft="@+id/profile_container"
|
||||
android:layout_below="@+id/text"
|
||||
android:layout_marginTop="@dimen/element_spacing_small"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
android:overScrollMode="never"
|
||||
android:scrollbars="none">
|
||||
|
||||
<org.mariotaku.twidere.view.IconActionButton
|
||||
android:id="@+id/reply_indicator"
|
||||
style="?cardActionButtonStyle"
|
||||
android:layout_width="@dimen/button_size_content_card"
|
||||
android:layout_height="@dimen/button_size_content_card"
|
||||
android:layout_weight="0"
|
||||
android:padding="@dimen/element_spacing_small"
|
||||
android:src="@drawable/ic_action_reply"
|
||||
app:activatedColor="@android:color/holo_blue_light"
|
||||
app:color="?android:textColorSecondary"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/reply_count"
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:minWidth="@dimen/element_spacing_mlarge"/>
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<org.mariotaku.twidere.view.IconActionButton
|
||||
android:id="@+id/retweet_indicator"
|
||||
style="?cardActionButtonStyle"
|
||||
android:layout_width="@dimen/button_size_content_card"
|
||||
android:layout_height="@dimen/button_size_content_card"
|
||||
android:layout_weight="0"
|
||||
android:padding="@dimen/element_spacing_small"
|
||||
android:src="@drawable/ic_action_retweet"
|
||||
app:activatedColor="@android:color/holo_green_light"
|
||||
app:color="?android:textColorSecondary"/>
|
||||
<org.mariotaku.twidere.view.CardActionTextView
|
||||
android:id="@+id/reply_count"
|
||||
style="?cardActionButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/button_size_content_card"
|
||||
android:layout_weight="0"
|
||||
android:drawableLeft="@drawable/ic_action_reply"
|
||||
android:gravity="center"
|
||||
android:paddingLeft="@dimen/element_spacing_normal"
|
||||
android:paddingRight="@dimen/element_spacing_normal"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
app:activatedColor="@android:color/holo_blue_light"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/retweet_count"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:minWidth="@dimen/element_spacing_mlarge"/>
|
||||
<org.mariotaku.twidere.view.CardActionTextView
|
||||
android:id="@+id/retweet_count"
|
||||
style="?cardActionButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/button_size_content_card"
|
||||
android:layout_weight="0"
|
||||
android:drawableLeft="@drawable/ic_action_retweet"
|
||||
android:gravity="center"
|
||||
android:paddingLeft="@dimen/element_spacing_normal"
|
||||
android:paddingRight="@dimen/element_spacing_normal"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
app:activatedColor="@android:color/holo_green_light"/>
|
||||
|
||||
<org.mariotaku.twidere.view.IconActionButton
|
||||
android:id="@+id/favorite_indicator"
|
||||
style="?cardActionButtonStyle"
|
||||
android:layout_width="@dimen/button_size_content_card"
|
||||
android:layout_height="@dimen/button_size_content_card"
|
||||
android:layout_weight="0"
|
||||
android:padding="@dimen/element_spacing_small"
|
||||
android:src="@drawable/ic_action_star"
|
||||
app:activatedColor="@android:color/holo_orange_light"
|
||||
app:color="?android:textColorSecondary"/>
|
||||
<org.mariotaku.twidere.view.CardActionTextView
|
||||
android:id="@+id/favorite_count"
|
||||
style="?cardActionButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/button_size_content_card"
|
||||
android:layout_weight="0"
|
||||
android:drawableLeft="@drawable/ic_action_star"
|
||||
android:gravity="center"
|
||||
android:paddingLeft="@dimen/element_spacing_normal"
|
||||
android:paddingRight="@dimen/element_spacing_normal"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
app:activatedColor="@android:color/holo_orange_light"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/favorite_count"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:minWidth="@dimen/element_spacing_mlarge"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</HorizontalScrollView>
|
||||
</RelativeLayout>
|
||||
|
||||
</android.support.v7.widget.CardView>
|
@ -2,7 +2,6 @@
|
||||
<RelativeLayout
|
||||
android:id="@+id/item_content"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:selectableItemBackground"
|
||||
@ -11,16 +10,47 @@
|
||||
android:paddingRight="@dimen/element_spacing_normal"
|
||||
android:paddingTop="@dimen/element_spacing_normal">
|
||||
|
||||
<com.pkmmte.view.CircularImageView
|
||||
<org.mariotaku.twidere.view.CircularImageView
|
||||
android:scaleType="centerCrop"
|
||||
android:id="@+id/retweet_profile_image"
|
||||
android:layout_width="@dimen/element_size_small"
|
||||
android:layout_height="@dimen/element_size_small"
|
||||
android:layout_marginLeft="@dimen/element_spacing_normal"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/reply_retweet_status"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/element_spacing_small"
|
||||
android:layout_marginLeft="@dimen/element_spacing_normal"
|
||||
android:layout_marginRight="@dimen/element_spacing_normal"
|
||||
android:layout_toRightOf="@id/retweet_profile_image"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="@dimen/element_size_small"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textSize="10sp"/>
|
||||
|
||||
<org.mariotaku.twidere.view.CircularImageView
|
||||
android:id="@+id/profile_image"
|
||||
android:layout_width="@dimen/icon_size_status_profile_image"
|
||||
android:layout_height="@dimen/icon_size_status_profile_image"
|
||||
android:layout_alignLeft="@id/retweet_profile_image"
|
||||
android:layout_alignWithParentIfMissing="true"
|
||||
android:layout_below="@+id/reply_retweet_status"
|
||||
android:contentDescription="@string/profile_image"
|
||||
android:scaleType="centerCrop"
|
||||
app:border="false"
|
||||
app:selector="true"
|
||||
app:selector_stroke_color="@android:color/transparent"
|
||||
app:selector_stroke_width="0dp"/>
|
||||
android:scaleType="centerCrop"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/profile_type"
|
||||
android:layout_width="@dimen/icon_size_profile_type"
|
||||
android:layout_height="@dimen/icon_size_profile_type"
|
||||
android:layout_alignBottom="@+id/profile_image"
|
||||
android:layout_marginRight="@dimen/element_spacing_minus_normal"
|
||||
android:layout_marginBottom="@dimen/element_spacing_minus_small"
|
||||
android:layout_alignRight="@+id/profile_image"
|
||||
android:scaleType="centerInside"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/status_content"
|
||||
@ -37,28 +67,38 @@
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<FrameLayout
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1">
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="left"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textStyle="bold"/>
|
||||
|
||||
</FrameLayout>
|
||||
<TextView
|
||||
android:id="@+id/screen_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/element_spacing_small"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="10sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<org.mariotaku.twidere.view.ShortTimeView
|
||||
android:id="@+id/time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:textAppearance="?android:textAppearanceSmall"/>
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textSize="10sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<org.mariotaku.twidere.view.ImagePreviewContainer
|
||||
@ -95,79 +135,76 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
<HorizontalScrollView
|
||||
android:id="@+id/actions_scroller"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignLeft="@id/status_content"
|
||||
android:layout_below="@+id/status_content"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginTop="@dimen/element_spacing_small"
|
||||
android:orientation="horizontal">
|
||||
android:overScrollMode="never"
|
||||
android:scrollbars="none">
|
||||
|
||||
<org.mariotaku.twidere.view.IconActionButton
|
||||
android:id="@+id/reply_indicator"
|
||||
style="?cardActionButtonStyle"
|
||||
android:layout_width="@dimen/button_size_content_card"
|
||||
android:layout_height="@dimen/button_size_content_card"
|
||||
android:layout_weight="0"
|
||||
android:padding="@dimen/element_spacing_small"
|
||||
android:src="@drawable/ic_action_reply"
|
||||
app:activatedColor="@android:color/holo_blue_light"
|
||||
app:color="?android:textColorSecondary"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/reply_count"
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:minWidth="@dimen/element_spacing_mlarge"/>
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<org.mariotaku.twidere.view.IconActionButton
|
||||
android:id="@+id/retweet_indicator"
|
||||
style="?cardActionButtonStyle"
|
||||
android:layout_width="@dimen/button_size_content_card"
|
||||
android:layout_height="@dimen/button_size_content_card"
|
||||
android:layout_weight="0"
|
||||
android:padding="@dimen/element_spacing_small"
|
||||
android:src="@drawable/ic_action_retweet"
|
||||
app:activatedColor="@android:color/holo_green_light"
|
||||
app:color="?android:textColorSecondary"/>
|
||||
<TextView
|
||||
android:id="@+id/reply_count"
|
||||
style="?cardActionButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/button_size_content_card"
|
||||
android:layout_weight="0"
|
||||
android:drawableLeft="@drawable/ic_action_reply"
|
||||
android:gravity="center"
|
||||
android:paddingLeft="@dimen/element_spacing_normal"
|
||||
android:paddingRight="@dimen/element_spacing_normal"
|
||||
android:textAppearance="?android:textAppearanceSmall"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/retweet_count"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:minWidth="@dimen/element_spacing_mlarge"/>
|
||||
<TextView
|
||||
android:id="@+id/retweet_count"
|
||||
style="?cardActionButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/button_size_content_card"
|
||||
android:layout_weight="0"
|
||||
android:drawableLeft="@drawable/ic_action_retweet"
|
||||
android:gravity="center"
|
||||
android:paddingLeft="@dimen/element_spacing_normal"
|
||||
android:paddingRight="@dimen/element_spacing_normal"
|
||||
android:textAppearance="?android:textAppearanceSmall"/>
|
||||
|
||||
<org.mariotaku.twidere.view.IconActionButton
|
||||
android:id="@+id/favorite_indicator"
|
||||
style="?cardActionButtonStyle"
|
||||
android:layout_width="@dimen/button_size_content_card"
|
||||
android:layout_height="@dimen/button_size_content_card"
|
||||
android:layout_weight="0"
|
||||
android:padding="@dimen/element_spacing_small"
|
||||
android:src="@drawable/ic_action_star"
|
||||
app:activatedColor="@android:color/holo_orange_light"
|
||||
app:color="?android:textColorSecondary"/>
|
||||
<TextView
|
||||
android:id="@+id/favorite_count"
|
||||
style="?cardActionButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/button_size_content_card"
|
||||
android:layout_weight="0"
|
||||
android:drawableLeft="@drawable/ic_action_star"
|
||||
android:gravity="center"
|
||||
android:paddingLeft="@dimen/element_spacing_normal"
|
||||
android:paddingRight="@dimen/element_spacing_normal"
|
||||
android:textAppearance="?android:textAppearanceSmall"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/favorite_count"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:minWidth="@dimen/element_spacing_mlarge"/>
|
||||
</LinearLayout>
|
||||
|
||||
<Space
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"/>
|
||||
</HorizontalScrollView>
|
||||
|
||||
<Space
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_toRightOf="@+id/actions_scroller"
|
||||
android:layout_toLeftOf="@+id/menu"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<org.mariotaku.twidere.view.ActionIconButton
|
||||
android:id="@+id/menu"
|
||||
style="?cardActionButtonStyle"
|
||||
android:layout_width="@dimen/button_size_content_card"
|
||||
android:layout_height="@dimen/button_size_content_card"
|
||||
android:layout_alignBottom="@+id/actions_scroller"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_weight="0"
|
||||
android:src="@drawable/ic_action_more_horizontal"/>
|
||||
|
||||
<org.mariotaku.twidere.view.ActionIconButton
|
||||
style="?cardActionButtonStyle"
|
||||
android:layout_width="@dimen/button_size_content_card"
|
||||
android:layout_height="@dimen/button_size_content_card"
|
||||
android:layout_weight="0"
|
||||
android:src="@drawable/ic_action_more_horizontal"/>
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
@ -1,20 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout
|
||||
android:id="@+id/fragment_content"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:animateLayoutChanges="true">
|
||||
android:clipToPadding="false"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@android:id/list"
|
||||
<android.support.v4.widget.SwipeRefreshLayout
|
||||
android:id="@+id/swipe_layout"
|
||||
android:clipToPadding="false"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@android:id/progress"
|
||||
style="?android:progressBarStyleLarge"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"/>
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
android:scrollbars="vertical"
|
||||
android:clipToPadding="false"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
</android.support.v4.widget.SwipeRefreshLayout>
|
||||
</FrameLayout>
|
@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
android:id="@+id/header_user_profile"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/header_user_profile"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
@ -19,35 +19,46 @@
|
||||
android:background="@drawable/shadow_top"/>
|
||||
|
||||
<!--<View-->
|
||||
<!--android:id="@+id/profile_layer_bottom"-->
|
||||
<!--android:layout_width="match_parent"-->
|
||||
<!--android:layout_height="match_parent"-->
|
||||
<!--android:layout_alignBottom="@+id/card"-->
|
||||
<!--android:layout_alignTop="@+id/profile_name_container"/>-->
|
||||
<!--android:id="@+id/profile_layer_bottom"-->
|
||||
<!--android:layout_width="match_parent"-->
|
||||
<!--android:layout_height="match_parent"-->
|
||||
<!--android:layout_alignBottom="@+id/card"-->
|
||||
<!--android:layout_alignTop="@+id/profile_name_container"/>-->
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/profile_image_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
<!--<FrameLayout-->
|
||||
<!--android:id="@+id/profile_image_container"-->
|
||||
<!--android:layout_width="wrap_content"-->
|
||||
<!--android:layout_height="wrap_content"-->
|
||||
<!--android:layout_alignBottom="@+id/profile_name_container"-->
|
||||
<!--android:layout_marginLeft="@dimen/element_spacing_normal"-->
|
||||
<!--android:background="?cardItemBackground">-->
|
||||
|
||||
<!--<org.mariotaku.twidere.view.ProfileImageView-->
|
||||
<!--android:id="@+id/profile_image"-->
|
||||
<!--android:layout_width="@dimen/icon_size_user_profile"-->
|
||||
<!--android:layout_height="@dimen/icon_size_user_profile"-->
|
||||
<!--android:contentDescription="@string/profile_image"-->
|
||||
<!--android:scaleType="centerCrop"-->
|
||||
<!--android:src="@drawable/ic_profile_image_default"/>-->
|
||||
<!--</FrameLayout>-->
|
||||
|
||||
<org.mariotaku.twidere.view.CircularImageView
|
||||
android:id="@+id/profile_image"
|
||||
style="?profileImageStyleLarge"
|
||||
android:elevation="0dp"
|
||||
android:layout_width="@dimen/icon_size_user_profile"
|
||||
android:layout_height="@dimen/icon_size_user_profile"
|
||||
android:layout_alignBottom="@+id/profile_name_container"
|
||||
android:layout_marginLeft="@dimen/element_spacing_normal"
|
||||
android:background="?cardItemBackground">
|
||||
|
||||
<org.mariotaku.twidere.view.ProfileImageView
|
||||
android:id="@+id/profile_image"
|
||||
android:layout_width="@dimen/icon_size_user_profile"
|
||||
android:layout_height="@dimen/icon_size_user_profile"
|
||||
android:contentDescription="@string/profile_image"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/ic_profile_image_default"/>
|
||||
</FrameLayout>
|
||||
android:contentDescription="@string/profile_image"
|
||||
android:src="@drawable/ic_profile_image_default"/>
|
||||
|
||||
<org.mariotaku.twidere.view.ColorLabelLinearLayout
|
||||
android:id="@+id/profile_name_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/profile_banner_space"
|
||||
android:layout_toRightOf="@+id/profile_image_container"
|
||||
android:layout_toRightOf="@+id/profile_image"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical"
|
||||
@ -89,212 +100,220 @@
|
||||
</LinearLayout>
|
||||
</org.mariotaku.twidere.view.ColorLabelLinearLayout>
|
||||
|
||||
<org.mariotaku.twidere.view.CardItemLinearLayout
|
||||
<android.support.v7.widget.CardView
|
||||
android:id="@+id/card"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/profile_name_container"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/element_spacing_normal"
|
||||
android:splitMotionEvents="false">
|
||||
android:layout_margin="@dimen/element_spacing_normal"
|
||||
app:cardBackgroundColor="?cardItemBackgroundColor"
|
||||
app:cardCornerRadius="@dimen/corner_radius_card"
|
||||
app:cardElevation="@dimen/elevation_card">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/description_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/element_spacing_small">
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/description"
|
||||
android:textAppearance="?android:textAppearanceMedium"/>
|
||||
|
||||
<org.mariotaku.twidere.view.HandleSpanClickTextView
|
||||
android:id="@+id/description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textColor="?android:textColorSecondary"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/location_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/element_spacing_small">
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:text="@string/location"
|
||||
android:textAppearance="?android:textAppearanceMedium"/>
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:id="@+id/location"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textColor="?android:textColorSecondary"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/url_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/element_spacing_small">
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:text="@string/url"
|
||||
android:textAppearance="?android:textAppearanceMedium"/>
|
||||
|
||||
<org.mariotaku.twidere.view.HandleSpanClickTextView
|
||||
android:id="@+id/url"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:autoLink="web"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textColor="?android:textColorSecondary"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/created_at_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/element_spacing_small">
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:text="@string/created_at"
|
||||
android:textAppearance="?android:textAppearanceMedium"/>
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:id="@+id/created_at"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textColor="?android:textColorSecondary"/>
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0.2dp"
|
||||
android:background="@color/divider_color"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/action_button_size"
|
||||
android:baselineAligned="false"
|
||||
android:divider="@drawable/divider_vertical_small_holo"
|
||||
android:orientation="horizontal"
|
||||
android:showDividers="middle"
|
||||
android:splitMotionEvents="false">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/tweets_container"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:id="@+id/description_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/element_spacing_small">
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:id="@+id/statuses_count"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:textAppearanceMedium"
|
||||
android:textColor="?android:textColorPrimary"/>
|
||||
android:text="@string/description"
|
||||
android:textAppearance="?android:textAppearanceMedium"/>
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:layout_width="wrap_content"
|
||||
<org.mariotaku.twidere.view.HandleSpanClickTextView
|
||||
android:id="@+id/description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:text="@string/statuses"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textColor="?android:textColorSecondary"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/followers_container"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:id="@+id/location_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/element_spacing_small">
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:id="@+id/followers_count"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:textAppearanceMedium"
|
||||
android:textColor="?android:textColorPrimary"/>
|
||||
android:text="@string/location"
|
||||
android:textAppearance="?android:textAppearanceMedium"/>
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:layout_width="wrap_content"
|
||||
android:id="@+id/location"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:text="@string/followers"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textColor="?android:textColorSecondary"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/friends_container"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:id="@+id/url_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/element_spacing_small">
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:id="@+id/friends_count"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:textAppearanceMedium"
|
||||
android:textColor="?android:textColorPrimary"/>
|
||||
android:text="@string/url"
|
||||
android:textAppearance="?android:textAppearanceMedium"/>
|
||||
|
||||
<org.mariotaku.twidere.view.HandleSpanClickTextView
|
||||
android:id="@+id/url"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:autoLink="web"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textColor="?android:textColorSecondary"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/created_at_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/element_spacing_small">
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:text="@string/following"
|
||||
android:text="@string/created_at"
|
||||
android:textAppearance="?android:textAppearanceMedium"/>
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:id="@+id/created_at"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textColor="?android:textColorSecondary"/>
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0.2dp"
|
||||
android:background="@color/divider_color"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/action_button_size"
|
||||
android:baselineAligned="false"
|
||||
android:divider="@drawable/divider_vertical_small_holo"
|
||||
android:orientation="horizontal"
|
||||
android:showDividers="middle"
|
||||
android:splitMotionEvents="false">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/tweets_container"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/element_spacing_small">
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:id="@+id/statuses_count"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:textAppearanceMedium"
|
||||
android:textColor="?android:textColorPrimary"/>
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:text="@string/statuses"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textColor="?android:textColorSecondary"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/followers_container"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/element_spacing_small">
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:id="@+id/followers_count"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:textAppearanceMedium"
|
||||
android:textColor="?android:textColorPrimary"/>
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:text="@string/followers"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textColor="?android:textColorSecondary"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/friends_container"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/element_spacing_small">
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:id="@+id/friends_count"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:textAppearanceMedium"
|
||||
android:textColor="?android:textColorPrimary"/>
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:text="@string/following"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textColor="?android:textColorSecondary"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</org.mariotaku.twidere.view.CardItemLinearLayout>
|
||||
</android.support.v7.widget.CardView>
|
||||
|
||||
</RelativeLayout>
|
@ -5,5 +5,4 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top"
|
||||
android:foreground="@drawable/shadow_user_banner_image"
|
||||
android:scaleType="centerCrop"/>
|
||||
|
@ -1,13 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.pkmmte.view.CircularImageView
|
||||
<org.mariotaku.twidere.view.CircularImageView
|
||||
android:id="@+id/color"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="@dimen/element_size_small"
|
||||
android:layout_height="@dimen/element_size_small"
|
||||
android:layout_gravity="center"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="centerCrop"
|
||||
app:border="true"
|
||||
app:border_color="@android:color/white"
|
||||
app:border_width="1dp"/>
|
||||
android:scaleType="centerCrop"/>
|
||||
|
@ -8,4 +8,26 @@
|
||||
<style name="Widget.Light.CardActionButton" parent="android:Widget.DeviceDefault.ImageButton">
|
||||
<item name="android:background">?android:selectableItemBackgroundBorderless</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.ProfileImage.Large">
|
||||
<item name="android:background">@drawable/bg_oval_white</item>
|
||||
<!--<item name="android:background">@android:color/transparent</item>-->
|
||||
<item name="android:paddingTop">1dp</item>
|
||||
<item name="android:paddingLeft">2dp</item>
|
||||
<item name="android:paddingRight">2dp</item>
|
||||
<item name="android:paddingBottom">3dp</item>
|
||||
<item name="elevation">@dimen/elevation_card</item>
|
||||
<item name="borderWidth">2dp</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Light.ProfileImage.Large">
|
||||
<item name="android:background">@drawable/bg_oval_white</item>
|
||||
<!--<item name="android:background">@android:color/transparent</item>-->
|
||||
<item name="android:paddingTop">1dp</item>
|
||||
<item name="android:paddingLeft">2dp</item>
|
||||
<item name="android:paddingRight">2dp</item>
|
||||
<item name="android:paddingBottom">3dp</item>
|
||||
<item name="elevation">@dimen/elevation_card</item>
|
||||
<item name="borderWidth">2dp</item>
|
||||
</style>
|
||||
</resources>
|
@ -3,6 +3,7 @@
|
||||
|
||||
<declare-styleable name="Twidere">
|
||||
<attr name="cardActionButtonStyle" format="reference"/>
|
||||
<attr name="profileImageStyleLarge" format="reference"/>
|
||||
<attr name="cardItemBackground" format="reference"/>
|
||||
<attr name="cardItemBackgroundColor" format="color"/>
|
||||
<attr name="cardItemMessageIncomingBackground" format="reference"/>
|
||||
@ -72,6 +73,12 @@
|
||||
<attr name="color" format="color"/>
|
||||
<attr name="activatedColor" format="color"/>
|
||||
</declare-styleable>
|
||||
<declare-styleable name="CircularImageView">
|
||||
<attr name="border" format="boolean"/>
|
||||
<attr name="borderWidth" format="dimension"/>
|
||||
<attr name="borderColor" format="color"/>
|
||||
<attr name="elevation" format="dimension"/>
|
||||
</declare-styleable>
|
||||
<attr name="notificationType">
|
||||
<flag name="none" value="0"/>
|
||||
<flag name="ringtone" value="1"/>
|
||||
|
@ -12,6 +12,7 @@
|
||||
<dimen name="element_spacing_large">16dp</dimen>
|
||||
<dimen name="element_spacing_xlarge">24dp</dimen>
|
||||
<dimen name="element_spacing_minus_small">-4dp</dimen>
|
||||
<dimen name="element_spacing_minus_normal">-8dp</dimen>
|
||||
<dimen name="icon_size_list_item">56dp</dimen>
|
||||
<dimen name="icon_size_list_item_small">42dp</dimen>
|
||||
<dimen name="icon_size_card_list_item">48dp</dimen>
|
||||
@ -74,5 +75,10 @@
|
||||
<dimen name="unread_indicator_size">16dp</dimen>
|
||||
<dimen name="account_selector_popup_width">180dp</dimen>
|
||||
<dimen name="icon_size_status_profile_image">48dp</dimen>
|
||||
<dimen name="icon_size_profile_type">24dp</dimen>
|
||||
|
||||
<!-- Elevation values -->
|
||||
<dimen name="elevation_card">2dp</dimen>
|
||||
<dimen name="corner_radius_card">2dp</dimen>
|
||||
|
||||
</resources>
|
@ -87,10 +87,10 @@
|
||||
<string name="look_and_feel">Look and feel</string>
|
||||
<string name="display_profile_image">Display profile image</string>
|
||||
<string name="image_load_summary">Disabling this will increase list scroll speed and reduce data usage.</string>
|
||||
<string name="in_reply_to">In reply to <xliff:g id="user_name">%s</xliff:g></string>
|
||||
<string name="retweeted_by"><xliff:g id="user_name">%s</xliff:g> retweeted this</string>
|
||||
<string name="retweeted_by_with_count"><xliff:g id="user_name">%1$s</xliff:g> and <xliff:g id="retweet_count">%2$d</xliff:g> others retweeted this</string>
|
||||
<string name="retweeted_by_count"><xliff:g id="retweet_count">%d</xliff:g> users retweeted this</string>
|
||||
<string name="in_reply_to_name">In reply to <xliff:g id="user_name">%s</xliff:g></string>
|
||||
<string name="retweeted_by_name">Retweeted by <xliff:g id="user_name">%s</xliff:g></string>
|
||||
<string name="retweeted_by_name_with_count">Retweeted by <xliff:g id="user_name">%1$s</xliff:g> and <xliff:g id="retweet_count">%2$d</xliff:g> others</string>
|
||||
<string name="retweeted_by_count">Retweeted by <xliff:g id="retweet_count">%d</xliff:g> users</string>
|
||||
<string name="users_retweeted_this">Users retweeted this</string>
|
||||
<string name="users_favorited_this">Users favorited this</string>
|
||||
<string name="reply_to">Reply to <xliff:g id="user_name">%s</xliff:g></string>
|
||||
|
@ -151,7 +151,28 @@
|
||||
<item name="android:background">?android:selectableItemBackground</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Light.CardActionButton" parent="android:Widget.DeviceDefault.ImageButton">
|
||||
<style name="Widget.Light.CardActionButton" parent="android:Widget.DeviceDefault.Light.ImageButton">
|
||||
<item name="android:background">?android:selectableItemBackground</item>
|
||||
</style>
|
||||
|
||||
|
||||
<style name="Widget.ProfileImage" parent="android:Widget.DeviceDefault">
|
||||
<item name="android:scaleType">centerCrop</item>
|
||||
<item name="borderWidth">1dp</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Light.ProfileImage" parent="android:Widget.DeviceDefault">
|
||||
<item name="android:scaleType">centerCrop</item>
|
||||
<item name="borderWidth">1dp</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.ProfileImage.Large">
|
||||
<item name="android:background">@drawable/bg_oval_black</item>
|
||||
<item name="borderWidth">2dp</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Light.ProfileImage.Large">
|
||||
<item name="android:background">@drawable/bg_oval_white</item>
|
||||
<item name="borderWidth">2dp</item>
|
||||
</style>
|
||||
</resources>
|
@ -39,6 +39,7 @@
|
||||
|
||||
<!-- Card UI styles -->
|
||||
<item name="cardActionButtonStyle">@style/Widget.CardActionButton</item>
|
||||
<item name="profileImageStyleLarge">@style/Widget.ProfileImage.Large</item>
|
||||
<item name="cardItemBackground">@drawable/bg_card_item_dark</item>
|
||||
<item name="cardItemBackgroundColor">#1a1a1a</item>
|
||||
<item name="cardItemMessageIncomingBackground">
|
||||
@ -83,6 +84,7 @@
|
||||
|
||||
<!-- Card UI styles -->
|
||||
<item name="cardActionButtonStyle">@style/Widget.Light.CardActionButton</item>
|
||||
<item name="profileImageStyleLarge">@style/Widget.Light.ProfileImage.Large</item>
|
||||
<item name="cardItemBackground">@drawable/bg_card_item_light</item>
|
||||
<item name="cardItemBackgroundColor">#f8f8f8</item>
|
||||
<item name="cardItemMessageIncomingBackground">
|
||||
@ -153,6 +155,7 @@
|
||||
|
||||
<!-- Card UI styles -->
|
||||
<item name="cardActionButtonStyle">@style/Widget.CardActionButton</item>
|
||||
<item name="profileImageStyleLarge">@style/Widget.ProfileImage.Large</item>
|
||||
<item name="cardItemBackground">@drawable/bg_card_item_dark</item>
|
||||
<item name="cardItemBackgroundColor">#1a1a1a</item>
|
||||
<item name="cardItemMessageIncomingBackground">
|
||||
@ -182,6 +185,7 @@
|
||||
|
||||
<!-- Card UI styles -->
|
||||
<item name="cardActionButtonStyle">@style/Widget.Light.CardActionButton</item>
|
||||
<item name="profileImageStyleLarge">@style/Widget.Light.ProfileImage.Large</item>
|
||||
<item name="cardItemBackground">@drawable/bg_card_item_light</item>
|
||||
<item name="cardItemBackgroundColor">#f8f8f8</item>
|
||||
<item name="cardItemMessageIncomingBackground">
|
||||
@ -240,6 +244,7 @@
|
||||
|
||||
<!-- Card UI styles -->
|
||||
<item name="cardActionButtonStyle">@style/Widget.CardActionButton</item>
|
||||
<item name="profileImageStyleLarge">@style/Widget.ProfileImage.Large</item>
|
||||
<item name="cardItemBackground">@drawable/bg_card_item_dark</item>
|
||||
<item name="cardItemBackgroundColor">#1a1a1a</item>
|
||||
<item name="cardItemMessageIncomingBackground">
|
||||
@ -338,6 +343,7 @@
|
||||
|
||||
<!-- Card UI styles -->
|
||||
<item name="cardActionButtonStyle">@style/Widget.CardActionButton</item>
|
||||
<item name="profileImageStyleLarge">@style/Widget.ProfileImage.Large</item>
|
||||
<item name="cardItemBackground">@drawable/bg_card_item_dark</item>
|
||||
<item name="cardItemBackgroundColor">#1a1a1a</item>
|
||||
<item name="cardItemMessageIncomingBackground">
|
||||
@ -373,6 +379,7 @@
|
||||
|
||||
<!-- Card UI styles -->
|
||||
<item name="cardActionButtonStyle">@style/Widget.Light.CardActionButton</item>
|
||||
<item name="profileImageStyleLarge">@style/Widget.Light.ProfileImage.Large</item>
|
||||
<item name="cardItemBackground">@drawable/bg_card_item_light</item>
|
||||
<item name="cardItemBackgroundColor">#f8f8f8</item>
|
||||
<item name="cardItemMessageIncomingBackground">
|
||||
@ -408,6 +415,7 @@
|
||||
|
||||
<!-- Card UI styles -->
|
||||
<item name="cardActionButtonStyle">@style/Widget.Light.CardActionButton</item>
|
||||
<item name="profileImageStyleLarge">@style/Widget.Light.ProfileImage.Large</item>
|
||||
<item name="cardItemBackground">@drawable/bg_card_item_light</item>
|
||||
<item name="cardItemBackgroundColor">#f8f8f8</item>
|
||||
<item name="cardItemMessageIncomingBackground">
|
||||
|
Loading…
Reference in New Issue
Block a user