1
0
mirror of https://github.com/TwidereProject/Twidere-Android synced 2025-02-12 17:50:38 +01:00

changed statuses count to listed count in profile page

improved gesture in user profile drawer
This commit is contained in:
Mariotaku Lee 2014-12-01 17:15:20 +08:00
parent b47b7c7d3b
commit 3c7b636b42
15 changed files with 369 additions and 277 deletions

View File

@ -28,7 +28,7 @@ package org.mariotaku.twidere;
public interface Constants extends TwidereConstants { public interface Constants extends TwidereConstants {
public static final String DATABASES_NAME = "twidere.sqlite"; public static final String DATABASES_NAME = "twidere.sqlite";
public static final int DATABASES_VERSION = 71; public static final int DATABASES_VERSION = 72;
public static final int MENU_GROUP_STATUS_EXTENSION = 10; public static final int MENU_GROUP_STATUS_EXTENSION = 10;
public static final int MENU_GROUP_COMPOSE_EXTENSION = 11; public static final int MENU_GROUP_COMPOSE_EXTENSION = 11;

View File

@ -31,10 +31,12 @@ import android.database.Cursor;
import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuff.Mode;
import android.graphics.Rect; import android.graphics.Rect;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.ActivityOptionsCompat;
import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager.LoaderCallbacks; import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader; import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader; import android.support.v4.content.Loader;
import android.support.v4.util.Pair;
import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.Adapter; import android.support.v7.widget.RecyclerView.Adapter;
@ -181,9 +183,11 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement
final OptionItem option = (OptionItem) item; final OptionItem option = (OptionItem) item;
switch (option.id) { switch (option.id) {
case MENU_VIEW_PROFILE: { case MENU_VIEW_PROFILE: {
openUserProfile(getActivity(), account.account_id, account.account_id, final FragmentActivity activity = getActivity();
account.screen_name, null); final ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(activity,
closeAccountsDrawer(); new Pair<View, String>(mAccountProfileImageView, UserProfileFragment.TRANSITION_NAME_PROFILE_IMAGE));
openUserProfile(activity, account.account_id, account.account_id, account.screen_name,
options.toBundle());
break; break;
} }
case MENU_SEARCH: { case MENU_SEARCH: {
@ -198,22 +202,18 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement
} }
case MENU_STATUSES: { case MENU_STATUSES: {
openUserTimeline(getActivity(), account.account_id, account.account_id, account.screen_name); openUserTimeline(getActivity(), account.account_id, account.account_id, account.screen_name);
closeAccountsDrawer();
break; break;
} }
case MENU_FAVORITES: { case MENU_FAVORITES: {
openUserFavorites(getActivity(), account.account_id, account.account_id, account.screen_name); openUserFavorites(getActivity(), account.account_id, account.account_id, account.screen_name);
closeAccountsDrawer();
break; break;
} }
case MENU_LISTS: { case MENU_LISTS: {
openUserLists(getActivity(), account.account_id, account.account_id, account.screen_name); openUserLists(getActivity(), account.account_id, account.account_id, account.screen_name);
closeAccountsDrawer();
break; break;
} }
case MENU_LIST_MEMBERSHIPS: { case MENU_LIST_MEMBERSHIPS: {
openUserListMemberships(getActivity(), account.account_id, account.account_id, account.screen_name); openUserListMemberships(getActivity(), account.account_id, account.account_id, account.screen_name);
closeAccountsDrawer();
break; break;
} }
case MENU_EDIT: { case MENU_EDIT: {
@ -223,7 +223,6 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement
intent.setClass(getActivity(), UserProfileEditorActivity.class); intent.setClass(getActivity(), UserProfileEditorActivity.class);
intent.putExtras(bundle); intent.putExtras(bundle);
startActivity(intent); startActivity(intent);
closeAccountsDrawer();
break; break;
} }
} }

View File

@ -120,8 +120,15 @@ public class BaseSupportFragment extends Fragment implements IBaseFragment, Cons
@Override @Override
public void requestFitSystemWindows() { public void requestFitSystemWindows() {
final Activity activity = getActivity(); final Activity activity = getActivity();
if (!(activity instanceof SystemWindowsInsetsCallback)) return; final Fragment parentFragment = getParentFragment();
final SystemWindowsInsetsCallback callback = (SystemWindowsInsetsCallback) activity; 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(); final Rect insets = new Rect();
if (callback.getSystemWindowsInsets(insets)) { if (callback.getSystemWindowsInsets(insets)) {
fitSystemWindows(insets); fitSystemWindows(insets);

View File

@ -123,8 +123,15 @@ public class BaseSupportListFragment extends ListFragment implements IBaseFragme
@Override @Override
public void requestFitSystemWindows() { public void requestFitSystemWindows() {
final Activity activity = getActivity(); final Activity activity = getActivity();
if (!(activity instanceof SystemWindowsInsetsCallback)) return; final Fragment parentFragment = getParentFragment();
final SystemWindowsInsetsCallback callback = (SystemWindowsInsetsCallback) activity; 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(); final Rect insets = new Rect();
if (callback.getSystemWindowsInsets(insets)) { if (callback.getSystemWindowsInsets(insets)) {
fitSystemWindows(insets); fitSystemWindows(insets);

View File

@ -55,9 +55,17 @@ public class BaseSupportStaggeredGridFragment extends StaggeredGridFragment impl
@Override @Override
public void requestFitSystemWindows() { public void requestFitSystemWindows() {
final Activity activity = getActivity(); 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(); final Rect insets = new Rect();
if (activity instanceof SystemWindowsInsetsCallback if (callback.getSystemWindowsInsets(insets)) {
&& ((SystemWindowsInsetsCallback) activity).getSystemWindowsInsets(insets)) {
fitSystemWindows(insets); fitSystemWindows(insets);
} }
} }

View File

@ -87,6 +87,7 @@ import org.mariotaku.twidere.activity.support.LinkHandlerActivity;
import org.mariotaku.twidere.activity.support.UserListSelectorActivity; import org.mariotaku.twidere.activity.support.UserListSelectorActivity;
import org.mariotaku.twidere.activity.support.UserProfileEditorActivity; import org.mariotaku.twidere.activity.support.UserProfileEditorActivity;
import org.mariotaku.twidere.adapter.support.SupportTabsAdapter; import org.mariotaku.twidere.adapter.support.SupportTabsAdapter;
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback;
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback; import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback;
import org.mariotaku.twidere.loader.support.ParcelableUserLoader; import org.mariotaku.twidere.loader.support.ParcelableUserLoader;
import org.mariotaku.twidere.model.ParcelableUser; import org.mariotaku.twidere.model.ParcelableUser;
@ -142,15 +143,15 @@ import static org.mariotaku.twidere.util.Utils.openStatus;
import static org.mariotaku.twidere.util.Utils.openTweetSearch; import static org.mariotaku.twidere.util.Utils.openTweetSearch;
import static org.mariotaku.twidere.util.Utils.openUserFollowers; import static org.mariotaku.twidere.util.Utils.openUserFollowers;
import static org.mariotaku.twidere.util.Utils.openUserFriends; import static org.mariotaku.twidere.util.Utils.openUserFriends;
import static org.mariotaku.twidere.util.Utils.openUserLists;
import static org.mariotaku.twidere.util.Utils.openUserProfile; import static org.mariotaku.twidere.util.Utils.openUserProfile;
import static org.mariotaku.twidere.util.Utils.openUserTimeline;
import static org.mariotaku.twidere.util.Utils.setMenuItemAvailability; import static org.mariotaku.twidere.util.Utils.setMenuItemAvailability;
import static org.mariotaku.twidere.util.Utils.showInfoMessage; import static org.mariotaku.twidere.util.Utils.showInfoMessage;
public class UserProfileFragment extends BaseSupportFragment implements OnClickListener, public class UserProfileFragment extends BaseSupportFragment implements OnClickListener,
OnMenuItemClickListener, OnLinkClickListener, OnSizeChangedListener, OnMenuItemClickListener, OnLinkClickListener, OnSizeChangedListener,
OnSharedPreferenceChangeListener, OnTouchListener, ImageLoadingListener, DrawerCallback, OnSharedPreferenceChangeListener, OnTouchListener, ImageLoadingListener, DrawerCallback,
SupportFragmentCallback { SupportFragmentCallback, SystemWindowsInsetsCallback {
public static final String TRANSITION_NAME_PROFILE_IMAGE = "profile_image"; public static final String TRANSITION_NAME_PROFILE_IMAGE = "profile_image";
public static final String TRANSITION_NAME_PROFILE_TYPE = "profile_type"; public static final String TRANSITION_NAME_PROFILE_TYPE = "profile_type";
@ -164,8 +165,8 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
private ImageView mProfileTypeView; private ImageView mProfileTypeView;
private ProfileBannerImageView mProfileBannerView; private ProfileBannerImageView mProfileBannerView;
private TextView mNameView, mScreenNameView, mDescriptionView, mLocationView, mURLView, mCreatedAtView, private TextView mNameView, mScreenNameView, mDescriptionView, mLocationView, mURLView, mCreatedAtView,
mTweetCount, mFollowersCount, mFriendsCount, mErrorMessageView; mListedCount, mFollowersCount, mFriendsCount, mErrorMessageView;
private View mDescriptionContainer, mLocationContainer, mURLContainer, mTweetsContainer, mFollowersContainer, private View mDescriptionContainer, mLocationContainer, mURLContainer, mListedContainer, mFollowersContainer,
mFriendsContainer; mFriendsContainer;
private Button mRetryButton; private Button mRetryButton;
private ColorLabelLinearLayout mProfileNameContainer; private ColorLabelLinearLayout mProfileNameContainer;
@ -182,16 +183,6 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
private Relationship mRelationship; private Relationship mRelationship;
private ParcelableUser mUser = null; private ParcelableUser mUser = null;
private Locale mLocale;
private boolean mGetUserInfoLoaderInitialized, mGetFriendShipLoaderInitialized;
private int mBannerWidth;
private ActionBarDrawable mActionBarBackground;
private Fragment mCurrentVisibleFragment;
private final BroadcastReceiver mStatusReceiver = new BroadcastReceiver() { private final BroadcastReceiver mStatusReceiver = new BroadcastReceiver() {
@Override @Override
@ -227,7 +218,6 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
} }
} }
}; };
private final LoaderCallbacks<SingleResponse<ParcelableUser>> mUserInfoLoaderCallbacks = new LoaderCallbacks<SingleResponse<ParcelableUser>>() { private final LoaderCallbacks<SingleResponse<ParcelableUser>> mUserInfoLoaderCallbacks = new LoaderCallbacks<SingleResponse<ParcelableUser>>() {
@Override @Override
@ -293,7 +283,6 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
} }
}; };
private final LoaderCallbacks<SingleResponse<Relationship>> mFriendshipLoaderCallbacks = new LoaderCallbacks<SingleResponse<Relationship>>() { private final LoaderCallbacks<SingleResponse<Relationship>> mFriendshipLoaderCallbacks = new LoaderCallbacks<SingleResponse<Relationship>>() {
@Override @Override
@ -338,6 +327,11 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
} }
}; };
private Locale mLocale;
private boolean mGetUserInfoLoaderInitialized, mGetFriendShipLoaderInitialized;
private int mBannerWidth;
private ActionBarDrawable mActionBarBackground;
private Fragment mCurrentVisibleFragment;
public void displayUser(final ParcelableUser user) { public void displayUser(final ParcelableUser user) {
mRelationship = null; mRelationship = null;
@ -383,7 +377,7 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
final int dailyTweets = Math.round(user.statuses_count / Math.max(1, daysSinceCreated)); final int dailyTweets = Math.round(user.statuses_count / Math.max(1, daysSinceCreated));
mCreatedAtView.setText(res.getQuantityString(R.plurals.created_at_with_N_tweets_per_day, dailyTweets, mCreatedAtView.setText(res.getQuantityString(R.plurals.created_at_with_N_tweets_per_day, dailyTweets,
createdAt, dailyTweets)); createdAt, dailyTweets));
mTweetCount.setText(getLocalizedNumber(mLocale, user.statuses_count)); mListedCount.setText(getLocalizedNumber(mLocale, user.listed_count));
mFollowersCount.setText(getLocalizedNumber(mLocale, user.followers_count)); mFollowersCount.setText(getLocalizedNumber(mLocale, user.followers_count));
mFriendsCount.setText(getLocalizedNumber(mLocale, user.friends_count)); mFriendsCount.setText(getLocalizedNumber(mLocale, user.friends_count));
if (userColor != 0) { if (userColor != 0) {
@ -454,54 +448,6 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
mUserProfileContent.setDrawColor(drawColor); mUserProfileContent.setDrawColor(drawColor);
} }
@Override
public void onActivityCreated(final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
getSharedPreferences(USER_COLOR_PREFERENCES_NAME, Context.MODE_PRIVATE)
.registerOnSharedPreferenceChangeListener(this);
getSharedPreferences(USER_NICKNAME_PREFERENCES_NAME, Context.MODE_PRIVATE)
.registerOnSharedPreferenceChangeListener(this);
mLocale = getResources().getConfiguration().locale;
final Bundle args = getArguments();
long accountId = -1, userId = -1;
String screenName = null;
if (savedInstanceState != null) {
args.putAll(savedInstanceState);
} else {
accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
userId = args.getLong(EXTRA_USER_ID, -1);
screenName = args.getString(EXTRA_SCREEN_NAME);
}
mProfileImageLoader = getApplication().getImageLoaderWrapper();
final FragmentActivity activity = getActivity();
ViewCompat.setTransitionName(mProfileImageView, TRANSITION_NAME_PROFILE_IMAGE);
ViewCompat.setTransitionName(mProfileTypeView, TRANSITION_NAME_PROFILE_TYPE);
mUserProfileDrawer.setDrawerCallback(this);
mPagerAdapter = new SupportTabsAdapter(activity, getChildFragmentManager());
mViewPager.setAdapter(mPagerAdapter);
mPagerIndicator.setViewPager(mViewPager);
mProfileImageView.setOnClickListener(this);
mProfileBannerView.setOnClickListener(this);
mTweetsContainer.setOnClickListener(this);
mFollowersContainer.setOnClickListener(this);
mFriendsContainer.setOnClickListener(this);
mRetryButton.setOnClickListener(this);
mProfileBannerView.setOnSizeChangedListener(this);
mProfileBannerSpace.setOnTouchListener(this);
getUserInfo(accountId, userId, screenName, false);
setupBaseActionBar();
setupUserPages();
}
private void setupUserPages() { private void setupUserPages() {
final Context context = getActivity(); final Context context = getActivity();
final Bundle args = getArguments(), tabArgs = new Bundle(); final Bundle args = getArguments(), tabArgs = new Bundle();
@ -519,8 +465,9 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
} }
mPagerAdapter.addTab(UserTimelineFragment.class, tabArgs, getString(R.string.statuses), null, 0); mPagerAdapter.addTab(UserTimelineFragment.class, tabArgs, getString(R.string.statuses), null, 0);
if (Utils.isOfficialKeyAccount(context, accountId)) { if (Utils.isOfficialKeyAccount(context, accountId)) {
mPagerAdapter.addTab(UserMediaTimelineFragment.class, tabArgs, getString(R.string.media), null, 0); mPagerAdapter.addTab(UserMediaTimelineFragment.class, tabArgs, getString(R.string.media), null, 1);
} }
mPagerAdapter.addTab(UserFavoritesFragment.class, tabArgs, getString(R.string.favorites), null, 2);
mPagerIndicator.notifyDataSetChanged(); mPagerIndicator.notifyDataSetChanged();
} }
@ -544,6 +491,7 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
} }
mActionBarBackground.setColor(color); mActionBarBackground.setColor(color);
mUserProfileContent.setColor(color); mUserProfileContent.setColor(color);
mPagerIndicator.setIndicatorColor(color);
} }
private boolean isUucky(long userId, String screenName, Parcelable parcelable) { private boolean isUucky(long userId, String screenName, Parcelable parcelable) {
@ -593,6 +541,111 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
} }
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_user_profile, container, false);
}
@Override
public void onActivityCreated(final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
getSharedPreferences(USER_COLOR_PREFERENCES_NAME, Context.MODE_PRIVATE)
.registerOnSharedPreferenceChangeListener(this);
getSharedPreferences(USER_NICKNAME_PREFERENCES_NAME, Context.MODE_PRIVATE)
.registerOnSharedPreferenceChangeListener(this);
mLocale = getResources().getConfiguration().locale;
final Bundle args = getArguments();
long accountId = -1, userId = -1;
String screenName = null;
if (savedInstanceState != null) {
args.putAll(savedInstanceState);
} else {
accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
userId = args.getLong(EXTRA_USER_ID, -1);
screenName = args.getString(EXTRA_SCREEN_NAME);
}
mProfileImageLoader = getApplication().getImageLoaderWrapper();
final FragmentActivity activity = getActivity();
ViewCompat.setTransitionName(mProfileImageView, TRANSITION_NAME_PROFILE_IMAGE);
ViewCompat.setTransitionName(mProfileTypeView, TRANSITION_NAME_PROFILE_TYPE);
mUserProfileDrawer.setDrawerCallback(this);
mPagerAdapter = new SupportTabsAdapter(activity, getChildFragmentManager());
mViewPager.setAdapter(mPagerAdapter);
mPagerIndicator.setViewPager(mViewPager);
mProfileImageView.setOnClickListener(this);
mProfileBannerView.setOnClickListener(this);
mListedContainer.setOnClickListener(this);
mFollowersContainer.setOnClickListener(this);
mFriendsContainer.setOnClickListener(this);
mRetryButton.setOnClickListener(this);
mProfileBannerView.setOnSizeChangedListener(this);
mProfileBannerSpace.setOnTouchListener(this);
getUserInfo(accountId, userId, screenName, false);
setupBaseActionBar();
// updateScrollOffset(0);
setupUserPages();
}
@Override
public void onStart() {
super.onStart();
final IntentFilter filter = new IntentFilter(BROADCAST_TASK_STATE_CHANGED);
filter.addAction(BROADCAST_FRIENDSHIP_CHANGED);
filter.addAction(BROADCAST_PROFILE_UPDATED);
filter.addAction(BROADCAST_PROFILE_IMAGE_UPDATED);
filter.addAction(BROADCAST_PROFILE_BANNER_UPDATED);
registerReceiver(mStatusReceiver, filter);
}
@Override
public void onSaveInstanceState(final Bundle outState) {
outState.putParcelable(EXTRA_USER, mUser);
super.onSaveInstanceState(outState);
}
@Override
public void onStop() {
unregisterReceiver(mStatusReceiver);
super.onStop();
}
@Override
public void onDestroyView() {
mUser = null;
mRelationship = null;
final LoaderManager lm = getLoaderManager();
lm.destroyLoader(LOADER_ID_USER);
lm.destroyLoader(LOADER_ID_FRIENDSHIP);
super.onDestroyView();
}
@Override
public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
if (!shouldUseNativeMenu()) return;
inflater.inflate(R.menu.menu_user_profile, menu);
}
@Override
public void onPrepareOptionsMenu(final Menu menu) {
if (!shouldUseNativeMenu() || !menu.hasVisibleItems()) return;
setMenu(menu);
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
return handleMenuItemClick(item);
}
@Override @Override
public void onClick(final View view) { public void onClick(final View view) {
final FragmentActivity activity = getActivity(); final FragmentActivity activity = getActivity();
@ -614,8 +667,8 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
openImage(getActivity(), user.account_id, profile_banner_url + "/ipad_retina", false); openImage(getActivity(), user.account_id, profile_banner_url + "/ipad_retina", false);
break; break;
} }
case R.id.tweets_container: { case R.id.listed_container: {
openUserTimeline(getActivity(), user.account_id, user.id, user.screen_name); openUserLists(getActivity(), user.account_id, user.id, user.screen_name);
break; break;
} }
case R.id.followers_container: { case R.id.followers_container: {
@ -635,28 +688,6 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
} }
@Override
public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
if (!shouldUseNativeMenu()) return;
inflater.inflate(R.menu.menu_user_profile, menu);
}
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_user_profile, container, false);
}
@Override
public void onDestroyView() {
mUser = null;
mRelationship = null;
final LoaderManager lm = getLoaderManager();
lm.destroyLoader(LOADER_ID_USER);
lm.destroyLoader(LOADER_ID_FRIENDSHIP);
super.onDestroyView();
}
@Override @Override
public void onLinkClick(final String link, final String orig, final long account_id, final int type, public void onLinkClick(final String link, final String orig, final long account_id, final int type,
final boolean sensitive) { final boolean sensitive) {
@ -703,23 +734,6 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
} }
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
return handleMenuItemClick(item);
}
@Override
public void onPrepareOptionsMenu(final Menu menu) {
if (!shouldUseNativeMenu() || !menu.hasVisibleItems()) return;
setMenu(menu);
}
@Override
public void onSaveInstanceState(final Bundle outState) {
outState.putParcelable(EXTRA_USER, mUser);
super.onSaveInstanceState(outState);
}
@Override @Override
public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) { public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) {
if (mUser == null || !ParseUtils.parseString(mUser.id).equals(key)) return; if (mUser == null || !ParseUtils.parseString(mUser.id).equals(key)) return;
@ -734,48 +748,11 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
} }
} }
@Override
public void onStart() {
super.onStart();
final IntentFilter filter = new IntentFilter(BROADCAST_TASK_STATE_CHANGED);
filter.addAction(BROADCAST_FRIENDSHIP_CHANGED);
filter.addAction(BROADCAST_PROFILE_UPDATED);
filter.addAction(BROADCAST_PROFILE_IMAGE_UPDATED);
filter.addAction(BROADCAST_PROFILE_BANNER_UPDATED);
registerReceiver(mStatusReceiver, filter);
}
@Override
public void onStop() {
unregisterReceiver(mStatusReceiver);
super.onStop();
}
@Override @Override
public boolean onTouch(final View v, final MotionEvent event) { public boolean onTouch(final View v, final MotionEvent event) {
return mProfileBannerView.dispatchTouchEvent(event); return mProfileBannerView.dispatchTouchEvent(event);
} }
@Override
protected void fitSystemWindows(Rect insets) {
super.fitSystemWindows(insets);
final View view = getView();
if (view != null) {
final View progress = view.findViewById(R.id.progress_container);
progress.setPadding(insets.left, insets.top, insets.right, insets.bottom);
}
mErrorRetryContainer.setPadding(insets.left, insets.top, insets.right, insets.bottom);
mUserProfileDrawer.setPadding(insets.left, insets.top, insets.right, insets.bottom);
mUserProfileDrawer.setClipToPadding(false);
final int bannerHeight = mProfileBannerView.getHeight();
if (bannerHeight != 0) {
final ViewGroup.LayoutParams params = mProfileBannerSpace.getLayoutParams();
params.height = bannerHeight - insets.top;
mProfileBannerSpace.setLayoutParams(params);
mProfileBannerSpace.requestLayout();
}
}
@Override @Override
public void onViewCreated(final View view, final Bundle savedInstanceState) { public void onViewCreated(final View view, final Bundle savedInstanceState) {
final Context context = view.getContext(); final Context context = view.getContext();
@ -796,8 +773,8 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
mLocationView = (TextView) headerView.findViewById(R.id.location); mLocationView = (TextView) headerView.findViewById(R.id.location);
mURLView = (TextView) headerView.findViewById(R.id.url); mURLView = (TextView) headerView.findViewById(R.id.url);
mCreatedAtView = (TextView) headerView.findViewById(R.id.created_at); mCreatedAtView = (TextView) headerView.findViewById(R.id.created_at);
mTweetsContainer = headerView.findViewById(R.id.tweets_container); mListedContainer = headerView.findViewById(R.id.listed_container);
mTweetCount = (TextView) headerView.findViewById(R.id.statuses_count); mListedCount = (TextView) headerView.findViewById(R.id.listed_count);
mFollowersContainer = headerView.findViewById(R.id.followers_container); mFollowersContainer = headerView.findViewById(R.id.followers_container);
mFollowersCount = (TextView) headerView.findViewById(R.id.followers_count); mFollowersCount = (TextView) headerView.findViewById(R.id.followers_count);
mFriendsContainer = headerView.findViewById(R.id.friends_container); mFriendsContainer = headerView.findViewById(R.id.friends_container);
@ -816,6 +793,26 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
ThemeUtils.applyThemeAlphaToDrawable(context, cardView.getBackground()); ThemeUtils.applyThemeAlphaToDrawable(context, cardView.getBackground());
} }
@Override
protected void fitSystemWindows(Rect insets) {
super.fitSystemWindows(insets);
final View view = getView();
if (view != null) {
final View progress = view.findViewById(R.id.progress_container);
progress.setPadding(insets.left, insets.top, insets.right, insets.bottom);
}
mErrorRetryContainer.setPadding(insets.left, insets.top, insets.right, insets.bottom);
mUserProfileDrawer.setPadding(insets.left, insets.top, insets.right, insets.bottom);
mUserProfileDrawer.setClipToPadding(false);
final int bannerHeight = mProfileBannerView.getHeight();
if (bannerHeight != 0) {
final ViewGroup.LayoutParams params = mProfileBannerSpace.getLayoutParams();
params.height = bannerHeight - insets.top;
mProfileBannerSpace.setLayoutParams(params);
mProfileBannerSpace.requestLayout();
}
}
private void getFriendship() { private void getFriendship() {
final ParcelableUser user = mUser; final ParcelableUser user = mUser;
final LoaderManager lm = getLoaderManager(); final LoaderManager lm = getLoaderManager();
@ -1087,8 +1084,11 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
@Override @Override
public boolean isScrollContent(float x, float y) { public boolean isScrollContent(float x, float y) {
final Fragment fragment = mCurrentVisibleFragment; final ViewPager v = mViewPager;
return fragment instanceof DrawerCallback && ((DrawerCallback) fragment).isScrollContent(x, y); final int[] location = new int[2];
v.getLocationOnScreen(location);
return x >= location[0] && x <= location[0] + v.getWidth()
&& y >= location[1] && y <= location[1] + v.getHeight();
} }
@Override @Override
@ -1102,9 +1102,19 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
@Override @Override
public void topChanged(int top) { public void topChanged(int top) {
final UserProfileDrawer drawer = mUserProfileDrawer; final UserProfileDrawer drawer = mUserProfileDrawer;
final View space = mProfileBannerSpace; if (drawer == null) return;
if (drawer == null || space == null) return;
final int offset = drawer.getPaddingTop() - top; final int offset = drawer.getPaddingTop() - top;
updateScrollOffset(offset);
final Fragment fragment = mCurrentVisibleFragment;
if (fragment instanceof DrawerCallback) {
((DrawerCallback) fragment).topChanged(top);
}
}
private void updateScrollOffset(int offset) {
final View space = mProfileBannerSpace;
if (space == null) return;
final float factor = offset / (float) space.getHeight(); final float factor = offset / (float) space.getHeight();
final ProfileBannerImageView profileBannerView = mProfileBannerView; final ProfileBannerImageView profileBannerView = mProfileBannerView;
profileBannerView.setAlpha(1.0f - factor / 8f); profileBannerView.setAlpha(1.0f - factor / 8f);
@ -1115,11 +1125,6 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
mActionBarBackground.setFactor(factor); mActionBarBackground.setFactor(factor);
mUserProfileContent.setFactor(factor); mUserProfileContent.setFactor(factor);
} }
final Fragment fragment = mCurrentVisibleFragment;
if (fragment instanceof DrawerCallback) {
((DrawerCallback) fragment).topChanged(top);
}
} }
@Override @Override
@ -1142,6 +1147,11 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
return false; return false;
} }
@Override
public boolean getSystemWindowsInsets(Rect insets) {
return false;
}
static class FriendshipLoader extends AsyncTaskLoader<SingleResponse<Relationship>> { static class FriendshipLoader extends AsyncTaskLoader<SingleResponse<Relationship>> {
@ -1267,23 +1277,38 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
setColor(Color.TRANSPARENT); setColor(Color.TRANSPARENT);
} }
@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
mBounds.set(bounds);
}
@Override @Override
public void draw(Canvas canvas) { public void draw(Canvas canvas) {
canvas.drawRect(mBounds.left, mBounds.bottom - mLineSize, mBounds.right, canvas.drawRect(mBounds.left, mBounds.bottom - mLineSize, mBounds.right,
mBounds.bottom, mPaint); mBounds.bottom, mPaint);
} }
@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
mBounds.set(bounds);
}
private void updatePaint() {
mPaint.setColor(mColor);
mPaint.setAlpha(Color.alpha(mColor) * mAlpha / 0xFF);
invalidateSelf();
}
public int getColor() {
return mColor;
}
@Override @Override
public int getAlpha() { public int getAlpha() {
return mAlpha; return mAlpha;
} }
public void setColor(int color) {
mColor = color;
updatePaint();
}
@Override @Override
public void setAlpha(int alpha) { public void setAlpha(int alpha) {
mAlpha = alpha; mAlpha = alpha;
@ -1300,20 +1325,6 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
return PixelFormat.TRANSLUCENT; return PixelFormat.TRANSLUCENT;
} }
public void setColor(int color) {
mColor = color;
updatePaint();
}
private void updatePaint() {
mPaint.setColor(mColor);
mPaint.setAlpha(Color.alpha(mColor) * mAlpha / 0xFF);
invalidateSelf();
}
public int getColor() {
return mColor;
}
} }
} }
} }

