migrated user lists into new recyclerview implementation

improved edit text theme
This commit is contained in:
Mariotaku Lee 2015-04-29 02:35:04 +08:00
parent 7f063531b6
commit a52c8ccd9e
40 changed files with 1214 additions and 1057 deletions

View File

@ -79,7 +79,7 @@ import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface;
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback;
import org.mariotaku.twidere.fragment.support.AccountsDashboardFragment;
import org.mariotaku.twidere.fragment.support.DirectMessagesFragment;
import org.mariotaku.twidere.fragment.support.TrendsSuggectionsFragment;
import org.mariotaku.twidere.fragment.support.TrendsSuggestionsFragment;
import org.mariotaku.twidere.graphic.EmptyDrawable;
import org.mariotaku.twidere.model.ParcelableAccount;
import org.mariotaku.twidere.model.SupportTabSpec;
@ -910,7 +910,7 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen
} else {
if (classEquals(DirectMessagesFragment.class, tab.cls)) {
openMessageConversation(this, -1, -1);
} else if (classEquals(TrendsSuggectionsFragment.class, tab.cls)) {
} else if (classEquals(TrendsSuggestionsFragment.class, tab.cls)) {
openSearchView(null);
} else {
startActivity(new Intent(INTENT_ACTION_COMPOSE));
@ -930,7 +930,7 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen
if (classEquals(DirectMessagesFragment.class, tab.cls)) {
icon = R.drawable.ic_action_add;
title = R.string.new_direct_message;
} else if (classEquals(TrendsSuggectionsFragment.class, tab.cls)) {
} else if (classEquals(TrendsSuggestionsFragment.class, tab.cls)) {
icon = R.drawable.ic_action_search;
title = android.R.string.search_go;
} else {

View File

@ -0,0 +1,213 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.adapter;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.iface.IUserListsAdapter;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.MediaLoaderWrapper;
import org.mariotaku.twidere.util.SharedPreferencesWrapper;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.UserColorNameManager;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.holder.LoadIndicatorViewHolder;
import org.mariotaku.twidere.view.holder.UserListViewHolder;
public abstract class AbsUserListsAdapter<D> extends LoadMoreSupportAdapter<ViewHolder> implements Constants,
IUserListsAdapter<D> {
public static final int ITEM_VIEW_TYPE_USER_LIST = 2;
private final Context mContext;
private final LayoutInflater mInflater;
private final MediaLoaderWrapper mMediaLoader;
private final int mCardBackgroundColor;
private final boolean mCompactCards;
private final int mProfileImageStyle;
private final int mTextSize;
private final AsyncTwitterWrapper mTwitterWrapper;
private final boolean mDisplayProfileImage;
private final UserColorNameManager mUserColorNameManager;
private final boolean mNameFirst;
public AbsUserListsAdapter(final Context context, final boolean compact) {
final TwidereApplication app = TwidereApplication.getInstance(context);
mContext = context;
mCardBackgroundColor = ThemeUtils.getCardBackgroundColor(context, ThemeUtils.getThemeBackgroundOption(context), ThemeUtils.getUserThemeBackgroundAlpha(context));
mInflater = LayoutInflater.from(context);
mMediaLoader = app.getMediaLoaderWrapper();
mUserColorNameManager = app.getUserColorNameManager();
mTwitterWrapper = app.getTwitterWrapper();
final SharedPreferencesWrapper preferences = SharedPreferencesWrapper.getInstance(context,
SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
mTextSize = preferences.getInt(KEY_TEXT_SIZE, context.getResources().getInteger(R.integer.default_text_size));
mProfileImageStyle = Utils.getProfileImageStyle(preferences.getString(KEY_PROFILE_IMAGE_STYLE, null));
mDisplayProfileImage = preferences.getBoolean(KEY_DISPLAY_PROFILE_IMAGE, true);
mNameFirst = preferences.getBoolean(KEY_NAME_FIRST, true);
mCompactCards = compact;
}
@Override
public Context getContext() {
return mContext;
}
@Override
public int getProfileImageStyle() {
return mProfileImageStyle;
}
@Override
public float getTextSize() {
return mTextSize;
}
@NonNull
@Override
public AsyncTwitterWrapper getTwitterWrapper() {
return mTwitterWrapper;
}
@Override
public UserColorNameManager getUserColorNameManager() {
return mUserColorNameManager;
}
@Override
public boolean isProfileImageEnabled() {
return mDisplayProfileImage;
}
@Override
public boolean isNameFirst() {
return mNameFirst;
}
public abstract D getData();
public boolean isUserList(int position) {
return position < getUserListsCount();
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case ITEM_VIEW_TYPE_USER_LIST: {
final View view;
if (mCompactCards) {
view = mInflater.inflate(R.layout.card_item_user_list_compact, parent, false);
final View itemContent = view.findViewById(R.id.item_content);
itemContent.setBackgroundColor(mCardBackgroundColor);
} else {
view = mInflater.inflate(R.layout.card_item_user_list, parent, false);
final CardView cardView = (CardView) view.findViewById(R.id.card);
cardView.setCardBackgroundColor(mCardBackgroundColor);
}
final UserListViewHolder holder = new UserListViewHolder(this, view);
holder.setOnClickListeners();
holder.setupViewOptions();
return holder;
}
case ITEM_VIEW_TYPE_LOAD_INDICATOR: {
final View view = mInflater.inflate(R.layout.card_item_load_indicator, parent, false);
return new LoadIndicatorViewHolder(view);
}
}
throw new IllegalStateException("Unknown view type " + viewType);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
switch (holder.getItemViewType()) {
case ITEM_VIEW_TYPE_USER_LIST: {
bindUserList(((UserListViewHolder) holder), position);
break;
}
}
}
@Override
public int getItemViewType(int position) {
if (position == getUserListsCount()) {
return ITEM_VIEW_TYPE_LOAD_INDICATOR;
}
return ITEM_VIEW_TYPE_USER_LIST;
}
@Override
public void onItemActionClick(ViewHolder holder, int id, int position) {
}
@Override
public void onItemMenuClick(ViewHolder holder, View menuView, int position) {
}
@Override
public void onUserListClick(UserListViewHolder holder, int position) {
if (mUserListAdapterListener == null) return;
mUserListAdapterListener.onUserListClick(holder, position);
}
@Override
public boolean onUserListLongClick(UserListViewHolder holder, int position) {
return mUserListAdapterListener != null && mUserListAdapterListener.onUserListLongClick(holder, position);
}
public void setListener(UserListAdapterListener userListAdapterListener) {
mUserListAdapterListener = userListAdapterListener;
}
@Override
public boolean shouldShowAccountsColor() {
return false;
}
@Override
public MediaLoaderWrapper getMediaLoader() {
return mMediaLoader;
}
protected abstract void bindUserList(UserListViewHolder holder, int position);
private UserListAdapterListener mUserListAdapterListener;
public static interface UserListAdapterListener {
void onUserListClick(UserListViewHolder holder, int position);
boolean onUserListLongClick(UserListViewHolder holder, int position);
}
}

View File

@ -142,7 +142,7 @@ public abstract class AbsUsersAdapter<D> extends LoadMoreSupportAdapter<ViewHold
public void onBindViewHolder(ViewHolder holder, int position) {
switch (holder.getItemViewType()) {
case ITEM_VIEW_TYPE_USER: {
bindStatus(((UserViewHolder) holder), position);
bindUser(((UserViewHolder) holder), position);
break;
}
}
@ -191,7 +191,7 @@ public abstract class AbsUsersAdapter<D> extends LoadMoreSupportAdapter<ViewHold
return mMediaLoader;
}
protected abstract void bindStatus(UserViewHolder holder, int position);
protected abstract void bindUser(UserViewHolder holder, int position);
private UserAdapterListener mUserAdapterListener;

View File

@ -0,0 +1,77 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.adapter;
import android.content.Context;
import org.mariotaku.twidere.model.ParcelableUserList;
import org.mariotaku.twidere.view.holder.UserListViewHolder;
import java.util.List;
public class ParcelableUserListsAdapter extends AbsUserListsAdapter<List<ParcelableUserList>> {
private List<ParcelableUserList> mData;
public ParcelableUserListsAdapter(Context context, boolean compact) {
super(context, compact);
}
@Override
public List<ParcelableUserList> getData() {
return mData;
}
@Override
public void setData(List<ParcelableUserList> data) {
mData = data;
notifyDataSetChanged();
}
@Override
protected void bindUserList(UserListViewHolder holder, int position) {
holder.displayUserList(getUserList(position));
}
@Override
public int getItemCount() {
return getUserListsCount() + (isLoadMoreIndicatorVisible() ? 1 : 0);
}
@Override
public ParcelableUserList getUserList(int position) {
if (position == getUserListsCount()) return null;
return mData.get(position);
}
@Override
public long getUserListId(int position) {
if (position == getUserListsCount()) return -1;
return mData.get(position).id;
}
@Override
public int getUserListsCount() {
if (mData == null) return 0;
return mData.size();
}
}

View File

@ -48,7 +48,7 @@ public class ParcelableUsersAdapter extends AbsUsersAdapter<List<ParcelableUser>
}
@Override
protected void bindStatus(UserViewHolder holder, int position) {
protected void bindUser(UserViewHolder holder, int position) {
holder.displayUser(getUser(position));
}

View File

@ -0,0 +1,80 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import twitter4j.ResponseList;
import twitter4j.SavedSearch;
/**
* Created by mariotaku on 15/4/29.
*/
public class SavedSearchesAdapter extends BaseAdapter {
private ResponseList<SavedSearch> mData;
private final LayoutInflater mInflater;
public SavedSearchesAdapter(final Context context) {
mInflater = LayoutInflater.from(context);
}
public SavedSearch findItem(final long id) {
for (int i = 0, count = getCount(); i < count; i++) {
if (id != -1 && id == getItemId(i)) return getItem(i);
}
return null;
}
@Override
public int getCount() {
return mData != null ? mData.size() : 0;
}
@Override
public SavedSearch getItem(final int position) {
return mData != null ? mData.get(position) : null;
}
@Override
public long getItemId(final int position) {
return mData != null ? mData.get(position).getId() : -1;
}
@Override
public View getView(final int position, final View convertView, final ViewGroup parent) {
final View view = convertView != null ? convertView : mInflater.inflate(
android.R.layout.simple_list_item_1, null);
final TextView text = (TextView) view.findViewById(android.R.id.text1);
text.setText(getItem(position).getName());
return view;
}
public void setData(final ResponseList<SavedSearch> data) {
mData = data;
notifyDataSetChanged();
}
}

View File

@ -0,0 +1,55 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.adapter;
import android.content.Context;
import android.database.Cursor;
import android.support.v4.widget.SimpleCursorAdapter;
import org.mariotaku.twidere.provider.TwidereDataStore;
/**
* Created by mariotaku on 15/4/29.
*/
public class TrendsAdapter extends SimpleCursorAdapter {
private int mNameIdx;
@Override
public String getItem(int position) {
final Cursor c = getCursor();
if (c != null && !c.isClosed() && c.moveToPosition(position))
return c.getString(mNameIdx);
return null;
}
@Override
public Cursor swapCursor(Cursor c) {
if (c != null) {
mNameIdx = c.getColumnIndex(TwidereDataStore.CachedTrends.NAME);
}
return super.swapCursor(c);
}
public TrendsAdapter(final Context context) {
super(context, android.R.layout.simple_list_item_1, null, new String[]{TwidereDataStore.CachedTrends.NAME},
new int[]{android.R.id.text1}, 0);
}
}

View File

@ -0,0 +1,46 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.adapter.iface;
import org.mariotaku.twidere.model.ParcelableUserList;
import org.mariotaku.twidere.util.MediaLoaderWrapper;
import org.mariotaku.twidere.view.holder.UserListViewHolder.UserListClickListener;
/**
* Created by mariotaku on 15/4/16.
*/
public interface IUserListsAdapter<Data> extends IContentCardAdapter, UserListClickListener {
ParcelableUserList getUserList(int position);
long getUserListId(int position);
int getUserListsCount();
void setData(Data data);
boolean shouldShowAccountsColor();
boolean isNameFirst();
@Override
MediaLoaderWrapper getMediaLoader();
}

View File

@ -0,0 +1,142 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.fragment.support;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.Loader;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.KeyEvent;
import org.mariotaku.twidere.adapter.AbsUserListsAdapter;
import org.mariotaku.twidere.loader.iface.IExtendedLoader;
import org.mariotaku.twidere.loader.support.iface.ICursorSupportLoader;
import org.mariotaku.twidere.model.ParcelableUserList;
import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback;
import org.mariotaku.twidere.util.RecyclerViewNavigationHelper;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.holder.UserListViewHolder;
abstract class AbsUserListsFragment<Data> extends AbsContentRecyclerViewFragment<AbsUserListsAdapter<Data>>
implements LoaderCallbacks<Data>, AbsUserListsAdapter.UserListAdapterListener, KeyboardShortcutCallback {
private RecyclerViewNavigationHelper mRecyclerViewNavigationHelper;
private long mNextCursor;
private long mPrevCursor;
public final Data getData() {
return getAdapter().getData();
}
@Override
public boolean handleKeyboardShortcutSingle(@NonNull KeyboardShortcutsHandler handler, int keyCode, @NonNull KeyEvent event) {
return false;
}
@Override
public boolean handleKeyboardShortcutRepeat(@NonNull KeyboardShortcutsHandler handler, int keyCode, int repeatCount, @NonNull KeyEvent event) {
return mRecyclerViewNavigationHelper.handleKeyboardShortcutRepeat(handler, keyCode, repeatCount, event);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
final FragmentActivity activity = getActivity();
final AbsUserListsAdapter<Data> adapter = getAdapter();
final RecyclerView recyclerView = getRecyclerView();
final LinearLayoutManager layoutManager = getLayoutManager();
adapter.setListener(this);
mRecyclerViewNavigationHelper = new RecyclerViewNavigationHelper(recyclerView, layoutManager, adapter);
final Bundle loaderArgs = new Bundle(getArguments());
loaderArgs.putBoolean(EXTRA_FROM_USER, true);
getLoaderManager().initLoader(0, loaderArgs, this);
}
@Override
public final Loader<Data> onCreateLoader(int id, Bundle args) {
final boolean fromUser = args.getBoolean(EXTRA_FROM_USER);
args.remove(EXTRA_FROM_USER);
return onCreateUserListsLoader(getActivity(), args, fromUser);
}
@Override
public void onLoadFinished(Loader<Data> loader, Data data) {
final AbsUserListsAdapter<Data> adapter = getAdapter();
adapter.setData(data);
if (!(loader instanceof IExtendedLoader) || ((IExtendedLoader) loader).isFromUser()) {
adapter.setLoadMoreSupported(hasMoreData(data));
setRefreshEnabled(true);
}
if (loader instanceof IExtendedLoader) {
((IExtendedLoader) loader).setFromUser(false);
}
if (loader instanceof ICursorSupportLoader) {
mNextCursor = ((ICursorSupportLoader) loader).getNextCursor();
mPrevCursor = ((ICursorSupportLoader) loader).getNextCursor();
}
showContent();
}
@Override
public void onLoaderReset(Loader<Data> loader) {
if (loader instanceof IExtendedLoader) {
((IExtendedLoader) loader).setFromUser(false);
}
}
@Override
public void onUserListClick(UserListViewHolder holder, int position) {
final ParcelableUserList userList = getAdapter().getUserList(position);
if (userList == null) return;
Utils.openUserListDetails(getActivity(), userList);
}
public long getPrevCursor() {
return mPrevCursor;
}
public long getNextCursor() {
return mNextCursor;
}
@Override
public boolean onUserListLongClick(UserListViewHolder holder, int position) {
return true;
}
protected ParcelableUserList getSelectedUserList() {
//TODO return selected
return null;
}
protected abstract boolean hasMoreData(Data data);
protected abstract Loader<Data> onCreateUserListsLoader(Context context, Bundle args, boolean fromUser);
}

View File

@ -1,76 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.fragment.support;
import android.app.Activity;
import android.graphics.Rect;
import android.support.v4.app.FragmentActivity;
import org.mariotaku.twidere.activity.iface.IControlBarActivity;
import org.mariotaku.twidere.activity.iface.IControlBarActivity.ControlBarOffsetListener;
import org.mariotaku.twidere.fragment.iface.IBasePullToRefreshFragment;
public abstract class BasePullToRefreshListFragment extends BaseSupportListFragment implements
IBasePullToRefreshFragment, ControlBarOffsetListener {
@Override
public boolean isRefreshing() {
return false;
}
@Override
public void onDetach() {
final FragmentActivity activity = getActivity();
if (activity instanceof IControlBarActivity) {
((IControlBarActivity) activity).unregisterControlBarOffsetListener(this);
}
super.onDetach();
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof IControlBarActivity) {
((IControlBarActivity) activity).registerControlBarOffsetListener(this);
}
}
@Override
public void setRefreshing(final boolean refresh) {
}
@Override
public boolean triggerRefresh() {
onRefresh();
setRefreshing(true);
return true;
}
@Override
protected void fitSystemWindows(Rect insets) {
super.fitSystemWindows(insets);
}
@Override
public void onControlBarOffsetChanged(IControlBarActivity activity, float offset) {
}
}

View File

@ -1,429 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.fragment.support;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManagerTrojan;
import android.support.v4.app.ListFragment;
import android.support.v4.view.LayoutInflaterCompat;
import android.support.v4.view.LayoutInflaterFactory;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.activity.iface.IControlBarActivity;
import org.mariotaku.twidere.activity.iface.IThemedActivity;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.fragment.iface.IBaseFragment;
import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.ListScrollDistanceCalculator;
import org.mariotaku.twidere.util.ListScrollDistanceCalculator.ScrollDistanceListener;
import org.mariotaku.twidere.util.MultiSelectManager;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.ThemedLayoutInflaterFactory;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.ExtendedFrameLayout;
import org.mariotaku.twidere.view.iface.IExtendedView.TouchInterceptor;
import static android.support.v4.app.ListFragmentTrojan.INTERNAL_EMPTY_ID;
import static android.support.v4.app.ListFragmentTrojan.INTERNAL_LIST_CONTAINER_ID;
import static android.support.v4.app.ListFragmentTrojan.INTERNAL_PROGRESS_CONTAINER_ID;
public class BaseSupportListFragment extends ListFragment implements IBaseFragment, Constants, OnScrollListener,
RefreshScrollTopInterface, ScrollDistanceListener {
private ListScrollDistanceCalculator mListScrollCounter = new ListScrollDistanceCalculator();
private boolean mIsInstanceStateSaved;
private boolean mReachedBottom, mNotReachedBottomBefore;
private boolean mReachedTop, mNotReachedTopBefore;
private boolean mStoppedPreviously;
public final TwidereApplication getApplication() {
return TwidereApplication.getInstance(getActivity());
}
public final ContentResolver getContentResolver() {
final Activity activity = getActivity();
if (activity != null) return activity.getContentResolver();
return null;
}
@Override
public Bundle getExtraConfiguration() {
final Bundle args = getArguments();
final Bundle extras = new Bundle();
if (args != null && args.containsKey(EXTRA_EXTRAS)) {
extras.putAll(args.getBundle(EXTRA_EXTRAS));
}
return extras;
}
public final MultiSelectManager getMultiSelectManager() {
return getApplication() != null ? getApplication().getMultiSelectManager() : null;
}
public final SharedPreferences getSharedPreferences(final String name, final int mode) {
final Activity activity = getActivity();
if (activity != null) return activity.getSharedPreferences(name, mode);
return null;
}
public final Object getSystemService(final String name) {
final Activity activity = getActivity();
if (activity != null) return activity.getSystemService(name);
return null;
}
@Override
public final int getTabPosition() {
final Bundle args = getArguments();
return args != null ? args.getInt(EXTRA_TAB_POSITION, -1) : -1;
}
@Override
public void requestFitSystemWindows() {
final Activity activity = getActivity();
final Fragment parentFragment = getParentFragment();
final SystemWindowsInsetsCallback callback;
if (parentFragment instanceof SystemWindowsInsetsCallback) {
callback = (SystemWindowsInsetsCallback) parentFragment;
} else if (activity instanceof SystemWindowsInsetsCallback) {
callback = (SystemWindowsInsetsCallback) activity;
} else {
return;
}
final Rect insets = new Rect();
if (callback.getSystemWindowsInsets(insets)) {
fitSystemWindows(insets);
}
}
@Override
public void onBaseViewCreated(View view, Bundle savedInstanceState) {
}
protected void fitSystemWindows(Rect insets) {
Utils.makeListFragmentFitsSystemWindows(this, insets);
}
public AsyncTwitterWrapper getTwitterWrapper() {
return getApplication() != null ? getApplication().getTwitterWrapper() : null;
}
public void invalidateOptionsMenu() {
final Activity activity = getActivity();
if (activity == null) return;
activity.invalidateOptionsMenu();
}
public boolean isInstanceStateSaved() {
return mIsInstanceStateSaved;
}
public boolean isReachedBottom() {
return mReachedBottom;
}
@Override
public void onActivityCreated(final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mNotReachedBottomBefore = true;
mStoppedPreviously = false;
mIsInstanceStateSaved = savedInstanceState != null;
mListScrollCounter.setScrollDistanceListener(this);
final ListView lv = getListView();
lv.setOnScrollListener(this);
}
@Override
public void onAttach(final Activity activity) {
super.onAttach(activity);
}
private final TouchInterceptor mInternalOnTouchListener = new TouchInterceptor() {
@Override
public boolean dispatchTouchEvent(View view, MotionEvent event) {
return false;
}
@Override
public boolean onInterceptTouchEvent(View view, MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN: {
onListTouched();
break;
}
}
return false;
}
@Override
public boolean onTouchEvent(View view, MotionEvent event) {
return false;
}
};
protected void onListTouched() {
}
@Override
public final void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
onBaseViewCreated(view, savedInstanceState);
requestFitSystemWindows();
}
/**
* Provide default implementation to return a simple list view. Subclasses
* can override to replace with their own layout. If doing so, the returned
* view hierarchy <em>must</em> have a ListView whose id is
* {@link android.R.id#list android.R.id.list} and can optionally have a
* sibling view id {@link android.R.id#empty android.R.id.empty} that is to
* be shown when the list is empty.
* <p/>
* <p/>
* If you are overriding this method with your own custom content, consider
* including the standard layout {@link android.R.layout#list_content} in
* your layout file, so that you continue to retain all of the standard
* behavior of ListFragment. In particular, this is currently the only way
* to have the built-in indeterminant progress state be shown.
*/
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
final Context context = getActivity();
final FrameLayout root = new FrameLayout(context);
// ------------------------------------------------------------------
final LinearLayout pframe = new LinearLayout(context);
pframe.setId(INTERNAL_PROGRESS_CONTAINER_ID);
pframe.setOrientation(LinearLayout.VERTICAL);
pframe.setVisibility(View.GONE);
pframe.setGravity(Gravity.CENTER);
final ProgressBar progress = new ProgressBar(context, null, android.R.attr.progressBarStyleLarge);
pframe.addView(progress, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
root.addView(pframe, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
// ------------------------------------------------------------------
final ExtendedFrameLayout lframe = new ExtendedFrameLayout(context);
lframe.setId(INTERNAL_LIST_CONTAINER_ID);
lframe.setTouchInterceptor(mInternalOnTouchListener);
final TextView tv = new TextView(getActivity());
tv.setTextAppearance(context, ThemeUtils.getTextAppearanceLarge(context));
tv.setId(INTERNAL_EMPTY_ID);
tv.setGravity(Gravity.CENTER);
lframe.addView(tv, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
final ListView lv = new ListView(getActivity());
lv.setId(android.R.id.list);
lv.setDrawSelectorOnTop(false);
lv.setOnScrollListener(this);
lframe.addView(lv, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
root.addView(lframe, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
// ------------------------------------------------------------------
root.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
return root;
}
@Override
public void onDestroy() {
mStoppedPreviously = false;
super.onDestroy();
}
public void onPostStart() {
}
public void onRestart() {
}
@Override
public void onScroll(final AbsListView view, final int firstVisibleItem, final int visibleItemCount,
final int totalItemCount) {
mListScrollCounter.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
final ListAdapter adapter = getListAdapter();
if (adapter == null) return;
final boolean reachedTop = firstVisibleItem == 0;
final boolean reachedBottom = firstVisibleItem + visibleItemCount >= totalItemCount
&& totalItemCount >= visibleItemCount;
if (mReachedBottom != reachedBottom) {
mReachedBottom = reachedBottom;
if (mReachedBottom && mNotReachedBottomBefore) {
mNotReachedBottomBefore = false;
return;
}
if (mReachedBottom && adapter.getCount() > visibleItemCount) {
onReachedBottom();
}
}
if (mReachedTop != reachedTop) {
mReachedTop = reachedTop;
if (mReachedTop && mNotReachedTopBefore) {
mNotReachedTopBefore = false;
return;
}
if (mReachedTop && adapter.getCount() > visibleItemCount) {
onReachedTop();
}
}
}
@Override
public void onScrollStateChanged(final AbsListView view, final int scrollState) {
mListScrollCounter.onScrollStateChanged(view, scrollState);
}
@Override
public void onStart() {
super.onStart();
onPostStart();
if (mStoppedPreviously) {
onRestart();
}
mStoppedPreviously = false;
}
@Override
public void onStop() {
mStoppedPreviously = true;
super.onStop();
}
public void registerReceiver(final BroadcastReceiver receiver, final IntentFilter filter) {
final Activity activity = getActivity();
if (activity == null) return;
activity.registerReceiver(receiver, filter);
}
@Override
public boolean scrollToStart() {
final Activity activity = getActivity();
if (!isAdded() || activity == null) return false;
Utils.scrollListToTop(getListView());
if (activity instanceof IControlBarActivity) {
((IControlBarActivity) activity).setControlBarOffset(1);
}
return true;
}
public void setProgressBarIndeterminateVisibility(final boolean visible) {
final Activity activity = getActivity();
if (activity == null) return;
activity.setProgressBarIndeterminateVisibility(visible);
}
@Override
public void setSelection(final int position) {
if (getView() == null) return;
Utils.scrollListToPosition(getListView(), position);
}
@Override
public boolean triggerRefresh() {
return false;
}
@Override
public LayoutInflater getLayoutInflater(Bundle savedInstanceState) {
final FragmentActivity activity = getActivity();
if (!(activity instanceof IThemedActivity)) {
return super.getLayoutInflater(savedInstanceState);
}
final LayoutInflater inflater = activity.getLayoutInflater().cloneInContext(getThemedContext());
getChildFragmentManager(); // Init if needed; use raw implementation below.
final LayoutInflaterFactory delegate = FragmentManagerTrojan.getLayoutInflaterFactory(getChildFragmentManager());
LayoutInflaterCompat.setFactory(inflater, new ThemedLayoutInflaterFactory((IThemedActivity) activity, delegate));
return inflater;
}
public Context getThemedContext() {
return getActivity();
}
public void unregisterReceiver(final BroadcastReceiver receiver) {
final Activity activity = getActivity();
if (activity == null) return;
activity.unregisterReceiver(receiver);
}
protected void onReachedBottom() {
}
protected void onReachedTop() {
}
@Override
public void onScrollDistanceChanged(int delta, int total) {
// final FragmentActivity a = getActivity();
// if (a instanceof IControlBarActivity && getTabPosition() >= 0 && getUserVisibleHint()) {
// ((IControlBarActivity) a).moveControlBarBy(delta);
// }
}
}

View File

@ -1,225 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.fragment.support;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.Loader;
import android.util.Log;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View;
import android.widget.AbsListView;
import android.widget.ListView;
import org.mariotaku.twidere.adapter.ParcelableUserListsListAdapter;
import org.mariotaku.twidere.adapter.iface.IBaseCardAdapter.MenuButtonClickListener;
import org.mariotaku.twidere.loader.support.BaseUserListsLoader;
import org.mariotaku.twidere.model.ParcelableUserList;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.MultiSelectManager;
import java.util.ArrayList;
import java.util.List;
import static org.mariotaku.twidere.util.Utils.configBaseCardAdapter;
import static org.mariotaku.twidere.util.Utils.openUserListDetails;
abstract class BaseUserListsListFragment extends BasePullToRefreshListFragment implements
LoaderCallbacks<List<ParcelableUserList>>, OnMenuItemClickListener, MenuButtonClickListener {
private ParcelableUserListsListAdapter mAdapter;
private SharedPreferences mPreferences;
private ListView mListView;
private long mAccountId, mUserId;
private String mScreenName;
private final ArrayList<ParcelableUserList> mData = new ArrayList<>();
private ParcelableUserList mSelectedUserList;
private long mCursor = -1;
private AsyncTwitterWrapper mTwitterWrapper;
private MultiSelectManager mMultiSelectManager;
public long getAccountId() {
return mAccountId;
}
public long getCursor() {
return mCursor;
}
public final ArrayList<ParcelableUserList> getData() {
return mData;
}
@Override
public ParcelableUserListsListAdapter getListAdapter() {
return mAdapter;
}
public String getScreenName() {
return mScreenName;
}
public long getUserId() {
return mUserId;
}
public void loadMoreUserLists() {
final int count = mAdapter.getCount();
if (count - 1 > 0) {
final Bundle args = getArguments();
if (args != null) {
args.putLong(EXTRA_MAX_ID, mAdapter.getItem(count - 1).user_id);
}
if (!getLoaderManager().hasRunningLoaders()) {
getLoaderManager().restartLoader(0, args, this);
}
}
}
public abstract Loader<List<ParcelableUserList>> newLoaderInstance(long accountId, long userId, String screen_name);
@Override
public void onActivityCreated(final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mTwitterWrapper = getTwitterWrapper();
mMultiSelectManager = getMultiSelectManager();
mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
final Bundle args = getArguments();
if (args != null) {
mAccountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
mUserId = args.getLong(EXTRA_USER_ID, -1);
mScreenName = args.getString(EXTRA_SCREEN_NAME);
}
mAdapter = new ParcelableUserListsListAdapter(getActivity());
mListView = getListView();
mListView.setFastScrollEnabled(mPreferences.getBoolean(KEY_FAST_SCROLL_THUMB, false));
// final long account_id = args.getLong(EXTRA_ACCOUNT_ID, -1);
// if (mAccountId != account_id) {
// mAdapter.clear();
// mData.clear();
// }
// mAccountId = account_id;
setListAdapter(mAdapter);
getLoaderManager().initLoader(0, getArguments(), this);
setListShown(false);
}
@Override
public Loader<List<ParcelableUserList>> onCreateLoader(final int id, final Bundle args) {
setProgressBarIndeterminateVisibility(true);
return newLoaderInstance(mAccountId, mUserId, mScreenName);
}
@Override
public final void onListItemClick(final ListView view, final View child, final int position, final long id) {
if (mMultiSelectManager.isActive()) return;
final int userListPosition = mAdapter.findItemPosition(id);
if (userListPosition < 0) return;
openUserListDetails(getActivity(), mAdapter.getItem(userListPosition));
}
@Override
public void onLoaderReset(final Loader<List<ParcelableUserList>> loader) {
setProgressBarIndeterminateVisibility(false);
}
@Override
public void onLoadFinished(final Loader<List<ParcelableUserList>> loader, final List<ParcelableUserList> data) {
setProgressBarIndeterminateVisibility(false);
mAdapter.appendData(data);
if (loader instanceof BaseUserListsLoader) {
final long cursor = ((BaseUserListsLoader) loader).getNextCursor();
if (cursor != -2) {
mCursor = cursor;
}
}
setRefreshing(false);
setListShown(true);
}
@Override
public void onMenuButtonClick(final View button, final int position, final long id) {
final ParcelableUserList userList = mAdapter.getItem(position - mListView.getHeaderViewsCount());
if (userList == null) return;
showMenu(button, userList);
}
@Override
public boolean onMenuItemClick(final MenuItem item) {
if (mSelectedUserList == null) return false;
switch (item.getItemId()) {
case MENU_ADD: {
AddUserListMemberDialogFragment.show(getFragmentManager(), mSelectedUserList.account_id,
mSelectedUserList.id);
break;
}
case MENU_DELETE: {
mTwitterWrapper.destroyUserListAsync(mSelectedUserList.account_id, mSelectedUserList.id);
break;
}
default: {
if (item.getIntent() != null) {
try {
startActivity(item.getIntent());
} catch (final ActivityNotFoundException e) {
Log.w(LOGTAG, e);
return false;
}
}
break;
}
}
return true;
}
@Override
public void onRefresh() {
if (isRefreshing()) return;
getLoaderManager().restartLoader(0, getArguments(), this);
}
@Override
public void onResume() {
super.onResume();
configBaseCardAdapter(getActivity(), mAdapter);
}
@Override
public void onScrollStateChanged(final AbsListView view, final int scrollState) {
}
@Override
protected void onReachedBottom() {
loadMoreUserLists();
}
private void showMenu(final View view, final ParcelableUserList userList) {
mSelectedUserList = userList;
//TODO show menu
}
}

View File

@ -0,0 +1,78 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.fragment.support;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import org.mariotaku.twidere.adapter.ParcelableUserListsAdapter;
import org.mariotaku.twidere.model.ParcelableUserList;
import java.util.List;
public abstract class ParcelableUserListsFragment extends AbsUserListsFragment<List<ParcelableUserList>> {
@Override
public boolean isRefreshing() {
final LoaderManager lm = getLoaderManager();
return lm.hasRunningLoaders();
}
@NonNull
@Override
protected final ParcelableUserListsAdapter onCreateAdapter(Context context, boolean compact) {
return new ParcelableUserListsAdapter(context, compact);
}
protected long getAccountId() {
final Bundle args = getArguments();
return args != null ? args.getLong(EXTRA_ACCOUNT_ID, -1) : -1;
}
@Override
protected boolean hasMoreData(List<ParcelableUserList> data) {
return data == null || !data.isEmpty();
}
@Override
public void onLoadFinished(Loader<List<ParcelableUserList>> loader, List<ParcelableUserList> data) {
super.onLoadFinished(loader, data);
setRefreshEnabled(true);
setRefreshing(false);
setLoadMoreIndicatorVisible(false);
}
@Override
public void onLoadMoreContents() {
super.onLoadMoreContents();
final Bundle loaderArgs = new Bundle(getArguments());
loaderArgs.putBoolean(EXTRA_FROM_USER, true);
loaderArgs.putLong(EXTRA_NEXT_CURSOR, getNextCursor());
getLoaderManager().restartLoader(0, loaderArgs, this);
}
protected void removeUsers(long... ids) {
//TODO remove from adapter
}
}

View File

@ -30,7 +30,7 @@ import org.mariotaku.querybuilder.SQLQueryBuilder;
import org.mariotaku.querybuilder.Table;
import org.mariotaku.querybuilder.query.SQLSelectQuery;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.fragment.support.TrendsSuggectionsFragment.TrendsAdapter;
import org.mariotaku.twidere.adapter.TrendsAdapter;
import org.mariotaku.twidere.provider.TwidereDataStore.CachedTrends;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.Utils;

View File

@ -21,17 +21,14 @@ package org.mariotaku.twidere.fragment.support;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.Loader;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import org.mariotaku.twidere.adapter.SavedSearchesAdapter;
import org.mariotaku.twidere.loader.support.SavedSearchesLoader;
import java.util.Collections;
@ -42,13 +39,9 @@ import twitter4j.SavedSearch;
import static org.mariotaku.twidere.util.Utils.openTweetSearch;
public class SavedSearchesListFragment extends BasePullToRefreshListFragment implements
LoaderCallbacks<ResponseList<SavedSearch>>, OnItemLongClickListener {
public class SavedSearchesListFragment extends AbsContentListViewFragment<SavedSearchesAdapter> implements
LoaderCallbacks<ResponseList<SavedSearch>>, AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener {
private SavedSearchesAdapter mAdapter;
private long mAccountId;
private ListView mListView;
private static final Comparator<SavedSearch> POSITION_COMPARATOR = new Comparator<SavedSearch>() {
@Override
@ -57,18 +50,24 @@ public class SavedSearchesListFragment extends BasePullToRefreshListFragment imp
}
};
private long mAccountId;
@Override
public void onActivityCreated(final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mAdapter = new SavedSearchesAdapter(getActivity());
setListAdapter(mAdapter);
mListView = getListView();
mListView.setOnItemLongClickListener(this);
final ListView listView = getListView();
listView.setOnItemClickListener(this);
listView.setOnItemLongClickListener(this);
final Bundle args = getArguments();
mAccountId = args != null ? args.getLong(EXTRA_ACCOUNT_ID, -1) : -1;
getLoaderManager().initLoader(0, null, this);
setListShown(false);
showProgress();
}
@NonNull
@Override
protected SavedSearchesAdapter onCreateAdapter(Context context, boolean compact) {
return new SavedSearchesAdapter(getActivity());
}
@Override
@ -78,22 +77,22 @@ public class SavedSearchesListFragment extends BasePullToRefreshListFragment imp
@Override
public boolean onItemLongClick(final AdapterView<?> view, final View child, final int position, final long id) {
final SavedSearch item = mAdapter.findItem(id);
final SavedSearch item = getAdapter().findItem(id);
if (item == null) return false;
DestroySavedSearchDialogFragment.show(getFragmentManager(), mAccountId, item.getId(), item.getName());
return true;
}
@Override
public void onListItemClick(final ListView view, final View child, final int position, final long id) {
final SavedSearch item = mAdapter.findItem(id);
public void onItemClick(final AdapterView<?> view, final View child, final int position, final long id) {
final SavedSearch item = getAdapter().findItem(id);
if (item == null) return;
openTweetSearch(getActivity(), mAccountId, item.getQuery());
}
@Override
public void onLoaderReset(final Loader<ResponseList<SavedSearch>> loader) {
mAdapter.setData(null);
getAdapter().setData(null);
}
@Override
@ -101,8 +100,8 @@ public class SavedSearchesListFragment extends BasePullToRefreshListFragment imp
if (data != null) {
Collections.sort(data, POSITION_COMPARATOR);
}
mAdapter.setData(data);
setListShown(true);
getAdapter().setData(data);
showContent();
setRefreshing(false);
}
@ -112,51 +111,9 @@ public class SavedSearchesListFragment extends BasePullToRefreshListFragment imp
getLoaderManager().restartLoader(0, null, this);
}
static class SavedSearchesAdapter extends BaseAdapter {
private ResponseList<SavedSearch> mData;
private final LayoutInflater mInflater;
public SavedSearchesAdapter(final Context context) {
mInflater = LayoutInflater.from(context);
}
public SavedSearch findItem(final long id) {
for (int i = 0, count = getCount(); i < count; i++) {
if (id != -1 && id == getItemId(i)) return getItem(i);
}
return null;
}
@Override
public int getCount() {
return mData != null ? mData.size() : 0;
}
@Override
public SavedSearch getItem(final int position) {
return mData != null ? mData.get(position) : null;
}
@Override
public long getItemId(final int position) {
return mData != null ? mData.get(position).getId() : -1;
}
@Override
public View getView(final int position, final View convertView, final ViewGroup parent) {
final View view = convertView != null ? convertView : mInflater.inflate(
android.R.layout.simple_list_item_1, null);
final TextView text = (TextView) view.findViewById(android.R.id.text1);
text.setText(getItem(position).getName());
return view;
}
public void setData(final ResponseList<SavedSearch> data) {
mData = data;
notifyDataSetChanged();
}
@Override
public boolean isRefreshing() {
return getLoaderManager().hasRunningLoaders();
}
}

View File

@ -24,16 +24,18 @@ import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.SimpleCursorAdapter;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import com.squareup.otto.Bus;
import com.squareup.otto.Subscribe;
import org.mariotaku.twidere.adapter.TrendsAdapter;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.provider.TwidereDataStore.CachedTrends;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
@ -44,12 +46,12 @@ import static org.mariotaku.twidere.util.Utils.getDefaultAccountId;
import static org.mariotaku.twidere.util.Utils.getTableNameByUri;
import static org.mariotaku.twidere.util.Utils.openTweetSearch;
public class TrendsSuggectionsFragment extends BasePullToRefreshListFragment implements LoaderCallbacks<Cursor> {
public class TrendsSuggestionsFragment extends AbsContentListViewFragment<TrendsAdapter>
implements LoaderCallbacks<Cursor>, AdapterView.OnItemClickListener {
private MultiSelectManager mMultiSelectManager;
private SharedPreferences mPreferences;
private TrendsAdapter mTrendsAdapter;
private long mAccountId;
@ -59,11 +61,16 @@ public class TrendsSuggectionsFragment extends BasePullToRefreshListFragment imp
super.onActivityCreated(savedInstanceState);
mMultiSelectManager = getMultiSelectManager();
mAccountId = getDefaultAccountId(getActivity());
mTrendsAdapter = new TrendsAdapter(getActivity());
setListAdapter(mTrendsAdapter);
getListView().setOnItemClickListener(this);
getLoaderManager().initLoader(0, null, this);
}
@NonNull
@Override
protected TrendsAdapter onCreateAdapter(Context context, boolean compact) {
return new TrendsAdapter(getActivity());
}
@Override
public Loader<Cursor> onCreateLoader(final int id, final Bundle args) {
final Uri uri = CachedTrends.Local.CONTENT_URI;
@ -74,21 +81,27 @@ public class TrendsSuggectionsFragment extends BasePullToRefreshListFragment imp
}
@Override
public void onListItemClick(final ListView l, final View v, final int position, final long id) {
public void onItemClick(final AdapterView<?> view, final View child, final int position, final long id) {
if (mMultiSelectManager.isActive()) return;
final String trend = mTrendsAdapter.getItem(position - l.getHeaderViewsCount());
final String trend;
if (view instanceof ListView) {
trend = getAdapter().getItem(position - ((ListView) view).getHeaderViewsCount());
} else {
trend = getAdapter().getItem(position);
}
if (trend == null) return;
openTweetSearch(getActivity(), mAccountId, trend);
}
@Override
public void onLoaderReset(final Loader<Cursor> loader) {
mTrendsAdapter.swapCursor(null);
getAdapter().swapCursor(null);
}
@Override
public void onLoadFinished(final Loader<Cursor> loader, final Cursor cursor) {
mTrendsAdapter.swapCursor(cursor);
getAdapter().swapCursor(cursor);
}
@Override
@ -99,6 +112,11 @@ public class TrendsSuggectionsFragment extends BasePullToRefreshListFragment imp
twitter.getLocalTrendsAsync(mAccountId, mPreferences.getInt(KEY_LOCAL_TRENDS_WOEID, 1));
}
@Override
public boolean isRefreshing() {
return false;
}
@Override
public void onStart() {
super.onStart();
@ -125,30 +143,4 @@ public class TrendsSuggectionsFragment extends BasePullToRefreshListFragment imp
setRefreshing(twitter.isLocalTrendsRefreshing());
}
static class TrendsAdapter extends SimpleCursorAdapter {
private int mNameIdx;
@Override
public String getItem(int position) {
final Cursor c = getCursor();
if (c != null && !c.isClosed() && c.moveToPosition(position))
return c.getString(mNameIdx);
return null;
}
@Override
public Cursor swapCursor(Cursor c) {
if (c != null) {
mNameIdx = c.getColumnIndex(CachedTrends.NAME);
}
return super.swapCursor(c);
}
public TrendsAdapter(final Context context) {
super(context, android.R.layout.simple_list_item_1, null, new String[]{CachedTrends.NAME},
new int[]{android.R.id.text1}, 0);
}
}
}

View File

@ -128,15 +128,21 @@ public class UserListFragment extends BaseSupportFragment implements OnClickList
};
public void displayUserList(final ParcelableUserList userList) {
if (userList == null || getActivity() == null) return;
final FragmentActivity activity = getActivity();
if (activity == null) return;
getLoaderManager().destroyLoader(0);
mUserList = userList;
final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST);
final String displayName = mUserColorNameManager.getDisplayName(userList, nameFirst, false);
final String description = userList.description;
final TwidereLinkify linkify = new TwidereLinkify(new OnLinkClickHandler(getActivity(),
getMultiSelectManager()));
if (userList != null) {
final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST);
final String displayName = mUserColorNameManager.getDisplayName(userList, nameFirst, false);
final String description = userList.description;
final TwidereLinkify linkify = new TwidereLinkify(new OnLinkClickHandler(activity,
getMultiSelectManager()));
activity.setTitle(userList.name);
} else {
activity.setTitle(R.string.user_list);
}
invalidateOptionsMenu();
}

View File

@ -19,6 +19,8 @@
package org.mariotaku.twidere.fragment.support;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.content.Loader;
import org.mariotaku.twidere.loader.support.UserListMembershipsLoader;
@ -26,12 +28,16 @@ import org.mariotaku.twidere.model.ParcelableUserList;
import java.util.List;
public class UserListMembershipsListFragment extends BaseUserListsListFragment {
public class UserListMembershipsListFragment extends ParcelableUserListsFragment {
@Override
public Loader<List<ParcelableUserList>> newLoaderInstance(final long accountId, final long userId,
final String screenName) {
return new UserListMembershipsLoader(getActivity(), accountId, userId, screenName, getCursor(), getData());
public Loader<List<ParcelableUserList>> onCreateUserListsLoader(final Context context,
final Bundle args, final boolean fromUser) {
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);
final long cursor = args.getLong(EXTRA_NEXT_CURSOR, -1);
return new UserListMembershipsLoader(getActivity(), accountId, userId, screenName, cursor, getData());
}
}

View File

@ -31,15 +31,13 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.ParcelableUserListsListAdapter;
import org.mariotaku.twidere.adapter.AbsUserListsAdapter;
import org.mariotaku.twidere.loader.support.UserListsLoader;
import org.mariotaku.twidere.model.ParcelableUserList;
import java.util.List;
import static org.mariotaku.twidere.util.Utils.getAccountScreenName;
public class UserListsListFragment extends BaseUserListsListFragment {
public class UserListsListFragment extends ParcelableUserListsFragment {
private final BroadcastReceiver mStatusReceiver = new BroadcastReceiver() {
@ -57,8 +55,11 @@ public class UserListsListFragment extends BaseUserListsListFragment {
};
@Override
public Loader<List<ParcelableUserList>> newLoaderInstance(final long accountId, final long userId,
final String screenName) {
public Loader<List<ParcelableUserList>> onCreateUserListsLoader(final Context context,
final Bundle args, final boolean fromUser) {
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 UserListsLoader(getActivity(), accountId, userId, screenName, true, getData());
}
@ -70,7 +71,7 @@ public class UserListsListFragment extends BaseUserListsListFragment {
@Override
public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
inflater.inflate(R.menu.menu_user_list_created, menu);
inflater.inflate(R.menu.menu_user_lists_owned, menu);
}
@Override
@ -90,11 +91,11 @@ public class UserListsListFragment extends BaseUserListsListFragment {
@Override
public void onPrepareOptionsMenu(final Menu menu) {
final MenuItem item = menu.findItem(R.id.new_user_list);
if (item == null) return;
final long account_id = getAccountId(), user_id = getUserId();
final String screen_name = getAccountScreenName(getActivity(), account_id);
item.setVisible(user_id == account_id || screen_name != null && screen_name.equalsIgnoreCase(getScreenName()));
// final MenuItem item = menu.findItem(R.id.new_user_list);
// if (item == null) return;
// final long account_id = getAccountId(), user_id = getUserId();
// final String screen_name = getAccountScreenName(getActivity(), account_id);
// item.setVisible(user_id == account_id || screen_name != null && screen_name.equalsIgnoreCase(getScreenName()));
}
public void onPullUpToRefresh() {
@ -113,11 +114,11 @@ public class UserListsListFragment extends BaseUserListsListFragment {
}
private void removeUserList(final long id) {
final ParcelableUserListsListAdapter adapter = getListAdapter();
final int listsIdx = adapter.findItemPosition(id);
if (listsIdx >= 0) {
adapter.removeAt(listsIdx);
}
final AbsUserListsAdapter<List<ParcelableUserList>> adapter = getAdapter();
// final int listsIdx = adapter.findItemPosition(id);
// if (listsIdx >= 0) {
// adapter.removeAt(listsIdx);
// }
}
}

View File

@ -22,13 +22,15 @@ package org.mariotaku.twidere.loader.support;
import android.content.Context;
import android.content.SharedPreferences;
import org.mariotaku.twidere.loader.support.iface.ICursorSupportLoader;
import org.mariotaku.twidere.model.ParcelableUser;
import java.util.List;
import twitter4j.CursorSupport;
public abstract class BaseCursorSupportUsersLoader extends Twitter4JUsersLoader {
public abstract class BaseCursorSupportUsersLoader extends Twitter4JUsersLoader
implements ICursorSupportLoader {
private final long mCursor;
private final SharedPreferences mPreferences;
@ -49,14 +51,17 @@ public abstract class BaseCursorSupportUsersLoader extends Twitter4JUsersLoader
return mLoadItemLimit;
}
@Override
public final long getCursor() {
return mCursor;
}
@Override
public final long getNextCursor() {
return mNextCursor;
}
@Override
public final long getPrevCursor() {
return mPrevCursor;
}

View File

@ -22,6 +22,7 @@ package org.mariotaku.twidere.loader.support;
import android.content.Context;
import android.support.v4.content.AsyncTaskLoader;
import org.mariotaku.twidere.loader.support.iface.ICursorSupportLoader;
import org.mariotaku.twidere.model.ParcelableUserList;
import org.mariotaku.twidere.util.collection.NoDuplicatesArrayList;
@ -36,7 +37,8 @@ import twitter4j.UserList;
import static org.mariotaku.twidere.util.Utils.getTwitterInstance;
public abstract class BaseUserListsLoader extends AsyncTaskLoader<List<ParcelableUserList>> {
public abstract class BaseUserListsLoader extends AsyncTaskLoader<List<ParcelableUserList>>
implements ICursorSupportLoader {
protected final NoDuplicatesArrayList<ParcelableUserList> mData = new NoDuplicatesArrayList<>();
protected final long mAccountId;
@ -44,24 +46,27 @@ public abstract class BaseUserListsLoader extends AsyncTaskLoader<List<Parcelabl
private long mNextCursor, mPrevCursor;
public BaseUserListsLoader(final Context context, final long account_id, final long cursor,
public BaseUserListsLoader(final Context context, final long accountId, final long cursor,
final List<ParcelableUserList> data) {
super(context);
if (data != null) {
mData.addAll(data);
}
mCursor = cursor;
mAccountId = account_id;
mAccountId = accountId;
}
@Override
public long getCursor() {
return mCursor;
}
@Override
public long getNextCursor() {
return mNextCursor;
}
@Override
public long getPrevCursor() {
return mPrevCursor;
}
@ -71,25 +76,26 @@ public abstract class BaseUserListsLoader extends AsyncTaskLoader<List<Parcelabl
@Override
public List<ParcelableUserList> loadInBackground() {
final Twitter twitter = getTwitterInstance(getContext(), mAccountId, true);
List<UserList> list_loaded = null;
List<UserList> listLoaded = null;
try {
list_loaded = getUserLists(twitter);
listLoaded = getUserLists(twitter);
} catch (final TwitterException e) {
e.printStackTrace();
}
if (list_loaded != null) {
final int list_size = list_loaded.size();
if (list_loaded instanceof PageableResponseList) {
mNextCursor = ((CursorSupport) list_loaded).getNextCursor();
mPrevCursor = ((CursorSupport) list_loaded).getPreviousCursor();
for (int i = 0; i < list_size; i++) {
final UserList list = list_loaded.get(i);
mData.add(new ParcelableUserList(list, mAccountId, (mCursor + 1) * 20 + i, isFollowing(list)));
if (listLoaded != null) {
final int listSize = listLoaded.size();
if (listLoaded instanceof PageableResponseList) {
mNextCursor = ((CursorSupport) listLoaded).getNextCursor();
mPrevCursor = ((CursorSupport) listLoaded).getPreviousCursor();
final int dataSize = mData.size();
for (int i = 0; i < listSize; i++) {
final UserList list = listLoaded.get(i);
mData.add(new ParcelableUserList(list, mAccountId, dataSize + i, isFollowing(list)));
}
} else {
for (int i = 0; i < list_size; i++) {
final UserList list = list_loaded.get(i);
mData.add(new ParcelableUserList(list_loaded.get(i), mAccountId, i, isFollowing(list)));
for (int i = 0; i < listSize; i++) {
final UserList list = listLoaded.get(i);
mData.add(new ParcelableUserList(listLoaded.get(i), mAccountId, i, isFollowing(list)));
}
}
}

View File

@ -0,0 +1,31 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.loader.support.iface;
/**
* Created by mariotaku on 15/4/29.
*/
public interface ICursorSupportLoader {
long getCursor();
long getNextCursor();
long getPrevCursor();
}

View File

@ -43,7 +43,7 @@ import org.mariotaku.twidere.fragment.support.InvalidTabFragment;
import org.mariotaku.twidere.fragment.support.MentionsTimelineFragment;
import org.mariotaku.twidere.fragment.support.RetweetsOfMeFragment;
import org.mariotaku.twidere.fragment.support.StatusesSearchFragment;
import org.mariotaku.twidere.fragment.support.TrendsSuggectionsFragment;
import org.mariotaku.twidere.fragment.support.TrendsSuggestionsFragment;
import org.mariotaku.twidere.fragment.support.UserFavoritesFragment;
import org.mariotaku.twidere.fragment.support.UserListTimelineFragment;
import org.mariotaku.twidere.fragment.support.UserTimelineFragment;
@ -77,7 +77,7 @@ public class CustomTabUtils implements Constants {
DirectMessagesFragment.class, R.string.direct_messages, R.drawable.ic_action_message,
CustomTabConfiguration.ACCOUNT_OPTIONAL, CustomTabConfiguration.FIELD_TYPE_NONE, 2, false));
CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_TRENDS_SUGGESTIONS, new CustomTabConfiguration(
TrendsSuggectionsFragment.class, R.string.trends, R.drawable.ic_action_hashtag,
TrendsSuggestionsFragment.class, R.string.trends, R.drawable.ic_action_hashtag,
CustomTabConfiguration.ACCOUNT_NONE, CustomTabConfiguration.FIELD_TYPE_NONE, 3, true));
CUSTOM_TABS_CONFIGURATION_MAP.put(TAB_TYPE_FAVORITES, new CustomTabConfiguration(UserFavoritesFragment.class,
R.string.favorites, R.drawable.ic_action_star, CustomTabConfiguration.ACCOUNT_REQUIRED,

View File

@ -0,0 +1,131 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.view.holder;
import android.content.Context;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.view.View;
import android.widget.TextView;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.iface.ContentCardClickListener;
import org.mariotaku.twidere.adapter.iface.IUserListsAdapter;
import org.mariotaku.twidere.model.ParcelableUserList;
import org.mariotaku.twidere.util.MediaLoaderWrapper;
import org.mariotaku.twidere.util.UserColorNameManager;
import org.mariotaku.twidere.view.ShapedImageView;
import org.mariotaku.twidere.view.iface.IColorLabelView;
/**
* Created by mariotaku on 15/4/29.
*/
public class UserListViewHolder extends ViewHolder implements View.OnClickListener, View.OnLongClickListener {
private final IUserListsAdapter<?> adapter;
private final IColorLabelView itemContent;
private final ShapedImageView profileImageView;
private final TextView nameView;
private final TextView createdByView;
private UserListClickListener userListClickListener;
public UserListViewHolder(IUserListsAdapter<?> adapter, View itemView) {
super(itemView);
itemContent = (IColorLabelView) itemView.findViewById(R.id.item_content);
this.adapter = adapter;
profileImageView = (ShapedImageView) itemView.findViewById(R.id.profile_image);
nameView = (TextView) itemView.findViewById(R.id.name);
createdByView = (TextView) itemView.findViewById(R.id.created_by);
}
public void displayUserList(ParcelableUserList userList) {
final Context context = adapter.getContext();
final MediaLoaderWrapper loader = adapter.getMediaLoader();
final UserColorNameManager manager = adapter.getUserColorNameManager();
itemContent.drawStart(manager.getUserColor(userList.user_id, false));
nameView.setText(userList.name);
final boolean nameFirst = adapter.isNameFirst();
final String createdByDisplayName = manager.getDisplayName(userList, nameFirst, false);
createdByView.setText(context.getString(R.string.created_by, createdByDisplayName));
if (adapter.isProfileImageEnabled()) {
profileImageView.setVisibility(View.VISIBLE);
loader.displayProfileImage(profileImageView, userList.user_profile_image_url);
} else {
profileImageView.setVisibility(View.GONE);
loader.cancelDisplayTask(profileImageView);
}
}
public void setOnClickListeners() {
setUserListClickListener(adapter);
}
@Override
public void onClick(View v) {
if (userListClickListener == null) return;
switch (v.getId()) {
case R.id.item_content: {
userListClickListener.onUserListClick(this, getLayoutPosition());
break;
}
}
}
@Override
public boolean onLongClick(View v) {
if (userListClickListener == null) return false;
switch (v.getId()) {
case R.id.item_content: {
return userListClickListener.onUserListLongClick(this, getLayoutPosition());
}
}
return false;
}
public void setUserListClickListener(UserListClickListener listener) {
userListClickListener = listener;
((View) itemContent).setOnClickListener(this);
((View) itemContent).setOnLongClickListener(this);
}
public void setupViewOptions() {
setTextSize(adapter.getTextSize());
profileImageView.setStyle(adapter.getProfileImageStyle());
}
public void setTextSize(final float textSize) {
nameView.setTextSize(textSize);
createdByView.setTextSize(textSize * 0.75f);
}
public static interface UserListClickListener extends ContentCardClickListener {
void onUserListClick(UserListViewHolder holder, int position);
boolean onUserListLongClick(UserListViewHolder holder, int position);
}
}

View File

@ -72,12 +72,11 @@ public class UserViewHolder extends ViewHolder implements OnClickListener, OnLon
public void displayUser(ParcelableUser user) {
final Context context = adapter.getContext();
final MediaLoaderWrapper loader = adapter.getMediaLoader();
final UserColorNameManager manager = adapter.getUserColorNameManager();
setUserColor(manager.getUserColor(user.id, false));
itemContent.drawStart(manager.getUserColor(user.id, false));
final int userTypeRes = getUserTypeIconRes(user.is_verified, user.is_protected);
if (userTypeRes != 0) {
@ -157,10 +156,6 @@ public class UserViewHolder extends ViewHolder implements OnClickListener, OnLon
((View) itemContent).setOnLongClickListener(this);
}
public void setUserColor(final int color) {
itemContent.drawStart(color);
}
public void setupViewOptions() {
setTextSize(adapter.getTextSize());
profileImageView.setStyle(adapter.getProfileImageStyle());

View File

@ -20,12 +20,13 @@
package org.mariotaku.twidere.view.iface;
import android.content.res.ColorStateList;
import android.support.annotation.NonNull;
/**
* Created by mariotaku on 14/12/19.
*/
public interface IThemeAccentView {
public void setAccentTintColor(ColorStateList color);
public void setAccentTintColor(@NonNull ColorStateList color);
}

View File

@ -20,12 +20,13 @@
package org.mariotaku.twidere.view.iface;
import android.content.res.ColorStateList;
import android.support.annotation.NonNull;
/**
* Created by mariotaku on 14/12/19.
*/
public interface IThemeBackgroundTintView {
public void setBackgroundTintColor(ColorStateList color);
public void setBackgroundTintColor(@NonNull ColorStateList color);
}

View File

@ -0,0 +1,51 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.view.themed;
import android.content.Context;
import android.content.res.ColorStateList;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import com.rengwuxian.materialedittext.MaterialEditText;
import org.mariotaku.twidere.view.iface.IThemeAccentView;
/**
* Created by mariotaku on 15/4/29.
*/
public class ThemedAccentMaterialEditText extends MaterialEditText implements IThemeAccentView {
public ThemedAccentMaterialEditText(Context context) {
super(context);
}
public ThemedAccentMaterialEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ThemedAccentMaterialEditText(Context context, AttributeSet attrs, int style) {
super(context, attrs, style);
}
@Override
public void setAccentTintColor(@NonNull ColorStateList color) {
setPrimaryColor(color.getDefaultColor());
}
}

View File

@ -21,7 +21,7 @@ package org.mariotaku.twidere.view.themed;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import com.pnikosis.materialishprogress.ProgressWheel;
@ -31,21 +31,17 @@ import org.mariotaku.twidere.view.iface.IThemeAccentView;
/**
* Created by mariotaku on 15/4/25.
*/
public class TintThemedProgressWheel extends ProgressWheel implements IThemeAccentView {
public TintThemedProgressWheel(Context context, AttributeSet attrs) {
public class ThemedAccentProgressWheel extends ProgressWheel implements IThemeAccentView {
public ThemedAccentProgressWheel(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TintThemedProgressWheel(Context context) {
public ThemedAccentProgressWheel(Context context) {
super(context);
}
@Override
public void setAccentTintColor(ColorStateList color) {
if (color != null) {
setBarColor(color.getDefaultColor());
} else {
setBarColor(Color.TRANSPARENT);
}
public void setAccentTintColor(@NonNull ColorStateList color) {
setBarColor(color.getDefaultColor());
}
}

View File

@ -23,28 +23,28 @@ import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.PorterDuff.Mode;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.widget.ImageButton;
import org.mariotaku.twidere.view.iface.IThemeAccentView;
import org.mariotaku.twidere.view.iface.IThemeBackgroundTintView;
/**
* Created by mariotaku on 14/11/5.
*/
public class TintThemedImageButton extends ImageButton implements IThemeBackgroundTintView {
public class ThemedBackgroundTintImageButton extends ImageButton implements IThemeBackgroundTintView {
private final int mDefaultColor;
public TintThemedImageButton(Context context) {
public ThemedBackgroundTintImageButton(Context context) {
this(context, null);
}
public TintThemedImageButton(Context context, AttributeSet attrs) {
public ThemedBackgroundTintImageButton(Context context, AttributeSet attrs) {
this(context, attrs, android.R.attr.imageButtonStyle);
}
public TintThemedImageButton(Context context, AttributeSet attrs, int defStyleAttr) {
public ThemedBackgroundTintImageButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
final TypedArray a = context.obtainStyledAttributes(attrs, new int[]{android.R.attr.color,
android.R.attr.colorForeground});
@ -63,11 +63,7 @@ public class TintThemedImageButton extends ImageButton implements IThemeBackgrou
@Override
public void setBackgroundTintColor(ColorStateList color) {
if (color == null) {
clearColorFilter();
} else {
setColorFilter(color.getDefaultColor());
}
public void setBackgroundTintColor(@NonNull ColorStateList color) {
setColorFilter(color.getDefaultColor());
}
}

View File

@ -50,7 +50,7 @@
<requestFocus />
</EditText>
<org.mariotaku.twidere.view.themed.TintThemedImageButton
<org.mariotaku.twidere.view.themed.ThemedBackgroundTintImageButton
android:id="@+id/query_button"
style="?cardActionButtonStyle"
android:layout_width="@dimen/element_size_normal"

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
<?xml version="1.0" encoding="utf-8"?><!--
~ Twidere - Twitter client for Android
~
~ Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
@ -18,16 +17,14 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<org.mariotaku.twidere.view.TintedStatusFrameLayout
android:id="@+id/main_content"
xmlns:android="http://schemas.android.com/apk/res/android"
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
android:orientation="vertical"
app:setPadding="true">
android:orientation="vertical">
<ScrollView
android:id="@+id/edit_profile_content"
@ -67,7 +64,7 @@
android:layout_height="@dimen/element_size_mlarge"
android:layout_gravity="center"
android:foreground="?selectableItemBackground"
android:scaleType="centerCrop"/>
android:scaleType="centerCrop" />
<LinearLayout
android:layout_width="match_parent"
@ -84,7 +81,7 @@
android:textAllCaps="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:textColorPrimary"
android:textStyle="bold"/>
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
@ -103,7 +100,7 @@
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_normal"
android:paddingTop="0dp"
android:text="@string/photo"/>
android:text="@string/photo" />
<org.mariotaku.twidere.view.ActionIconThemedTextView
android:id="@+id/profile_image_gallery"
@ -116,7 +113,7 @@
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_normal"
android:paddingTop="0dp"
android:text="@string/gallery"/>
android:text="@string/gallery" />
</LinearLayout>
@ -136,7 +133,7 @@
android:layout_height="@dimen/element_size_mlarge"
android:layout_gravity="center"
android:foreground="?selectableItemBackground"
android:scaleType="centerCrop"/>
android:scaleType="centerCrop" />
<LinearLayout
android:layout_width="match_parent"
@ -153,7 +150,7 @@
android:textAllCaps="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:textColorPrimary"
android:textStyle="bold"/>
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
@ -172,7 +169,7 @@
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_normal"
android:paddingTop="0dp"
android:text="@string/gallery"/>
android:text="@string/gallery" />
<org.mariotaku.twidere.view.ActionIconThemedTextView
android:id="@+id/profile_banner_remove"
@ -185,7 +182,7 @@
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_normal"
android:paddingTop="0dp"
android:text="@string/remove"/>
android:text="@string/remove" />
</LinearLayout>
@ -211,8 +208,7 @@
android:orientation="vertical"
android:padding="@dimen/element_spacing_normal">
<com.rengwuxian.materialedittext.MaterialEditText
<org.mariotaku.twidere.view.themed.ThemedAccentMaterialEditText
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -221,10 +217,9 @@
app:met_baseColor="?android:textColorPrimary"
app:met_floatingLabel="normal"
app:met_floatingLabelText="@string/name"
app:met_maxCharacters="20"/>
app:met_maxCharacters="20" />
<com.rengwuxian.materialedittext.MaterialEditText
<org.mariotaku.twidere.view.themed.ThemedAccentMaterialEditText
android:id="@+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -234,9 +229,9 @@
app:met_baseColor="?android:textColorPrimary"
app:met_floatingLabel="normal"
app:met_floatingLabelText="@string/description"
app:met_maxCharacters="160"/>
app:met_maxCharacters="160" />
<com.rengwuxian.materialedittext.MaterialEditText
<org.mariotaku.twidere.view.themed.ThemedAccentMaterialEditText
android:id="@+id/location"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -245,9 +240,9 @@
app:met_baseColor="?android:textColorPrimary"
app:met_floatingLabel="normal"
app:met_floatingLabelText="@string/location"
app:met_maxCharacters="30"/>
app:met_maxCharacters="30" />
<com.rengwuxian.materialedittext.MaterialEditText
<org.mariotaku.twidere.view.themed.ThemedAccentMaterialEditText
android:id="@+id/url"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -256,7 +251,7 @@
app:met_baseColor="?android:textColorPrimary"
app:met_floatingLabel="normal"
app:met_floatingLabelText="@string/url"
app:met_maxCharacters="100"/>
app:met_maxCharacters="100" />
</LinearLayout>
</android.support.v7.widget.CardView>
@ -289,7 +284,7 @@
android:id="@+id/link_color"
android:layout_width="@dimen/element_size_normal"
android:layout_height="@dimen/element_size_normal"
android:layout_weight="0"/>
android:layout_weight="0" />
<TextView
android:layout_width="match_parent"
@ -300,7 +295,7 @@
android:textAllCaps="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:textColorPrimary"
android:textStyle="bold"/>
android:textStyle="bold" />
</LinearLayout>
@ -317,7 +312,7 @@
android:id="@+id/background_color"
android:layout_width="@dimen/element_size_normal"
android:layout_height="@dimen/element_size_normal"
android:layout_weight="0"/>
android:layout_weight="0" />
<TextView
android:layout_width="match_parent"
@ -328,7 +323,7 @@
android:textAllCaps="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:textColorPrimary"
android:textStyle="bold"/>
android:textStyle="bold" />
</LinearLayout>
@ -350,7 +345,7 @@
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
android:layout_gravity="center" />
</FrameLayout>
</org.mariotaku.twidere.view.TintedStatusFrameLayout>
</FrameLayout>

View File

@ -30,6 +30,7 @@
android:layout_marginRight="@dimen/element_spacing_normal"
android:layout_marginTop="@dimen/element_spacing_small"
app:cardBackgroundColor="?cardItemBackgroundColor"
tools:context=".adapter.ParcelableUsersAdapter"
app:cardCornerRadius="2dp"
app:cardElevation="2dp">
@ -44,8 +45,7 @@
android:paddingBottom="@dimen/element_spacing_small"
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_normal"
android:paddingTop="@dimen/element_spacing_small"
tools:context=".adapter.ParcelableUsersAdapter">
android:paddingTop="@dimen/element_spacing_small">
<RelativeLayout
android:id="@+id/profile_container"

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
<?xml version="1.0" encoding="utf-8"?><!--
~ Twidere - Twitter client for Android
~
~ Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
@ -18,105 +17,124 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<org.mariotaku.twidere.view.ColorLabelLinearLayout
android:id="@+id/content"
<android.support.v7.widget.CardView
android:id="@+id/card"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="@dimen/element_spacing_small"
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_normal"
android:paddingTop="@dimen/element_spacing_small"
tools:context=".adapter.ParcelableUserListsAdapter">
android:layout_marginBottom="@dimen/element_spacing_small"
android:layout_marginLeft="@dimen/element_spacing_normal"
android:layout_marginRight="@dimen/element_spacing_normal"
tools:context=".adapter.ParcelableUserListsAdapter"
android:layout_marginTop="@dimen/element_spacing_small"
app:cardBackgroundColor="?cardItemBackgroundColor"
app:cardCornerRadius="2dp"
app:cardElevation="2dp">
<LinearLayout
android:id="@+id/profile_container"
<org.mariotaku.twidere.view.ColorLabelLinearLayout
android:id="@+id/item_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingBottom="@dimen/element_spacing_normal"
android:background="?selectableItemBackground"
android:focusable="true"
android:focusableInTouchMode="false"
android:orientation="vertical"
android:paddingBottom="@dimen/element_spacing_small"
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_xlarge"
android:paddingTop="@dimen/element_spacing_normal">
<org.mariotaku.twidere.view.ShapedImageView
android:id="@+id/profile_image"
style="?profileImageStyle"
android:layout_width="@dimen/icon_size_card_list_item"
android:layout_height="@dimen/icon_size_card_list_item"
android:layout_weight="0"
android:contentDescription="@string/profile_image"
android:scaleType="fitCenter"/>
android:paddingRight="@dimen/element_spacing_normal"
android:paddingTop="@dimen/element_spacing_small">
<LinearLayout
android:layout_width="wrap_content"
android:id="@+id/profile_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingLeft="@dimen/element_spacing_normal">
android:orientation="horizontal"
android:paddingBottom="@dimen/element_spacing_normal"
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_xlarge"
android:paddingTop="@dimen/element_spacing_normal">
<TextView
android:id="@+id/name"
<org.mariotaku.twidere.view.ShapedImageView
android:id="@+id/profile_image"
style="?profileImageStyle"
android:layout_width="@dimen/icon_size_card_list_item"
android:layout_height="@dimen/icon_size_card_list_item"
android:layout_weight="0"
android:contentDescription="@string/profile_image"
android:scaleType="fitCenter" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorPrimary"
android:textStyle="bold"/>
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingLeft="@dimen/element_spacing_normal">
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorPrimary"
android:textStyle="bold" />
<TextView
android:id="@+id/created_by"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary" />
</LinearLayout>
</LinearLayout>
<View
android:id="@+id/divider"
android:layout_width="match_parent"
android:visibility="gone"
android:layout_height="0.2dp"
android:background="#40808080" />
<TextView
android:id="@+id/description"
android:layout_width="match_parent"
android:visibility="gone"
android:layout_height="wrap_content"
android:padding="@dimen/element_spacing_normal"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="@dimen/element_spacing_normal">
<TextView
android:id="@+id/created_by"
android:layout_width="match_parent"
android:id="@+id/members_count"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:drawableLeft="@drawable/ic_indicator_following"
android:drawablePadding="@dimen/element_spacing_small"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"/>
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="@+id/subscribers_count"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:drawableLeft="@drawable/ic_indicator_followers"
android:drawablePadding="@dimen/element_spacing_small"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
</LinearLayout>
<View
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="0.2dp"
android:background="#40808080"/>
<TextView
android:id="@+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/element_spacing_normal"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="@dimen/element_spacing_normal">
<TextView
android:id="@+id/members_count"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:drawableLeft="@drawable/ic_indicator_following"
android:drawablePadding="@dimen/element_spacing_small"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"/>
<TextView
android:id="@+id/subscribers_count"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:drawableLeft="@drawable/ic_indicator_followers"
android:drawablePadding="@dimen/element_spacing_small"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"/>
</LinearLayout>
</org.mariotaku.twidere.view.ColorLabelLinearLayout>
</org.mariotaku.twidere.view.ColorLabelLinearLayout>
</android.support.v7.widget.CardView>

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
<?xml version="1.0" encoding="utf-8"?><!--
~ Twidere - Twitter client for Android
~
~ Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
@ -19,15 +18,16 @@
-->
<org.mariotaku.twidere.view.ColorLabelFrameLayout
android:id="@+id/content"
android:id="@+id/item_content"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
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_marginTop="@dimen/element_spacing_small"
android:paddingBottom="@dimen/element_spacing_small"
android:background="?selectableItemBackground"
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="@dimen/element_spacing_normal"
android:paddingTop="@dimen/element_spacing_small"
tools:context=".adapter.ParcelableUsersAdapter">
<RelativeLayout
@ -47,7 +47,7 @@
android:layout_alignParentTop="true"
android:layout_marginRight="@dimen/element_spacing_normal"
android:contentDescription="@string/profile_image"
android:scaleType="fitCenter"/>
android:scaleType="fitCenter" />
<FrameLayout
android:id="@+id/name_frame"
@ -73,7 +73,7 @@
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorPrimary"
android:textStyle="bold"/>
android:textStyle="bold" />
<org.mariotaku.twidere.view.HandleSpanClickTextView
android:id="@+id/created_by"
@ -83,7 +83,7 @@
android:paddingRight="4dp"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"/>
android:textColor="?android:attr/textColorSecondary" />
</LinearLayout>
</FrameLayout>
@ -95,7 +95,7 @@
android:layout_below="@id/name_frame"
android:paddingTop="@dimen/element_spacing_small"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"/>
android:textColor="?android:attr/textColorSecondary" />
<LinearLayout
android:layout_width="match_parent"
@ -113,7 +113,7 @@
android:drawableLeft="@drawable/ic_indicator_following"
android:drawablePadding="4dp"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"/>
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="@+id/subscribers_count"
@ -123,7 +123,7 @@
android:drawableLeft="@drawable/ic_indicator_followers"
android:drawablePadding="4dp"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"/>
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
</RelativeLayout>

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
<?xml version="1.0" encoding="utf-8"?><!--
~ Twidere - Twitter client for Android
~
~ Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
@ -18,13 +17,13 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="8dp">
<EditText
<org.mariotaku.twidere.view.themed.ThemedAccentMaterialEditText
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -32,9 +31,13 @@
android:hint="@string/name"
android:inputType="text"
android:maxLength="20"
android:singleLine="true"/>
android:singleLine="true"
app:met_baseColor="?android:textColorPrimary"
app:met_floatingLabel="normal"
app:met_floatingLabelText="@string/name"
app:met_maxCharacters="20" />
<EditText
<org.mariotaku.twidere.view.themed.ThemedAccentMaterialEditText
android:id="@+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -42,18 +45,22 @@
android:gravity="top"
android:hint="@string/description"
android:inputType="textMultiLine"
android:maxLength="160"
android:minLines="3"
android:singleLine="false"/>
android:singleLine="false"
app:met_baseColor="?android:textColorPrimary"
app:met_floatingLabel="normal"
app:met_floatingLabelText="@string/description"
app:met_maxCharacters="160" />
<CheckBox
android:id="@+id/is_public"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/name"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_alignTop="@+id/name"
android:checked="true"
android:singleLine="true"
android:text="@string/is_public"/>
android:text="@string/is_public" />
</RelativeLayout>

View File

@ -20,7 +20,7 @@
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<org.mariotaku.twidere.view.themed.TintThemedProgressWheel
<org.mariotaku.twidere.view.themed.ThemedAccentProgressWheel
android:id="@+id/load_progress"
android:layout_width="@dimen/element_size_normal"
android:layout_height="@dimen/element_size_normal"

View File

@ -17,7 +17,7 @@
<item
android:id="@id/edit"
android:icon="@drawable/ic_action_edit"
android:title="@string/edit_profile"
android:title="@string/edit_details"
android:visible="false" />
<item
android:id="@id/add"

View File

@ -344,6 +344,7 @@
<string name="hashtag">Hashtag</string>
<string name="links">Links</string>
<string name="edit_profile">Edit profile</string>
<string name="edit_details">Edit details</string>
<string name="display_sensitive_contents">Display sensitive contents</string>
<string name="display_sensitive_contents_summary">Display sensitive contents without notice in timeline</string>
<string name="sensitive_content_warning">This tweet may have sensitive content, continue?</string>