View File

@ -72,7 +72,7 @@ public class ParcelableUser implements TwidereParcelable, Comparable<ParcelableU
public final String description_plain, name, screen_name, location, profile_image_url, profile_banner_url, url, public final String description_plain, name, screen_name, location, profile_image_url, profile_banner_url, url,
url_expanded, description_html, description_unescaped, description_expanded; url_expanded, description_html, description_unescaped, description_expanded;
public final int followers_count, friends_count, statuses_count, favorites_count; public final int followers_count, friends_count, statuses_count, favorites_count, listed_count;
public final boolean is_cache; public final boolean is_cache;
@ -101,6 +101,7 @@ public class ParcelableUser implements TwidereParcelable, Comparable<ParcelableU
friends_count = 0; friends_count = 0;
statuses_count = 0; statuses_count = 0;
favorites_count = 0; favorites_count = 0;
listed_count = 0;
is_cache = true; is_cache = true;
} }
@ -125,6 +126,7 @@ public class ParcelableUser implements TwidereParcelable, Comparable<ParcelableU
is_protected = cursor.getInt(cursor.getColumnIndex(CachedUsers.IS_PROTECTED)) == 1; is_protected = cursor.getInt(cursor.getColumnIndex(CachedUsers.IS_PROTECTED)) == 1;
is_verified = cursor.getInt(cursor.getColumnIndex(CachedUsers.IS_VERIFIED)) == 1; is_verified = cursor.getInt(cursor.getColumnIndex(CachedUsers.IS_VERIFIED)) == 1;
favorites_count = cursor.getInt(cursor.getColumnIndex(CachedUsers.FAVORITES_COUNT)); favorites_count = cursor.getInt(cursor.getColumnIndex(CachedUsers.FAVORITES_COUNT));
listed_count = cursor.getInt(cursor.getColumnIndex(CachedUsers.LISTED_COUNT));
followers_count = cursor.getInt(cursor.getColumnIndex(CachedUsers.FOLLOWERS_COUNT)); followers_count = cursor.getInt(cursor.getColumnIndex(CachedUsers.FOLLOWERS_COUNT));
friends_count = cursor.getInt(cursor.getColumnIndex(CachedUsers.FRIENDS_COUNT)); friends_count = cursor.getInt(cursor.getColumnIndex(CachedUsers.FRIENDS_COUNT));
statuses_count = cursor.getInt(cursor.getColumnIndex(CachedUsers.STATUSES_COUNT)); statuses_count = cursor.getInt(cursor.getColumnIndex(CachedUsers.STATUSES_COUNT));
@ -159,6 +161,7 @@ public class ParcelableUser implements TwidereParcelable, Comparable<ParcelableU
friends_count = in.readInt("friends_count"); friends_count = in.readInt("friends_count");
statuses_count = in.readInt("statuses_count"); statuses_count = in.readInt("statuses_count");
favorites_count = in.readInt("favorites_count"); favorites_count = in.readInt("favorites_count");
listed_count = in.readInt("listed_count");
is_cache = in.readBoolean("is_cache"); is_cache = in.readBoolean("is_cache");
description_html = in.readString("description_html"); description_html = in.readString("description_html");
description_expanded = in.readString("description_expanded"); description_expanded = in.readString("description_expanded");
@ -186,6 +189,7 @@ public class ParcelableUser implements TwidereParcelable, Comparable<ParcelableU
friends_count = in.readInt(); friends_count = in.readInt();
statuses_count = in.readInt(); statuses_count = in.readInt();
favorites_count = in.readInt(); favorites_count = in.readInt();
listed_count = in.readInt();
is_cache = in.readInt() == 1; is_cache = in.readInt() == 1;
description_html = in.readString(); description_html = in.readString();
description_expanded = in.readString(); description_expanded = in.readString();
@ -222,6 +226,7 @@ public class ParcelableUser implements TwidereParcelable, Comparable<ParcelableU
friends_count = user.getFriendsCount(); friends_count = user.getFriendsCount();
statuses_count = user.getStatusesCount(); statuses_count = user.getStatusesCount();
favorites_count = user.getFavouritesCount(); favorites_count = user.getFavouritesCount();
listed_count = user.getListedCount();
is_cache = false; is_cache = false;
is_following = user.isFollowing(); is_following = user.isFollowing();
description_unescaped = toPlainText(description_html); description_unescaped = toPlainText(description_html);
@ -294,6 +299,7 @@ public class ParcelableUser implements TwidereParcelable, Comparable<ParcelableU
out.writeInt("friends_count", friends_count); out.writeInt("friends_count", friends_count);
out.writeInt("statuses_count", statuses_count); out.writeInt("statuses_count", statuses_count);
out.writeInt("favorites_count", favorites_count); out.writeInt("favorites_count", favorites_count);
out.writeInt("listed_count", listed_count);
out.writeBoolean("is_cache", is_cache); out.writeBoolean("is_cache", is_cache);
out.writeString("description_html", description_html); out.writeString("description_html", description_html);
out.writeString("description_expanded", description_expanded); out.writeString("description_expanded", description_expanded);
@ -322,6 +328,7 @@ public class ParcelableUser implements TwidereParcelable, Comparable<ParcelableU
out.writeInt(friends_count); out.writeInt(friends_count);
out.writeInt(statuses_count); out.writeInt(statuses_count);
out.writeInt(favorites_count); out.writeInt(favorites_count);
out.writeInt(listed_count);
out.writeInt(is_cache ? 1 : 0); out.writeInt(is_cache ? 1 : 0);
out.writeString(description_html); out.writeString(description_html);
out.writeString(description_expanded); out.writeString(description_expanded);
@ -340,6 +347,7 @@ public class ParcelableUser implements TwidereParcelable, Comparable<ParcelableU
values.put(CachedUsers.CREATED_AT, user.created_at); values.put(CachedUsers.CREATED_AT, user.created_at);
values.put(CachedUsers.IS_PROTECTED, user.is_protected); values.put(CachedUsers.IS_PROTECTED, user.is_protected);
values.put(CachedUsers.IS_VERIFIED, user.is_verified); values.put(CachedUsers.IS_VERIFIED, user.is_verified);
values.put(CachedUsers.LISTED_COUNT, user.listed_count);
values.put(CachedUsers.FAVORITES_COUNT, user.favorites_count); values.put(CachedUsers.FAVORITES_COUNT, user.favorites_count);
values.put(CachedUsers.FOLLOWERS_COUNT, user.followers_count); values.put(CachedUsers.FOLLOWERS_COUNT, user.followers_count);
values.put(CachedUsers.FRIENDS_COUNT, user.friends_count); values.put(CachedUsers.FRIENDS_COUNT, user.friends_count);

View File

@ -239,6 +239,8 @@ public interface TweetStore {
public static final String FAVORITES_COUNT = "favorites_count"; public static final String FAVORITES_COUNT = "favorites_count";
public static final String LISTED_COUNT = "listed_count";
/** /**
* User's screen name of the status.<br> * User's screen name of the status.<br>
* Type: TEXT * Type: TEXT
@ -253,12 +255,12 @@ public interface TweetStore {
public static final String[] COLUMNS = new String[]{_ID, USER_ID, CREATED_AT, NAME, SCREEN_NAME, public static final String[] COLUMNS = new String[]{_ID, USER_ID, CREATED_AT, NAME, SCREEN_NAME,
DESCRIPTION_PLAIN, LOCATION, URL, PROFILE_IMAGE_URL, PROFILE_BANNER_URL, IS_PROTECTED, IS_VERIFIED, DESCRIPTION_PLAIN, LOCATION, URL, PROFILE_IMAGE_URL, PROFILE_BANNER_URL, IS_PROTECTED, IS_VERIFIED,
IS_FOLLOWING, FOLLOWERS_COUNT, FRIENDS_COUNT, STATUSES_COUNT, FAVORITES_COUNT, DESCRIPTION_HTML, IS_FOLLOWING, FOLLOWERS_COUNT, FRIENDS_COUNT, STATUSES_COUNT, FAVORITES_COUNT, LISTED_COUNT, DESCRIPTION_HTML,
DESCRIPTION_EXPANDED, URL_EXPANDED}; DESCRIPTION_EXPANDED, URL_EXPANDED};
public static final String[] TYPES = new String[]{TYPE_PRIMARY_KEY, TYPE_INT_UNIQUE, TYPE_INT, TYPE_TEXT, public static final String[] TYPES = new String[]{TYPE_PRIMARY_KEY, TYPE_INT_UNIQUE, TYPE_INT, TYPE_TEXT,
TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_BOOLEAN, TYPE_BOOLEAN, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_BOOLEAN, TYPE_BOOLEAN,
TYPE_BOOLEAN, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT}; TYPE_BOOLEAN, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT};
} }

View File

@ -139,6 +139,7 @@ public final class ContentValuesCreator implements TwidereConstants {
values.put(CachedUsers.FOLLOWERS_COUNT, user.getFollowersCount()); values.put(CachedUsers.FOLLOWERS_COUNT, user.getFollowersCount());
values.put(CachedUsers.FRIENDS_COUNT, user.getFriendsCount()); values.put(CachedUsers.FRIENDS_COUNT, user.getFriendsCount());
values.put(CachedUsers.STATUSES_COUNT, user.getStatusesCount()); values.put(CachedUsers.STATUSES_COUNT, user.getStatusesCount());
values.put(CachedUsers.LISTED_COUNT, user.getListedCount());
values.put(CachedUsers.LOCATION, user.getLocation()); values.put(CachedUsers.LOCATION, user.getLocation());
values.put(CachedUsers.DESCRIPTION_PLAIN, user.getDescription()); values.put(CachedUsers.DESCRIPTION_PLAIN, user.getDescription());
values.put(CachedUsers.DESCRIPTION_HTML, Utils.formatUserDescription(user)); values.put(CachedUsers.DESCRIPTION_HTML, Utils.formatUserDescription(user));

View File

@ -34,7 +34,8 @@ public class UserProfileDrawer extends ViewGroup {
private final DragCallback mDragCallback; private final DragCallback mDragCallback;
private DrawerCallback mDrawerCallback; private DrawerCallback mDrawerCallback;
private boolean mUsingDragHelper, mScrollingHeaderByGesture; private boolean mUsingDragHelper;
private boolean mScrollingHeaderByGesture, mScrollingContentCallback;
private boolean mTouchDown, mTouchingScrollableContent; private boolean mTouchDown, mTouchingScrollableContent;
private int mHeaderOffset; private int mHeaderOffset;
@ -73,6 +74,20 @@ public class UserProfileDrawer extends ViewGroup {
mScrollingHeaderByGesture = scrolling; mScrollingHeaderByGesture = scrolling;
} }
public void flingHeader(float velocity) {
if (mTouchDown) {
mScroller.abortAnimation();
return;
}
mScroller.fling(0, getHeaderTop(), 0, (int) velocity, 0, 0,
mContainer.getHeaderTopMinimum(), mContainer.getHeaderTopMaximum());
ViewCompat.postInvalidateOnAnimation(this);
}
private void flingCallback(float velocity) {
mDrawerCallback.fling(velocity);
}
@Override @Override
public void computeScroll() { public void computeScroll() {
boolean invalidate = mDragHelper.continueSettling(true); boolean invalidate = mDragHelper.continueSettling(true);
@ -88,28 +103,8 @@ public class UserProfileDrawer extends ViewGroup {
} }
} }
public void flingHeader(float velocity) {
if (mTouchDown) {
mScroller.abortAnimation();
return;
}
mScroller.fling(0, getHeaderTop(), 0, (int) velocity, 0, 0,
mContainer.getHeaderTopMinimum(), mContainer.getHeaderTopMaximum());
ViewCompat.postInvalidateOnAnimation(this);
}
@Override
protected void onFinishInflate() {
if (getChildCount() != 1) {
throw new IllegalArgumentException("Add subview by XML is not allowed.");
}
}
private void flingCallback(float velocity) {
mDrawerCallback.fling(velocity);
}
private void scrollByCallback(float dy) { private void scrollByCallback(float dy) {
setScrollingContentCallback(true);
mDrawerCallback.scrollBy(dy); mDrawerCallback.scrollBy(dy);
} }
@ -121,6 +116,13 @@ public class UserProfileDrawer extends ViewGroup {
mDrawerCallback.cancelTouch(); mDrawerCallback.cancelTouch();
} }
@Override
protected void onFinishInflate() {
if (getChildCount() != 1) {
throw new IllegalArgumentException("Add subview by XML is not allowed.");
}
}
private boolean canScrollCallback(float dy) { private boolean canScrollCallback(float dy) {
return mDrawerCallback.canScroll(dy); return mDrawerCallback.canScroll(dy);
} }
@ -140,7 +142,6 @@ public class UserProfileDrawer extends ViewGroup {
mTouchDown = true; mTouchDown = true;
mTouchingScrollableContent = isScrollContentCallback(ev.getX(), ev.getY()); mTouchingScrollableContent = isScrollContentCallback(ev.getX(), ev.getY());
mUsingDragHelper = false; mUsingDragHelper = false;
mScrollingHeaderByGesture = false;
break; break;
} }
case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_CANCEL:
@ -148,7 +149,6 @@ public class UserProfileDrawer extends ViewGroup {
mTouchDown = false; mTouchDown = false;
mTouchingScrollableContent = false; mTouchingScrollableContent = false;
mUsingDragHelper = false; mUsingDragHelper = false;
mScrollingHeaderByGesture = false;
} }
} }
mGestureDetector.onTouchEvent(ev); mGestureDetector.onTouchEvent(ev);
@ -172,6 +172,7 @@ public class UserProfileDrawer extends ViewGroup {
final int top = i == 0 ? mHeaderOffset + getPaddingTop() : getChildAt(i - 1).getBottom(); final int top = i == 0 ? mHeaderOffset + getPaddingTop() : getChildAt(i - 1).getBottom();
final int bottom = top + child.getMeasuredHeight(); final int bottom = top + child.getMeasuredHeight();
child.layout(left, top, right, bottom); child.layout(left, top, right, bottom);
notifyOffsetChanged();
} }
} }
@ -185,17 +186,6 @@ public class UserProfileDrawer extends ViewGroup {
return mContainer.getHeader(); return mContainer.getHeader();
} }
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final View child = getChildAt(0);
final int childWidthMeasureSpec = makeChildMeasureSpec(widthMeasureSpec, getPaddingLeft() + getPaddingRight());
final int childHeightMeasureSpec = makeChildMeasureSpec(heightMeasureSpec, getPaddingTop() + getPaddingBottom());
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public View getContent() { public View getContent() {
return mContainer.getContent(); return mContainer.getContent();
} }
@ -222,6 +212,17 @@ public class UserProfileDrawer extends ViewGroup {
return mContainer.getHeaderTopMinimum(); return mContainer.getHeaderTopMinimum();
} }
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final View child = getChildAt(0);
final int childWidthMeasureSpec = makeChildMeasureSpec(widthMeasureSpec, getPaddingLeft() + getPaddingRight());
final int childHeightMeasureSpec = makeChildMeasureSpec(heightMeasureSpec, getPaddingTop() + getPaddingBottom());
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
private boolean isTouchingScrollableContent() { private boolean isTouchingScrollableContent() {
return mTouchingScrollableContent; return mTouchingScrollableContent;
} }
@ -240,6 +241,18 @@ public class UserProfileDrawer extends ViewGroup {
return Math.abs(direction) > getDragTouchSlop() && Math.abs(direction) > Math.abs(other); return Math.abs(direction) > getDragTouchSlop() && Math.abs(direction) > Math.abs(other);
} }
private boolean isScrollingHeaderByHelper() {
return mDragCallback.isScrollingHeaderByHelper();
}
private boolean isScrollingContentCallback() {
return mScrollingContentCallback;
}
private void setScrollingContentCallback(boolean scrolling) {
mScrollingContentCallback = scrolling;
}
public static interface DrawerCallback { public static interface DrawerCallback {
void fling(float velocity); void fling(float velocity);
@ -260,7 +273,7 @@ public class UserProfileDrawer extends ViewGroup {
private final UserProfileDrawer mDrawer; private final UserProfileDrawer mDrawer;
private long mTime; private long mTime;
private float mDx, mDy, mVelocity; private float mDx, mDy, mVelocity;
private boolean mScrollingByHelper; private boolean mScrollingHeaderByHelper;
public DragCallback(UserProfileDrawer drawer) { public DragCallback(UserProfileDrawer drawer) {
mDrawer = drawer; mDrawer = drawer;
@ -275,7 +288,7 @@ public class UserProfileDrawer extends ViewGroup {
switch (state) { switch (state) {
case ViewDragHelper.STATE_SETTLING: case ViewDragHelper.STATE_SETTLING:
case ViewDragHelper.STATE_DRAGGING: { case ViewDragHelper.STATE_DRAGGING: {
mScrollingByHelper = false; mScrollingHeaderByHelper = false;
break; break;
} }
case ViewDragHelper.STATE_IDLE: { case ViewDragHelper.STATE_IDLE: {
@ -289,7 +302,7 @@ public class UserProfileDrawer extends ViewGroup {
mDx = Float.NaN; mDx = Float.NaN;
mDy = Float.NaN; mDy = Float.NaN;
mVelocity = Float.NaN; mVelocity = Float.NaN;
mScrollingByHelper = false; mScrollingHeaderByHelper = false;
break; break;
} }
} }
@ -331,31 +344,33 @@ public class UserProfileDrawer extends ViewGroup {
} }
@Override @Override
public int clampViewPositionVertical(View child, int top, int dy) { public int clampViewPositionVertical(final View child, final int top, final int dy) {
final int current = mDrawer.getHeaderTop(); final int current = mDrawer.getHeaderTop();
if (!Float.isNaN(mDx) && mDrawer.isValidScroll(mDx, dy)) { if (!Float.isNaN(mDx) && mDrawer.isValidScroll(mDx, dy)) {
mScrollingByHelper = false; mScrollingHeaderByHelper = false;
return current; return current;
} }
if (dy > 0 && mDrawer.canScrollCallback(-dy) && !mDrawer.isUsingDragHelper()) { if (dy > 0 && mDrawer.canScrollCallback(-dy)) {
if (!mDrawer.isUsingDragHelper()) {
// Scrolling up while list still has space to scroll, so make header still // Scrolling up while list still has space to scroll, so make header still
mScrollingByHelper = false; mScrollingHeaderByHelper = false;
return current; return current;
} else if (dy > 0 && mDrawer.canScrollCallback(-dy) && mDrawer.isTouchingScrollableContent()) { } else if (mDrawer.isTouchingScrollableContent()) {
mDrawer.scrollByCallback(-dy); mDrawer.scrollByCallback(-dy);
mScrollingByHelper = false; mScrollingHeaderByHelper = false;
return current; return current;
} }
}
final int min = mDrawer.getHeaderTopMinimum(), max = mDrawer.getHeaderTopMaximum(); final int min = mDrawer.getHeaderTopMinimum(), max = mDrawer.getHeaderTopMaximum();
if (top < min && mDrawer.isTouchingScrollableContent()) { if (top < min && mDrawer.isTouchingScrollableContent() && mDrawer.isUsingDragHelper()) {
mDrawer.scrollByCallback(-dy); mDrawer.scrollByCallback(-dy);
} }
mScrollingByHelper = true; mScrollingHeaderByHelper = true;
return MathUtils.clamp(top, min, max); return MathUtils.clamp(top, min, max);
} }
private boolean isScrollingByHelper() { private boolean isScrollingHeaderByHelper() {
return mScrollingByHelper; return mScrollingHeaderByHelper;
} }
} }
@ -373,14 +388,14 @@ public class UserProfileDrawer extends ViewGroup {
final int offset = mDrawer.getHeaderTop(), min = mDrawer.getHeaderTopMinimum(); final int offset = mDrawer.getHeaderTop(), min = mDrawer.getHeaderTopMinimum();
if (!mDrawer.canScrollCallback(-1)) { if (!mDrawer.canScrollCallback(-1)) {
if (distanceY < 0) { if (distanceY < 0) {
if (!mDrawer.mDragCallback.isScrollingByHelper()) { if (!mDrawer.isScrollingHeaderByHelper()) {
mDrawer.offsetHeaderBy(Math.round(-distanceY)); mDrawer.offsetHeaderBy(Math.round(-distanceY));
} }
mDrawer.setScrollingHeaderByGesture(true); mDrawer.setScrollingHeaderByGesture(true);
} else if (distanceY > 0 && offset > min) { } else if (distanceY > 0 && offset > min) {
// Scrolling up when scrolling to list top, so we cancel touch event and scrolling header up // Scrolling up when scrolling to list top, so we cancel touch event and scrolling header up
mDrawer.cancelTouchCallback(); mDrawer.cancelTouchCallback();
if (!mDrawer.mDragCallback.isScrollingByHelper()) { if (!mDrawer.isScrollingHeaderByHelper()) {
mDrawer.offsetHeaderBy(Math.round(-distanceY)); mDrawer.offsetHeaderBy(Math.round(-distanceY));
} }
} else if (offset <= min) { } else if (offset <= min) {
@ -393,12 +408,13 @@ public class UserProfileDrawer extends ViewGroup {
@Override @Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
final int top = mDrawer.getHeaderTop(), min = mDrawer.getHeaderTopMinimum();
if (velocityY > 0 && !mDrawer.canScrollCallback(-1)) { if (velocityY > 0 && !mDrawer.canScrollCallback(-1)) {
// Fling down when list reached top, so we fling header down here // Fling down when list reached top, so we fling header down here
if (Math.abs(velocityY) > Math.abs(velocityX)) { if (Math.abs(velocityY) > Math.abs(velocityX)) {
mDrawer.flingHeader(velocityY); mDrawer.flingHeader(velocityY);
} }
} else if (velocityY < 0 && mDrawer.getHeaderTop() <= mDrawer.getHeaderTopMinimum()) { } else if (velocityY < 0 && top <= min && mDrawer.isScrollingContentCallback()) {
// Fling up when showing full content, so we fling list up here // Fling up when showing full content, so we fling list up here
if (Math.abs(velocityY) > Math.abs(velocityX)) { if (Math.abs(velocityY) > Math.abs(velocityX)) {
mDrawer.flingCallback(-velocityY); mDrawer.flingCallback(-velocityY);
@ -409,6 +425,8 @@ public class UserProfileDrawer extends ViewGroup {
@Override @Override
public boolean onDown(MotionEvent e) { public boolean onDown(MotionEvent e) {
mDrawer.setScrollingHeaderByGesture(false);
mDrawer.setScrollingContentCallback(false);
return true; return true;
} }
} }

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Twidere - Twitter client for Android
~
~ Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@color/bg_color_tab_pressed"/>
<item android:state_focused="true" android:drawable="@color/bg_color_tab_pressed"/>
<item android:drawable="@android:color/transparent"/>
</selector>

View File

@ -20,6 +20,7 @@
<LinearLayout <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" 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_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"> android:orientation="vertical">
@ -27,7 +28,8 @@
<com.astuetz.PagerSlidingTabStrip <com.astuetz.PagerSlidingTabStrip
android:id="@+id/view_pager_tabs" android:id="@+id/view_pager_tabs"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="@dimen/element_size_normal"/> android:layout_height="@dimen/element_size_normal"
app:pstsTabBackground="?android:selectableItemBackground"/>
<android.support.v4.view.ViewPager <android.support.v4.view.ViewPager
android:id="@+id/view_pager" android:id="@+id/view_pager"

View File

@ -219,34 +219,6 @@
android:showDividers="middle" android:showDividers="middle"
android:splitMotionEvents="false"> android:splitMotionEvents="false">
<LinearLayout
android:id="@+id/tweets_container"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="?android:selectableItemBackground"
android:clickable="true"
android:gravity="center"
android:orientation="vertical"
android:padding="@dimen/element_spacing_small">
<org.mariotaku.twidere.view.themed.ThemedTextView
android:id="@+id/statuses_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:textAppearanceMedium"
android:textColor="?android:textColorPrimary"/>
<org.mariotaku.twidere.view.themed.ThemedTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:text="@string/statuses"
android:textAppearance="?android:textAppearanceSmall"
android:textColor="?android:textColorSecondary"/>
</LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/followers_container" android:id="@+id/followers_container"
android:layout_width="0dp" android:layout_width="0dp"
@ -302,6 +274,34 @@
android:textAppearance="?android:textAppearanceSmall" android:textAppearance="?android:textAppearanceSmall"
android:textColor="?android:textColorSecondary"/> android:textColor="?android:textColorSecondary"/>
</LinearLayout> </LinearLayout>
<LinearLayout
android:id="@+id/listed_container"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="?android:selectableItemBackground"
android:clickable="true"
android:gravity="center"
android:orientation="vertical"
android:padding="@dimen/element_spacing_small">
<org.mariotaku.twidere.view.themed.ThemedTextView
android:id="@+id/listed_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:textAppearanceMedium"
android:textColor="?android:textColorPrimary"/>
<org.mariotaku.twidere.view.themed.ThemedTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:text="@string/listed"
android:textAppearance="?android:textAppearanceSmall"
android:textColor="?android:textColorSecondary"/>
</LinearLayout>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
</android.support.v7.widget.CardView> </android.support.v7.widget.CardView>

View File

@ -23,5 +23,6 @@
<color name="highlight_reply">@color/material_light_blue</color> <color name="highlight_reply">@color/material_light_blue</color>
<color name="unread_color">@color/material_red</color> <color name="unread_color">@color/material_red</color>
<color name="branding_color">@color/material_light_blue</color> <color name="branding_color">@color/material_light_blue</color>
<color name="bg_color_tab_pressed">#40808080</color>
</resources> </resources>

View File

@ -677,5 +677,6 @@
<string name="replies">Replies</string> <string name="replies">Replies</string>
<string name="profile_banner">Profile banner</string> <string name="profile_banner">Profile banner</string>
<string name="profile">Profile</string> <string name="profile">Profile</string>
<string name="listed">Listed</string>
</resources> </resources>