improved L compatibility

This commit is contained in:
Mariotaku Lee 2014-12-02 00:04:55 +08:00
parent 3c7b636b42
commit f26db18748
34 changed files with 1082 additions and 859 deletions

View File

@ -56,7 +56,7 @@
android:hardwareAccelerated="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/Theme.Twidere.Dark">
android:theme="@style/Theme.Blank">
<uses-library
android:name="com.sec.android.app.multiwindow"
android:required="false"/>

View File

@ -41,6 +41,16 @@ public abstract class BasePreferenceActivity extends PreferenceActivity implemen
return super.onMenuOpened(featureId, menu);
}
@Override
public int getCurrentThemeBackgroundAlpha() {
return 0;
}
@Override
public int getCurrentThemeColor() {
return 0;
}
@Override
public int getCurrentThemeResourceId() {
return mCurrentThemeResource;

View File

@ -94,6 +94,16 @@ public abstract class BaseThemedActivity extends Activity implements IThemedActi
|| getThemeBackgroundAlpha() != mCurrentThemeBackgroundAlpha;
}
@Override
public int getCurrentThemeBackgroundAlpha() {
return mCurrentThemeBackgroundAlpha;
}
@Override
public int getCurrentThemeColor() {
return mCurrentThemeColor;
}
@Override
protected void onCreate(final Bundle savedInstanceState) {
if (Utils.isDebugBuild()) {

View File

@ -28,9 +28,12 @@ public interface IThemedActivity {
public Resources getDefaultResources();
public int getThemeBackgroundAlpha();
public int getCurrentThemeBackgroundAlpha();
public int getThemeColor();
public int getCurrentThemeColor();
public String getThemeFontFamily();
int getThemeResourceId();

View File

@ -38,7 +38,7 @@ public class AccountsManagerActivity extends BaseSupportActivity {
setContentView(R.layout.activity_content_fragment);
final FragmentManager fm = getSupportFragmentManager();
final FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.content_fragment, new AccountsManagerFragment());
ft.replace(R.id.main_content, new AccountsManagerFragment());
ft.commit();
}
@ -46,7 +46,7 @@ public class AccountsManagerActivity extends BaseSupportActivity {
public void fitSystemWindows(Rect insets) {
super.fitSystemWindows(insets);
final FragmentManager fm = getSupportFragmentManager();
final Fragment f = fm.findFragmentById(R.id.content_fragment);
final Fragment f = fm.findFragmentById(R.id.main_content);
if (f instanceof IBaseFragment) {
((IBaseFragment) f).requestFitSystemWindows();
}

View File

@ -54,6 +54,16 @@ public abstract class BaseSupportThemedActivity extends FragmentActivity impleme
return ThemeUtils.isTransparentBackground(this) ? ThemeUtils.getUserThemeBackgroundAlpha(this) : 0xff;
}
@Override
public int getCurrentThemeBackgroundAlpha() {
return mCurrentThemeBackgroundAlpha;
}
@Override
public int getCurrentThemeColor() {
return mCurrentThemeColor;
}
@Override
public String getThemeFontFamily() {
return ThemeUtils.getThemeFontFamily(this);
@ -77,7 +87,6 @@ public abstract class BaseSupportThemedActivity extends FragmentActivity impleme
}
setTheme();
super.onCreate(savedInstanceState);
setActionBarBackground();
}
@Override
@ -105,10 +114,6 @@ public abstract class BaseSupportThemedActivity extends FragmentActivity impleme
return true;
}
private final void setActionBarBackground() {
ThemeUtils.applyActionBarBackground(getActionBar(), this, mCurrentThemeResource);
}
private final void setTheme() {
mCurrentThemeResource = getThemeResourceId();
mCurrentThemeColor = getThemeColor();

View File

@ -94,11 +94,11 @@ import org.mariotaku.twidere.util.UnreadCountUtils;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.util.accessor.ViewAccessor;
import org.mariotaku.twidere.view.ExtendedViewPager;
import org.mariotaku.twidere.view.HomeContentFrameLayout;
import org.mariotaku.twidere.view.HomeSlidingMenu;
import org.mariotaku.twidere.view.LeftDrawerFrameLayout;
import org.mariotaku.twidere.view.RightDrawerFrameLayout;
import org.mariotaku.twidere.view.TabPagerIndicator;
import org.mariotaku.twidere.view.TintedStatusFrameLayout;
import org.mariotaku.twidere.view.iface.IHomeActionButton;
import java.util.ArrayList;
@ -169,7 +169,7 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
private View mActionBarOverlay;
private LeftDrawerFrameLayout mLeftDrawerContainer;
private RightDrawerFrameLayout mRightDrawerContainer;
private HomeContentFrameLayout mHomeContentFrameLayout;
private TintedStatusFrameLayout mColorStatusFrameLayout;
private Fragment mCurrentVisibleFragment;
private UpdateUnreadCountTask mUpdateUnreadCountTask;
@ -254,7 +254,7 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
mTabsContainer = findViewById(R.id.tabs_container);
mTabIndicator = (TabPagerIndicator) findViewById(R.id.main_tabs);
mActionBarOverlay = findViewById(R.id.actionbar_overlay);
mHomeContentFrameLayout = (HomeContentFrameLayout) findViewById(R.id.home_content);
mColorStatusFrameLayout = (TintedStatusFrameLayout) findViewById(R.id.home_content);
}
@Override
@ -579,7 +579,10 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
mTabIndicator.setStripColor(contrastColor);
mTabIndicator.setIconColor(contrastColor);
ActivityAccessor.setTaskDescription(this, new TaskDescriptionCompat(null, null, themeColor));
mHomeContentFrameLayout.setColor(themeColor, actionBarAlpha);
mColorStatusFrameLayout.setDrawColor(true);
mColorStatusFrameLayout.setDrawShadow(false);
mColorStatusFrameLayout.setColor(themeColor, actionBarAlpha);
mColorStatusFrameLayout.setFactor(1);
} else {
final int backgroundColor = ThemeUtils.getThemeBackgroundColor(mTabIndicator.getItemContext());
final int foregroundColor = ThemeUtils.getThemeForegroundColor(mTabIndicator.getItemContext());
@ -588,7 +591,8 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
homeActionButton.setIconColor(foregroundColor, Mode.SRC_ATOP);
mTabIndicator.setStripColor(themeColor);
mTabIndicator.setIconColor(foregroundColor);
mHomeContentFrameLayout.setColor(backgroundColor, actionBarAlpha);
mColorStatusFrameLayout.setDrawColor(false);
mColorStatusFrameLayout.setDrawShadow(false);
}
mTabIndicator.setAlpha(actionBarAlpha / 255f);
mActionsButton.setAlpha(actionBarAlpha / 255f);
@ -910,7 +914,6 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
}
public void setSystemWindowInsets(Rect insets) {
mHomeContentFrameLayout.setStatusBarHeight(insets.top);
final Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.left_drawer);
if (fragment instanceof AccountsDashboardFragment) {
((AccountsDashboardFragment) fragment).setStatusBarHeight(insets.top);

View File

@ -29,8 +29,6 @@ import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.ListFragment;
import android.transition.Transition;
import android.transition.TransitionInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
@ -45,8 +43,13 @@ import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCal
import org.mariotaku.twidere.fragment.iface.IBasePullToRefreshFragment;
import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface;
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback;
import org.mariotaku.twidere.util.ActivityAccessor;
import org.mariotaku.twidere.util.ActivityAccessor.TaskDescriptionCompat;
import org.mariotaku.twidere.util.FlymeUtils;
import org.mariotaku.twidere.util.MultiSelectEventHandler;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.TintedStatusFrameLayout;
import static org.mariotaku.twidere.util.Utils.createFragmentForIntent;
import static org.mariotaku.twidere.util.Utils.matchLinkId;
@ -56,13 +59,15 @@ public class LinkHandlerActivity extends BaseSupportActivity implements OnClickL
private MultiSelectEventHandler mMultiSelectHandler;
private TintedStatusFrameLayout mMainContent;
private boolean mFinishOnly;
@Override
public void onClick(final View v) {
switch (v.getId()) {
case R.id.go_top: {
final Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.content_fragment);
final Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.main_content);
if (fragment instanceof RefreshScrollTopInterface) {
((RefreshScrollTopInterface) fragment).scrollToStart();
} else if (fragment instanceof ListFragment) {
@ -77,7 +82,7 @@ public class LinkHandlerActivity extends BaseSupportActivity implements OnClickL
public boolean onLongClick(final View v) {
switch (v.getId()) {
case R.id.go_top: {
final Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.content_fragment);
final Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.main_content);
if (fragment instanceof RefreshScrollTopInterface) {
((RefreshScrollTopInterface) fragment).triggerRefresh();
}
@ -115,6 +120,12 @@ public class LinkHandlerActivity extends BaseSupportActivity implements OnClickL
return null;
}
@Override
public void onContentChanged() {
super.onContentChanged();
mMainContent = (TintedStatusFrameLayout) findViewById(R.id.main_content);
}
@Override
protected void onCreate(final Bundle savedInstanceState) {
mMultiSelectHandler = new MultiSelectEventHandler(this);
@ -128,26 +139,74 @@ public class LinkHandlerActivity extends BaseSupportActivity implements OnClickL
final ActionBar actionBar = getActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
setActionBarBackground(actionBar, linkId, data);
}
setContentView(R.layout.activity_content_fragment);
setStatusBarColor(linkId, data);
setTaskinfo(linkId, data);
setProgressBarIndeterminateVisibility(false);
if (data == null || !showFragment(linkId, data)) {
finish();
}
}
private void requestWindowFeatures(Window window, int linkId, Uri uri) {
private void setTaskinfo(int linkId, Uri uri) {
switch (linkId) {
case LINK_ID_USER: {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
window.addFlags(LayoutParams.FLAG_TRANSLUCENT_STATUS);
break;
}
default: {
if (ThemeUtils.isColoredActionBar(getCurrentThemeResourceId())) {
ActivityAccessor.setTaskDescription(this, new TaskDescriptionCompat(null, null,
getCurrentThemeColor()));
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);
final TransitionInflater inflater = TransitionInflater.from(this);
final Transition transition = inflater.inflateTransition(R.transition.transition_user_profile);
window.setSharedElementEnterTransition(transition);
window.setSharedElementExitTransition(transition);
break;
}
}
}
private void setActionBarBackground(ActionBar actionBar, int linkId, Uri data) {
switch (linkId) {
case LINK_ID_USER: {
break;
}
default: {
ThemeUtils.applyActionBarBackground(actionBar, this, getCurrentThemeResourceId(),
getCurrentThemeColor());
break;
}
}
}
private void setStatusBarColor(int linkId, Uri uri) {
switch (linkId) {
case LINK_ID_USER: {
mMainContent.setShadowColor(0xA0000000);
mMainContent.setDrawShadow(false);
mMainContent.setDrawColor(!ThemeUtils.isDarkTheme(getCurrentThemeResourceId()));
break;
}
default: {
mMainContent.setDrawShadow(false);
mMainContent.setDrawColor(true);
mMainContent.setFactor(1);
final int color = ThemeUtils.getUserAccentColor(this);
final int alpha = ThemeUtils.getThemeAlpha(this);
mMainContent.setColor(color, alpha);
break;
}
}
}
private void requestWindowFeatures(Window window, int linkId, Uri uri) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
window.addFlags(LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
switch (linkId) {
case LINK_ID_USER: {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && !ThemeUtils.isTransparentBackground(this)) {
Utils.setSharedElementTransition(this, window, R.transition.transition_user_profile);
}
break;
}
@ -169,7 +228,7 @@ public class LinkHandlerActivity extends BaseSupportActivity implements OnClickL
@Override
public void fitSystemWindows(Rect insets) {
super.fitSystemWindows(insets);
final Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.content_fragment);
final Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.main_content);
if (fragment instanceof IBaseFragment) {
((IBaseFragment) fragment).requestFitSystemWindows();
}
@ -295,7 +354,7 @@ public class LinkHandlerActivity extends BaseSupportActivity implements OnClickL
}
mFinishOnly = Boolean.parseBoolean(uri.getQueryParameter(QUERY_PARAM_FINISH_ONLY));
final FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_fragment, fragment);
ft.replace(R.id.main_content, fragment);
ft.commit();
return true;
}

View File

@ -24,7 +24,8 @@ import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.v4.app.ActivityOptionsCompat;
import android.os.Bundle;
import android.support.v4.util.Pair;
import android.text.Html;
import android.text.TextUtils;
import android.view.View;
@ -35,6 +36,7 @@ import android.widget.ImageView.ScaleType;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.iface.IStatusesListAdapter;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.fragment.support.UserFragment;
import org.mariotaku.twidere.model.ParcelableMedia;
import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.model.ParcelableUserMention;
@ -374,10 +376,10 @@ public class CursorStatusesAdapter extends BaseCursorAdapter implements IStatuse
final ParcelableStatus status = getStatus(position);
if (status == null) return;
final Activity activity = (Activity) getContext();
final ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(activity,
view, "profile_image");
final Bundle options = Utils.makeSceneTransitionOption(activity,
new Pair<>(view, UserFragment.TRANSITION_NAME_PROFILE_IMAGE));
openUserProfile(mContext, status.account_id, status.user_id,
status.user_screen_name, options.toBundle());
status.user_screen_name, options);
break;
}
}

View File

@ -31,7 +31,6 @@ import android.database.Cursor;
import android.graphics.PorterDuff.Mode;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.v4.app.ActivityOptionsCompat;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
@ -71,6 +70,7 @@ import org.mariotaku.twidere.model.Account.Indices;
import org.mariotaku.twidere.provider.TweetStore.Accounts;
import org.mariotaku.twidere.util.ImageLoaderWrapper;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.util.content.SupportFragmentReloadCursorObserver;
import java.util.ArrayList;
@ -184,10 +184,10 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement
switch (option.id) {
case MENU_VIEW_PROFILE: {
final FragmentActivity activity = getActivity();
final ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(activity,
new Pair<View, String>(mAccountProfileImageView, UserProfileFragment.TRANSITION_NAME_PROFILE_IMAGE));
openUserProfile(activity, account.account_id, account.account_id, account.screen_name,
options.toBundle());
final Bundle activityOption = Utils.makeSceneTransitionOption(activity,
new Pair<View, String>(mAccountProfileImageView, UserFragment.TRANSITION_NAME_PROFILE_IMAGE));
openUserProfile(activity, account.account_id, account.account_id,
account.screen_name, activityOption);
break;
}
case MENU_SEARCH: {

View File

@ -20,11 +20,12 @@
package org.mariotaku.twidere.fragment.support;
import android.app.ActionBar;
import android.graphics.Rect;
import android.os.Bundle;
import android.provider.SearchRecentSuggestions;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@ -32,24 +33,24 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import com.astuetz.PagerSlidingTabStrip;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.support.LinkHandlerActivity;
import org.mariotaku.twidere.adapter.support.SupportTabsAdapter;
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback;
import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface;
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback;
import org.mariotaku.twidere.provider.RecentSearchProvider;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.view.ExtendedViewPager;
import org.mariotaku.twidere.view.LinePageIndicator;
public class SearchFragment extends BaseSupportFragment implements OnPageChangeListener,
RefreshScrollTopInterface, SupportFragmentCallback {
public class SearchFragment extends BaseSupportFragment implements RefreshScrollTopInterface,
SupportFragmentCallback, SystemWindowsInsetsCallback {
private ExtendedViewPager mViewPager;
private ViewPager mViewPager;
private SupportTabsAdapter mAdapter;
private LinePageIndicator mPagerIndicator;
private PagerSlidingTabStrip mPagerIndicator;
private Fragment mCurrentVisibleFragment;
@ -72,9 +73,7 @@ public class SearchFragment extends BaseSupportFragment implements OnPageChangeL
R.drawable.ic_action_twitter, 0);
mAdapter.addTab(SearchUsersFragment.class, args, getString(R.string.users), R.drawable.ic_action_user, 1);
mViewPager.setAdapter(mAdapter);
mViewPager.setOnPageChangeListener(this);
mViewPager.setOffscreenPageLimit(2);
mPagerIndicator.setSelectedColor(ThemeUtils.getThemeColor(activity));
mPagerIndicator.setViewPager(mViewPager);
if (savedInstanceState == null && args != null && args.containsKey(EXTRA_QUERY)) {
final String query = args.getString(EXTRA_QUERY);
@ -97,7 +96,7 @@ public class SearchFragment extends BaseSupportFragment implements OnPageChangeL
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_search, container, false);
return inflater.inflate(R.layout.fragment_content_pages, container, false);
}
@Override
@ -122,18 +121,6 @@ public class SearchFragment extends BaseSupportFragment implements OnPageChangeL
return super.onOptionsItemSelected(item);
}
@Override
public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) {
}
@Override
public void onPageScrollStateChanged(final int state) {
}
@Override
public void onPageSelected(final int position) {
}
@Override
public void onSetUserVisibleHint(final Fragment fragment, final boolean isVisibleToUser) {
if (isVisibleToUser) {
@ -144,8 +131,8 @@ public class SearchFragment extends BaseSupportFragment implements OnPageChangeL
@Override
public void onViewCreated(final View view, final Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mViewPager = (ExtendedViewPager) view.findViewById(R.id.search_pager);
mPagerIndicator = (LinePageIndicator) view.findViewById(R.id.search_pager_indicator);
mViewPager = (ViewPager) view.findViewById(R.id.view_pager);
mPagerIndicator = (PagerSlidingTabStrip) view.findViewById(R.id.view_pager_tabs);
}
@Override
@ -170,4 +157,8 @@ public class SearchFragment extends BaseSupportFragment implements OnPageChangeL
return false;
}
@Override
public boolean getSystemWindowsInsets(Rect insets) {
return false;
}
}

View File

@ -36,7 +36,6 @@ import android.location.Geocoder;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityOptionsCompat;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager;
@ -516,11 +515,11 @@ public class StatusFragment extends ParcelableStatusesListFragment implements On
switch (view.getId()) {
case R.id.profile: {
final FragmentActivity activity = getActivity();
final ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(activity,
new Pair<View, String>(mProfileImageView, UserProfileFragment.TRANSITION_NAME_PROFILE_IMAGE),
new Pair<View, String>(mProfileTypeView, UserProfileFragment.TRANSITION_NAME_PROFILE_TYPE));
final Bundle activityOption = Utils.makeSceneTransitionOption(activity,
new Pair<View, String>(mProfileImageView, UserFragment.TRANSITION_NAME_PROFILE_IMAGE),
new Pair<View, String>(mProfileTypeView, UserFragment.TRANSITION_NAME_PROFILE_TYPE));
openUserProfile(activity, status.account_id, status.user_id, status.user_screen_name,
options.toBundle());
activityOption);
break;
}
case R.id.follow: {
@ -581,7 +580,7 @@ public class StatusFragment extends ParcelableStatusesListFragment implements On
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_details_page, container, false);
final View view = inflater.inflate(R.layout.fragment_details_page_with_menubar, container, false);
view.findViewById(R.id.menu_bar).setVisibility(View.GONE);
mMainContent = view.findViewById(R.id.content);
mDetailsLoadProgress = (ProgressBar) view.findViewById(R.id.details_load_progress);

View File

@ -108,10 +108,10 @@ import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.util.menu.TwidereMenuInfo;
import org.mariotaku.twidere.view.CircularImageView;
import org.mariotaku.twidere.view.ColorLabelLinearLayout;
import org.mariotaku.twidere.view.HeaderDrawerLayout;
import org.mariotaku.twidere.view.HeaderDrawerLayout.DrawerCallback;
import org.mariotaku.twidere.view.ProfileBannerImageView;
import org.mariotaku.twidere.view.UserProfileContentFrameLayout;
import org.mariotaku.twidere.view.UserProfileDrawer;
import org.mariotaku.twidere.view.UserProfileDrawer.DrawerCallback;
import org.mariotaku.twidere.view.TintedStatusFrameLayout;
import org.mariotaku.twidere.view.iface.IExtendedView.OnSizeChangedListener;
import java.util.Locale;
@ -148,7 +148,7 @@ import static org.mariotaku.twidere.util.Utils.openUserProfile;
import static org.mariotaku.twidere.util.Utils.setMenuItemAvailability;
import static org.mariotaku.twidere.util.Utils.showInfoMessage;
public class UserProfileFragment extends BaseSupportFragment implements OnClickListener,
public class UserFragment extends BaseSupportFragment implements OnClickListener,
OnMenuItemClickListener, OnLinkClickListener, OnSizeChangedListener,
OnSharedPreferenceChangeListener, OnTouchListener, ImageLoadingListener, DrawerCallback,
SupportFragmentCallback, SystemWindowsInsetsCallback {
@ -174,8 +174,8 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
private View mFollowingYouIndicator;
private View mMainContent;
private View mProfileBannerSpace;
private UserProfileContentFrameLayout mUserProfileContent;
private UserProfileDrawer mUserProfileDrawer;
private TintedStatusFrameLayout mTintedStatusContent;
private HeaderDrawerLayout mHeaderDrawerLayout;
private ViewPager mViewPager;
private PagerSlidingTabStrip mPagerIndicator;
@ -332,6 +332,7 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
private int mBannerWidth;
private ActionBarDrawable mActionBarBackground;
private Fragment mCurrentVisibleFragment;
private View mUuckyFooter;
public void displayUser(final ParcelableUser user) {
mRelationship = null;
@ -401,12 +402,90 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
final String where = Accounts.ACCOUNT_ID + " = " + user.id;
resolver.update(Accounts.CONTENT_URI, values, where, null);
}
mUuckyFooter.setVisibility(isUucky(user.id, user.screen_name, user) ? View.VISIBLE : View.GONE);
if (!user.is_cache) {
getFriendship();
}
invalidateOptionsMenu();
}
@Override
public void fling(float velocity) {
final Fragment fragment = mCurrentVisibleFragment;
if (fragment instanceof DrawerCallback) {
((DrawerCallback) fragment).fling(velocity);
}
}
@Override
public void scrollBy(float dy) {
final Fragment fragment = mCurrentVisibleFragment;
if (fragment instanceof DrawerCallback) {
((DrawerCallback) fragment).scrollBy(dy);
}
}
@Override
public boolean canScroll(float dy) {
final Fragment fragment = mCurrentVisibleFragment;
return fragment instanceof DrawerCallback && ((DrawerCallback) fragment).canScroll(dy);
}
@Override
public boolean isScrollContent(float x, float y) {
final ViewPager v = mViewPager;
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
public void cancelTouch() {
final Fragment fragment = mCurrentVisibleFragment;
if (fragment instanceof DrawerCallback) {
((DrawerCallback) fragment).cancelTouch();
}
}
@Override
public void topChanged(int top) {
final HeaderDrawerLayout drawer = mHeaderDrawerLayout;
if (drawer == null) return;
final int offset = drawer.getPaddingTop() - top;
updateScrollOffset(offset);
final Fragment fragment = mCurrentVisibleFragment;
if (fragment instanceof DrawerCallback) {
((DrawerCallback) fragment).topChanged(top);
}
}
@Override
public Fragment getCurrentVisibleFragment() {
return mCurrentVisibleFragment;
}
@Override
public void onDetachFragment(Fragment fragment) {
}
@Override
public void onSetUserVisibleHint(Fragment fragment, boolean isVisibleToUser) {
mCurrentVisibleFragment = isVisibleToUser ? fragment : null;
}
@Override
public boolean triggerRefresh(int position) {
return false;
}
@Override
public boolean getSystemWindowsInsets(Rect insets) {
return false;
}
public void getUserInfo(final long accountId, final long userId, final String screenName,
final boolean omitIntentExtra) {
final LoaderManager lm = getLoaderManager();
@ -435,74 +514,6 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
}
}
public void setListShown(boolean shown) {
final boolean drawColor;
final FragmentActivity activity = getActivity();
if (activity instanceof LinkHandlerActivity) {
final LinkHandlerActivity linkHandler = (LinkHandlerActivity) activity;
drawColor = !ThemeUtils.isDarkTheme(linkHandler.getCurrentThemeResourceId());
} else {
drawColor = false;
}
mUserProfileContent.setDrawShadow(shown);
mUserProfileContent.setDrawColor(drawColor);
}
private void setupUserPages() {
final Context context = getActivity();
final Bundle args = getArguments(), tabArgs = new Bundle();
final long accountId;
if (args.containsKey(EXTRA_USER)) {
final ParcelableUser user = args.getParcelable(EXTRA_USER);
tabArgs.putLong(EXTRA_ACCOUNT_ID, accountId = user.account_id);
tabArgs.putLong(EXTRA_USER_ID, user.id);
tabArgs.putString(EXTRA_SCREEN_NAME, user.screen_name);
} else {
accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
tabArgs.putLong(EXTRA_ACCOUNT_ID, accountId);
tabArgs.putLong(EXTRA_USER_ID, args.getLong(EXTRA_USER_ID, -1));
tabArgs.putString(EXTRA_SCREEN_NAME, args.getString(EXTRA_SCREEN_NAME));
}
mPagerAdapter.addTab(UserTimelineFragment.class, tabArgs, getString(R.string.statuses), null, 0);
if (Utils.isOfficialKeyAccount(context, accountId)) {
mPagerAdapter.addTab(UserMediaTimelineFragment.class, tabArgs, getString(R.string.media), null, 1);
}
mPagerAdapter.addTab(UserFavoritesFragment.class, tabArgs, getString(R.string.favorites), null, 2);
mPagerIndicator.notifyDataSetChanged();
}
private void setupBaseActionBar() {
final FragmentActivity activity = getActivity();
if (!(activity instanceof LinkHandlerActivity)) return;
final LinkHandlerActivity linkHandler = (LinkHandlerActivity) activity;
final ActionBar actionBar = linkHandler.getActionBar();
if (actionBar == null) return;
final int themeResId = linkHandler.getCurrentThemeResourceId();
final Drawable shadow = activity.getResources().getDrawable(R.drawable.shadow_user_banner_action_bar);
final Drawable background = ThemeUtils.getActionBarBackground(activity, themeResId);
actionBar.setBackgroundDrawable(mActionBarBackground = new ActionBarDrawable(getResources(),
shadow, background, ThemeUtils.isDarkTheme(themeResId)));
mUserProfileContent.setShadowColor(0xA0000000);
}
private void setupUserColorActionBar(int color) {
if (mActionBarBackground == null) {
setupBaseActionBar();
}
mActionBarBackground.setColor(color);
mUserProfileContent.setColor(color);
mPagerIndicator.setIndicatorColor(color);
}
private boolean isUucky(long userId, String screenName, Parcelable parcelable) {
if (userId == UUCKY_ID || UUCKY_SCREEN_NAME.equalsIgnoreCase(screenName)) return true;
if (parcelable instanceof ParcelableUser) {
final ParcelableUser user = (ParcelableUser) parcelable;
return user.id == UUCKY_ID || UUCKY_SCREEN_NAME.equalsIgnoreCase(user.screen_name);
}
return false;
}
@Override
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
final ParcelableUser user = mUser;
@ -541,9 +552,15 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mTintedStatusContent = (TintedStatusFrameLayout) activity.findViewById(R.id.main_content);
}
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_user_profile, container, false);
return inflater.inflate(R.layout.fragment_user, container, false);
}
@Override
@ -571,7 +588,7 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
ViewCompat.setTransitionName(mProfileImageView, TRANSITION_NAME_PROFILE_IMAGE);
ViewCompat.setTransitionName(mProfileTypeView, TRANSITION_NAME_PROFILE_TYPE);
mUserProfileDrawer.setDrawerCallback(this);
mHeaderDrawerLayout.setDrawerCallback(this);
mPagerAdapter = new SupportTabsAdapter(activity, getChildFragmentManager());
@ -591,8 +608,6 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
setupBaseActionBar();
// updateScrollOffset(0);
setupUserPages();
}
@ -728,6 +743,34 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
}
}
@Override
public void onLoadingStarted(String imageUri, View view) {
}
@Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
}
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
Palette.generateAsync(loadedImage, new PaletteAsyncListener() {
@Override
public void onGenerated(Palette palette) {
final ParcelableUser user = mUser;
if (user == null) return;
final int color = palette.getVibrantColor(0);
setupUserColorActionBar(color);
}
});
}
@Override
public void onLoadingCancelled(String imageUri, View view) {
}
@Override
public boolean onMenuItemClick(final MenuItem item) {
return handleMenuItemClick(item);
@ -757,16 +800,15 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
public void onViewCreated(final View view, final Bundle savedInstanceState) {
final Context context = view.getContext();
super.onViewCreated(view, savedInstanceState);
mUserProfileContent = (UserProfileContentFrameLayout) view.findViewById(R.id.user_profile_fragment);
mMainContent = view.findViewById(R.id.details_container);
mUserProfileDrawer = (UserProfileDrawer) view.findViewById(R.id.user_profile_drawer);
mHeaderDrawerLayout = (HeaderDrawerLayout) view.findViewById(R.id.user_profile_drawer);
mErrorRetryContainer = view.findViewById(R.id.error_retry_container);
mProgressContainer = view.findViewById(R.id.progress_container);
mRetryButton = (Button) view.findViewById(R.id.retry);
mErrorMessageView = (TextView) view.findViewById(R.id.error_message);
mProfileBannerView = (ProfileBannerImageView) view.findViewById(R.id.profile_banner);
final View headerView = mUserProfileDrawer.getHeader();
final View contentView = mUserProfileDrawer.getContent();
final View headerView = mHeaderDrawerLayout.getHeader();
final View contentView = mHeaderDrawerLayout.getContent();
mNameView = (TextView) headerView.findViewById(R.id.name);
mScreenNameView = (TextView) headerView.findViewById(R.id.screen_name);
mDescriptionView = (TextView) headerView.findViewById(R.id.description);
@ -789,8 +831,7 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
mProfileBannerSpace = headerView.findViewById(R.id.profile_banner_space);
mViewPager = (ViewPager) contentView.findViewById(R.id.view_pager);
mPagerIndicator = (PagerSlidingTabStrip) contentView.findViewById(R.id.view_pager_tabs);
final View cardView = headerView.findViewById(R.id.card);
ThemeUtils.applyThemeAlphaToDrawable(context, cardView.getBackground());
mUuckyFooter = headerView.findViewById(R.id.uucky_footer);
}
@Override
@ -802,8 +843,8 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
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);
mHeaderDrawerLayout.setPadding(insets.left, insets.top, insets.right, insets.bottom);
mHeaderDrawerLayout.setClipToPadding(ThemeUtils.isTransparentBackground(getActivity()));
final int bannerHeight = mProfileBannerView.getHeight();
if (bannerHeight != 0) {
final ViewGroup.LayoutParams params = mProfileBannerSpace.getLayoutParams();
@ -813,6 +854,16 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
}
}
public void setListShown(boolean shown) {
final TintedStatusFrameLayout tintedStatus = mTintedStatusContent;
if (tintedStatus == null) return;
final FragmentActivity activity = getActivity();
final LinkHandlerActivity linkHandler = (LinkHandlerActivity) activity;
final boolean drawColor = !ThemeUtils.isDarkTheme(linkHandler.getCurrentThemeResourceId());
tintedStatus.setDrawShadow(shown);
tintedStatus.setDrawColor(drawColor);
}
private void getFriendship() {
final ParcelableUser user = mUser;
final LoaderManager lm = getLoaderManager();
@ -964,6 +1015,15 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
return true;
}
private boolean isUucky(long userId, String screenName, Parcelable parcelable) {
if (userId == UUCKY_ID || UUCKY_SCREEN_NAME.equalsIgnoreCase(screenName)) return true;
if (parcelable instanceof ParcelableUser) {
final ParcelableUser user = (ParcelableUser) parcelable;
return user.id == UUCKY_ID || UUCKY_SCREEN_NAME.equalsIgnoreCase(user.screen_name);
}
return false;
}
private void setMenu(final Menu menu) {
final AsyncTwitterWrapper twitter = getTwitterWrapper();
final ParcelableUser user = mUser;
@ -1028,131 +1088,72 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
addIntentToMenu(getActivity(), menu, intent, MENU_GROUP_USER_EXTENSION);
}
private void setupBaseActionBar() {
final FragmentActivity activity = getActivity();
if (!(activity instanceof LinkHandlerActivity)) return;
final LinkHandlerActivity linkHandler = (LinkHandlerActivity) activity;
final ActionBar actionBar = linkHandler.getActionBar();
if (actionBar == null) return;
final int themeResId = linkHandler.getCurrentThemeResourceId();
final Drawable shadow = activity.getResources().getDrawable(R.drawable.shadow_user_banner_action_bar);
final Drawable background = ThemeUtils.getActionBarBackground(activity, themeResId);
mActionBarBackground = new ActionBarDrawable(getResources(), shadow, background, ThemeUtils.isDarkTheme(themeResId));
mActionBarBackground.setAlpha(ThemeUtils.getThemeAlpha(activity));
actionBar.setBackgroundDrawable(mActionBarBackground);
}
private void setupUserColorActionBar(int color) {
if (mActionBarBackground == null) {
setupBaseActionBar();
}
mActionBarBackground.setColor(color);
mTintedStatusContent.setColor(color, ThemeUtils.getThemeAlpha(getActivity()));
mPagerIndicator.setIndicatorColor(color);
}
private void setupUserPages() {
final Context context = getActivity();
final Bundle args = getArguments(), tabArgs = new Bundle();
final long accountId;
if (args.containsKey(EXTRA_USER)) {
final ParcelableUser user = args.getParcelable(EXTRA_USER);
tabArgs.putLong(EXTRA_ACCOUNT_ID, accountId = user.account_id);
tabArgs.putLong(EXTRA_USER_ID, user.id);
tabArgs.putString(EXTRA_SCREEN_NAME, user.screen_name);
} else {
accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
tabArgs.putLong(EXTRA_ACCOUNT_ID, accountId);
tabArgs.putLong(EXTRA_USER_ID, args.getLong(EXTRA_USER_ID, -1));
tabArgs.putString(EXTRA_SCREEN_NAME, args.getString(EXTRA_SCREEN_NAME));
}
mPagerAdapter.addTab(UserTimelineFragment.class, tabArgs, getString(R.string.statuses), null, 0);
if (Utils.isOfficialKeyAccount(context, accountId)) {
mPagerAdapter.addTab(UserMediaTimelineFragment.class, tabArgs, getString(R.string.media), null, 1);
}
mPagerAdapter.addTab(UserFavoritesFragment.class, tabArgs, getString(R.string.favorites), null, 2);
mPagerIndicator.notifyDataSetChanged();
}
private boolean shouldUseNativeMenu() {
return getActivity() instanceof LinkHandlerActivity;
}
@Override
public void onLoadingStarted(String imageUri, View view) {
}
@Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
}
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
Palette.generateAsync(loadedImage, new PaletteAsyncListener() {
@Override
public void onGenerated(Palette palette) {
final ParcelableUser user = mUser;
if (user == null) return;
final int color = palette.getVibrantColor(0);
setupUserColorActionBar(color);
}
});
}
@Override
public void onLoadingCancelled(String imageUri, View view) {
}
@Override
public void fling(float velocity) {
final Fragment fragment = mCurrentVisibleFragment;
if (fragment instanceof DrawerCallback) {
((DrawerCallback) fragment).fling(velocity);
}
}
@Override
public void scrollBy(float dy) {
final Fragment fragment = mCurrentVisibleFragment;
if (fragment instanceof DrawerCallback) {
((DrawerCallback) fragment).scrollBy(dy);
}
}
@Override
public boolean canScroll(float dy) {
final Fragment fragment = mCurrentVisibleFragment;
return fragment instanceof DrawerCallback && ((DrawerCallback) fragment).canScroll(dy);
}
@Override
public boolean isScrollContent(float x, float y) {
final ViewPager v = mViewPager;
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
public void cancelTouch() {
final Fragment fragment = mCurrentVisibleFragment;
if (fragment instanceof DrawerCallback) {
((DrawerCallback) fragment).cancelTouch();
}
}
@Override
public void topChanged(int top) {
final UserProfileDrawer drawer = mUserProfileDrawer;
if (drawer == null) return;
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 int spaceHeight = space.getHeight();
final float factor = MathUtils.clamp(offset / (float) spaceHeight, 0, 1);
final ProfileBannerImageView profileBannerView = mProfileBannerView;
profileBannerView.setAlpha(1.0f - factor / 8f);
profileBannerView.setTranslationY(offset / -2f);
profileBannerView.setBottomClip(offset);
profileBannerView.setTranslationY(Math.min(offset, spaceHeight) / -2);
profileBannerView.setBottomClip(Math.min(offset, spaceHeight));
if (mActionBarBackground != null) {
if (mActionBarBackground != null && mTintedStatusContent != null) {
mActionBarBackground.setFactor(factor);
mUserProfileContent.setFactor(factor);
mTintedStatusContent.setFactor(factor);
}
}
@Override
public Fragment getCurrentVisibleFragment() {
return mCurrentVisibleFragment;
}
@Override
public void onDetachFragment(Fragment fragment) {
}
@Override
public void onSetUserVisibleHint(Fragment fragment, boolean isVisibleToUser) {
mCurrentVisibleFragment = isVisibleToUser ? fragment : null;
}
@Override
public boolean triggerRefresh(int position) {
return false;
}
@Override
public boolean getSystemWindowsInsets(Rect insets) {
return false;
}
static class FriendshipLoader extends AsyncTaskLoader<SingleResponse<Relationship>> {
private final Context context;
@ -1194,6 +1195,7 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
private float mFactor;
private int mColor;
private int mAlpha;
public ActionBarDrawable(Resources resources, Drawable shadow, Drawable background,
boolean colorLineOnly) {
@ -1204,17 +1206,7 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
mLineDrawable = (LineBackgroundDrawable) getDrawable(2);
mColorDrawable = (ColorDrawable) getDrawable(3);
mColorLineOnly = colorLineOnly;
}
public void setColor(int color) {
mColor = color;
final float[] hsv = new float[3];
Color.colorToHSV(color, hsv);
hsv[2] = Math.min(hsv[2], 0.8f);
final int processedColor = Color.HSVToColor(hsv);
mColorDrawable.setColor(processedColor);
mLineDrawable.setColor(color);
setFactor(mFactor);
setAlpha(0xFF);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@ -1228,6 +1220,13 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
}
}
@Override
public void setAlpha(int alpha) {
super.setAlpha(alpha);
mAlpha = alpha;
setFactor(mFactor);
}
@Override
public int getIntrinsicWidth() {
final boolean showColor = !mColorLineOnly && mColor != 0;
@ -1248,16 +1247,27 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
}
}
public void setColor(int color) {
mColor = color;
final float[] hsv = new float[3];
Color.colorToHSV(color, hsv);
hsv[2] = Math.min(hsv[2], 0.8f);
final int processedColor = Color.HSVToColor(hsv);
mColorDrawable.setColor(processedColor);
mLineDrawable.setColor(color);
setFactor(mFactor);
}
public void setFactor(float f) {
mFactor = f;
mShadowDrawable.setAlpha(Math.round(0xFF * MathUtils.clamp(1 - f, 0, 1)));
mShadowDrawable.setAlpha(Math.round(mAlpha * MathUtils.clamp(1 - f, 0, 1)));
final boolean hasColor = mColor != 0;
final boolean showBackground = mColorLineOnly || !hasColor;
final boolean showLine = mColorLineOnly && hasColor;
final boolean showColor = !mColorLineOnly && hasColor;
mBackgroundDrawable.setAlpha(showBackground ? Math.round(0xFF * MathUtils.clamp(f, 0, 1)) : 0);
mLineDrawable.setAlpha(showLine ? Math.round(0xFF * MathUtils.clamp(f, 0, 1)) : 0);
mColorDrawable.setAlpha(showColor ? Math.round(0xFF * MathUtils.clamp(f, 0, 1)) : 0);
mBackgroundDrawable.setAlpha(showBackground ? Math.round(mAlpha * MathUtils.clamp(f, 0, 1)) : 0);
mLineDrawable.setAlpha(showLine ? Math.round(mAlpha * MathUtils.clamp(f, 0, 1)) : 0);
mColorDrawable.setAlpha(showColor ? Math.round(mAlpha * MathUtils.clamp(f, 0, 1)) : 0);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@ -1283,31 +1293,32 @@ public class UserProfileFragment extends BaseSupportFragment implements OnClickL
mBounds.bottom, mPaint);
}
public int getColor() {
return mColor;
}
@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
mBounds.set(bounds);
}
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;
}
@Override
public int getAlpha() {
return mAlpha;
}
public void setColor(int color) {
mColor = color;
updatePaint();
}
@Override
public void setAlpha(int alpha) {

View File

@ -28,36 +28,37 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.AsyncTaskLoader;
import android.support.v4.content.Loader;
import android.support.v4.view.ViewPager;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import com.astuetz.PagerSlidingTabStrip;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.support.UserListSelectorActivity;
import org.mariotaku.twidere.adapter.ListActionAdapter;
import org.mariotaku.twidere.model.ListAction;
import org.mariotaku.twidere.adapter.support.SupportTabsAdapter;
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback;
import org.mariotaku.twidere.model.ParcelableUser;
import org.mariotaku.twidere.model.ParcelableUserList;
import org.mariotaku.twidere.model.SingleResponse;
@ -68,9 +69,8 @@ import org.mariotaku.twidere.util.ParseUtils;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.TwidereLinkify;
import org.mariotaku.twidere.view.ColorLabelRelativeLayout;
import org.mariotaku.twidere.view.TwidereMenuBar;
import java.util.Locale;
import org.mariotaku.twidere.view.HeaderDrawerLayout;
import org.mariotaku.twidere.view.HeaderDrawerLayout.DrawerCallback;
import twitter4j.Twitter;
import twitter4j.TwitterException;
@ -80,37 +80,30 @@ import static android.text.TextUtils.isEmpty;
import static org.mariotaku.twidere.util.Utils.addIntentToMenu;
import static org.mariotaku.twidere.util.Utils.getAccountColor;
import static org.mariotaku.twidere.util.Utils.getDisplayName;
import static org.mariotaku.twidere.util.Utils.getLocalizedNumber;
import static org.mariotaku.twidere.util.Utils.getTwitterInstance;
import static org.mariotaku.twidere.util.Utils.openUserListMembers;
import static org.mariotaku.twidere.util.Utils.openUserListSubscribers;
import static org.mariotaku.twidere.util.Utils.openUserListTimeline;
import static org.mariotaku.twidere.util.Utils.openUserProfile;
import static org.mariotaku.twidere.util.Utils.setMenuItemAvailability;
public class UserListDetailsFragment extends BaseSupportListFragment implements OnClickListener, OnItemClickListener,
OnItemLongClickListener, OnMenuItemClickListener, LoaderCallbacks<SingleResponse<ParcelableUserList>> {
public class UserListFragment extends BaseSupportFragment implements OnClickListener,
LoaderCallbacks<SingleResponse<ParcelableUserList>>, DrawerCallback,
SystemWindowsInsetsCallback {
private ImageLoaderWrapper mProfileImageLoader;
private AsyncTwitterWrapper mTwitterWrapper;
private ImageView mProfileImageView;
private TextView mListNameView, mCreatedByView, mDescriptionView, mErrorMessageView;
private View mListContainer, mErrorRetryContainer;
private View mErrorRetryContainer, mProgressContainer;
private ColorLabelRelativeLayout mProfileContainer;
private View mDescriptionContainer;
private Button mRetryButton;
private ListView mListView;
private View mHeaderView;
private TwidereMenuBar mMenuBar;
private HeaderDrawerLayout mHeaderDrawerLayout;
private ViewPager mViewPager;
private PagerSlidingTabStrip mPagerIndicator;
private ListActionAdapter mAdapter;
private SupportTabsAdapter mPagerAdapter;
private ParcelableUserList mUserList;
private Locale mLocale;
private boolean mUserListLoaderInitialized;
private final BroadcastReceiver mStatusReceiver = new BroadcastReceiver() {
@Override
@ -131,12 +124,14 @@ public class UserListDetailsFragment extends BaseSupportListFragment implements
}
}
};
private boolean mUserListLoaderInitialized;
public void displayUserList(final ParcelableUserList userList) {
if (userList == null || getActivity() == null) return;
getLoaderManager().destroyLoader(0);
final boolean is_myself = userList.account_id == userList.user_id;
mErrorRetryContainer.setVisibility(View.GONE);
mProgressContainer.setVisibility(View.GONE);
mUserList = userList;
mProfileContainer.drawEnd(getAccountColor(getActivity(), userList.account_id));
mListNameView.setText(userList.name);
@ -151,9 +146,6 @@ public class UserListDetailsFragment extends BaseSupportListFragment implements
linkify.applyAllLinks(mDescriptionView, userList.account_id, false);
mDescriptionView.setMovementMethod(LinkMovementMethod.getInstance());
mProfileImageLoader.displayProfileImage(mProfileImageView, userList.user_profile_image_url);
mAdapter.notifyDataSetChanged();
setMenu(mMenuBar.getMenu());
mMenuBar.show();
invalidateOptionsMenu();
}
@ -170,35 +162,6 @@ public class UserListDetailsFragment extends BaseSupportListFragment implements
}
}
@Override
public void onActivityCreated(final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
mTwitterWrapper = getApplication().getTwitterWrapper();
mLocale = getResources().getConfiguration().locale;
mProfileImageLoader = getApplication().getImageLoaderWrapper();
mAdapter = new ListActionAdapter(getActivity());
mAdapter.add(new ListTimelineAction(1));
mAdapter.add(new ListMembersAction(2));
mAdapter.add(new ListSubscribersAction(3));
mProfileImageView.setOnClickListener(this);
mProfileContainer.setOnClickListener(this);
mRetryButton.setOnClickListener(this);
setListAdapter(null);
mListView = getListView();
mListView.addHeaderView(mHeaderView, null, false);
mListView.setOnItemClickListener(this);
mListView.setOnItemLongClickListener(this);
setListAdapter(mAdapter);
getUserListInfo(false);
mMenuBar.inflate(R.menu.menu_user_list);
mMenuBar.setIsBottomBar(true);
mMenuBar.setOnMenuItemClickListener(this);
setMenu(mMenuBar.getMenu());
mMenuBar.show();
}
@Override
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
switch (requestCode) {
@ -213,60 +176,48 @@ public class UserListDetailsFragment extends BaseSupportListFragment implements
super.onActivityResult(requestCode, resultCode, data);
}
@Override
public void onClick(final View view) {
switch (view.getId()) {
case R.id.retry: {
getUserListInfo(true);
break;
}
case R.id.profile_image: {
if (mUserList == null) return;
openUserProfile(getActivity(), mUserList.account_id,
mUserList.user_id, mUserList.user_screen_name, null);
break;
}
}
}
@Override
public Loader<SingleResponse<ParcelableUserList>> onCreateLoader(final int id, final Bundle args) {
mListContainer.setVisibility(View.VISIBLE);
mErrorMessageView.setText(null);
mErrorMessageView.setVisibility(View.GONE);
mErrorRetryContainer.setVisibility(View.GONE);
setListShown(false);
setProgressBarIndeterminateVisibility(true);
final long accountId = args != null ? args.getLong(EXTRA_ACCOUNT_ID, -1) : -1;
final long userId = args != null ? args.getLong(EXTRA_USER_ID, -1) : -1;
final int listId = args != null ? args.getInt(EXTRA_LIST_ID, -1) : -1;
final String listName = args != null ? args.getString(EXTRA_LIST_NAME) : null;
final String screenName = args != null ? args.getString(EXTRA_SCREEN_NAME) : null;
final boolean omitIntentExtra = args != null ? args.getBoolean(EXTRA_OMIT_INTENT_EXTRA, true) : true;
return new ParcelableUserListLoader(getActivity(), omitIntentExtra, getArguments(), accountId, listId,
listName, userId, screenName);
}
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
mHeaderView = inflater.inflate(R.layout.header_user_list_details, null);
mProfileContainer = (ColorLabelRelativeLayout) mHeaderView.findViewById(R.id.profile);
mListNameView = (TextView) mHeaderView.findViewById(R.id.list_name);
mCreatedByView = (TextView) mHeaderView.findViewById(R.id.created_by);
mDescriptionView = (TextView) mHeaderView.findViewById(R.id.description);
mProfileImageView = (ImageView) mHeaderView.findViewById(R.id.profile_image);
mDescriptionContainer = mHeaderView.findViewById(R.id.description_container);
mListContainer = super.onCreateView(inflater, container, savedInstanceState);
final View containerView = inflater.inflate(R.layout.fragment_details_page, null);
((FrameLayout) containerView.findViewById(R.id.details_container)).addView(mListContainer);
mErrorRetryContainer = containerView.findViewById(R.id.error_retry_container);
mRetryButton = (Button) containerView.findViewById(R.id.retry);
mErrorMessageView = (TextView) containerView.findViewById(R.id.error_message);
mMenuBar = (TwidereMenuBar) containerView.findViewById(R.id.menu_bar);
final View cardView = mHeaderView.findViewById(R.id.card);
ThemeUtils.applyThemeAlphaToDrawable(cardView.getContext(), cardView.getBackground());
return containerView;
return inflater.inflate(R.layout.fragment_user_list, container, false);
}
@Override
public void onActivityCreated(final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
final FragmentActivity activity = getActivity();
mHeaderDrawerLayout.setDrawerCallback(this);
mPagerAdapter = new SupportTabsAdapter(activity, getChildFragmentManager());
mViewPager.setAdapter(mPagerAdapter);
mPagerIndicator.setViewPager(mViewPager);
mTwitterWrapper = getApplication().getTwitterWrapper();
mProfileImageLoader = getApplication().getImageLoaderWrapper();
mProfileImageView.setOnClickListener(this);
mProfileContainer.setOnClickListener(this);
mRetryButton.setOnClickListener(this);
getUserListInfo(false);
setupUserPages();
}
@Override
public void onStart() {
super.onStart();
final IntentFilter filter = new IntentFilter(BROADCAST_USER_LIST_DETAILS_UPDATED);
filter.addAction(BROADCAST_USER_LIST_SUBSCRIBED);
filter.addAction(BROADCAST_USER_LIST_UNSUBSCRIBED);
registerReceiver(mStatusReceiver, filter);
}
@Override
public void onStop() {
unregisterReceiver(mStatusReceiver);
super.onStop();
}
@Override
@ -277,48 +228,46 @@ public class UserListDetailsFragment extends BaseSupportListFragment implements
}
@Override
public void onItemClick(final AdapterView<?> adapter, final View view, final int position, final long id) {
final ListAction action = mAdapter.findItem(id);
if (action != null) {
action.onClick();
}
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_user_list, menu);
}
@Override
public boolean onItemLongClick(final AdapterView<?> adapter, final View view, final int position, final long id) {
final ListAction action = mAdapter.findItem(id);
if (action != null) return action.onLongClick();
return false;
}
@Override
public void onLoaderReset(final Loader<SingleResponse<ParcelableUserList>> loader) {
}
@Override
public void onLoadFinished(final Loader<SingleResponse<ParcelableUserList>> loader,
final SingleResponse<ParcelableUserList> data) {
if (data == null) return;
if (getActivity() == null) return;
if (data.getData() != null) {
final ParcelableUserList list = data.getData();
setListShown(true);
displayUserList(list);
mErrorRetryContainer.setVisibility(View.GONE);
} else {
if (data.hasException()) {
mErrorMessageView.setText(data.getException().getMessage());
mErrorMessageView.setVisibility(View.VISIBLE);
public void onPrepareOptionsMenu(Menu menu) {
final AsyncTwitterWrapper twitter = getTwitterWrapper();
final ParcelableUserList userList = mUserList;
final MenuItem followItem = menu.findItem(MENU_FOLLOW);
if (followItem != null) {
followItem.setEnabled(userList != null);
if (userList == null) {
followItem.setIcon(android.R.color.transparent);
}
mListContainer.setVisibility(View.GONE);
mErrorRetryContainer.setVisibility(View.VISIBLE);
}
setProgressBarIndeterminateVisibility(false);
if (twitter == null || userList == null) return;
final boolean isMyList = userList.user_id == userList.account_id;
setMenuItemAvailability(menu, MENU_EDIT, isMyList);
setMenuItemAvailability(menu, MENU_ADD, isMyList);
setMenuItemAvailability(menu, MENU_DELETE, isMyList);
final boolean isFollowing = userList.is_following;
if (followItem != null) {
followItem.setVisible(!isMyList);
if (isFollowing) {
followItem.setIcon(R.drawable.ic_action_cancel);
followItem.setTitle(R.string.unsubscribe);
} else {
followItem.setIcon(R.drawable.ic_action_add);
followItem.setTitle(R.string.subscribe);
}
}
menu.removeGroup(MENU_GROUP_USER_LIST_EXTENSION);
final Intent extensionsIntent = new Intent(INTENT_ACTION_EXTENSION_OPEN_USER_LIST);
extensionsIntent.setExtrasClassLoader(getActivity().getClassLoader());
extensionsIntent.putExtra(EXTRA_USER_LIST, mUserList);
addIntentToMenu(getActivity(), menu, extensionsIntent, MENU_GROUP_USER_LIST_EXTENSION);
}
@Override
public boolean onMenuItemClick(final MenuItem item) {
public boolean onOptionsItemSelected(final MenuItem item) {
final AsyncTwitterWrapper twitter = getTwitterWrapper();
final ParcelableUserList userList = mUserList;
if (twitter == null || userList == null) return false;
@ -371,57 +320,160 @@ public class UserListDetailsFragment extends BaseSupportListFragment implements
return true;
}
@Override
public void onStart() {
super.onStart();
final IntentFilter filter = new IntentFilter(BROADCAST_USER_LIST_DETAILS_UPDATED);
filter.addAction(BROADCAST_USER_LIST_SUBSCRIBED);
filter.addAction(BROADCAST_USER_LIST_UNSUBSCRIBED);
registerReceiver(mStatusReceiver, filter);
private void setupUserPages() {
final Context context = getActivity();
final Bundle args = getArguments(), tabArgs = new Bundle();
if (args.containsKey(EXTRA_USER)) {
final ParcelableUserList userList = args.getParcelable(EXTRA_USER_LIST);
tabArgs.putLong(EXTRA_ACCOUNT_ID, userList.account_id);
tabArgs.putLong(EXTRA_USER_ID, userList.user_id);
tabArgs.putString(EXTRA_SCREEN_NAME, userList.user_screen_name);
tabArgs.putInt(EXTRA_LIST_ID, (int) userList.id);
tabArgs.putString(EXTRA_LIST_NAME, userList.name);
} else {
tabArgs.putLong(EXTRA_ACCOUNT_ID, args.getLong(EXTRA_ACCOUNT_ID, -1));
tabArgs.putLong(EXTRA_USER_ID, args.getLong(EXTRA_USER_ID, -1));
tabArgs.putString(EXTRA_SCREEN_NAME, args.getString(EXTRA_SCREEN_NAME));
tabArgs.putInt(EXTRA_LIST_ID, args.getInt(EXTRA_LIST_ID, -1));
tabArgs.putString(EXTRA_LIST_NAME, args.getString(EXTRA_LIST_NAME));
}
mPagerAdapter.addTab(UserListTimelineFragment.class, tabArgs, getString(R.string.statuses), null, 0);
mPagerAdapter.addTab(UserListMembersFragment.class, tabArgs, getString(R.string.list_members), null, 1);
mPagerAdapter.addTab(UserListSubscribersFragment.class, tabArgs, getString(R.string.list_subscribers), null, 2);
mPagerIndicator.notifyDataSetChanged();
}
@Override
public void onStop() {
unregisterReceiver(mStatusReceiver);
super.onStop();
public void onClick(final View view) {
switch (view.getId()) {
case R.id.retry: {
getUserListInfo(true);
break;
}
case R.id.profile_image: {
if (mUserList == null) return;
openUserProfile(getActivity(), mUserList.account_id,
mUserList.user_id, mUserList.user_screen_name, null);
break;
}
}
}
@Override
public Loader<SingleResponse<ParcelableUserList>> onCreateLoader(final int id, final Bundle args) {
mErrorMessageView.setText(null);
mErrorMessageView.setVisibility(View.GONE);
mErrorRetryContainer.setVisibility(View.GONE);
mHeaderDrawerLayout.setVisibility(View.GONE);
mProgressContainer.setVisibility(View.VISIBLE);
setProgressBarIndeterminateVisibility(true);
final long accountId = args != null ? args.getLong(EXTRA_ACCOUNT_ID, -1) : -1;
final long userId = args != null ? args.getLong(EXTRA_USER_ID, -1) : -1;
final int listId = args != null ? args.getInt(EXTRA_LIST_ID, -1) : -1;
final String listName = args != null ? args.getString(EXTRA_LIST_NAME) : null;
final String screenName = args != null ? args.getString(EXTRA_SCREEN_NAME) : null;
final boolean omitIntentExtra = args == null || args.getBoolean(EXTRA_OMIT_INTENT_EXTRA, true);
return new ParcelableUserListLoader(getActivity(), omitIntentExtra, getArguments(), accountId, listId,
listName, userId, screenName);
}
@Override
public void onLoadFinished(final Loader<SingleResponse<ParcelableUserList>> loader,
final SingleResponse<ParcelableUserList> data) {
if (data == null) return;
if (getActivity() == null) return;
if (data.getData() != null) {
final ParcelableUserList list = data.getData();
displayUserList(list);
mHeaderDrawerLayout.setVisibility(View.VISIBLE);
mErrorRetryContainer.setVisibility(View.GONE);
mProgressContainer.setVisibility(View.GONE);
} else {
if (data.hasException()) {
mErrorMessageView.setText(data.getException().getMessage());
mErrorMessageView.setVisibility(View.VISIBLE);
}
mHeaderDrawerLayout.setVisibility(View.GONE);
mErrorRetryContainer.setVisibility(View.VISIBLE);
mProgressContainer.setVisibility(View.GONE);
}
setProgressBarIndeterminateVisibility(false);
}
@Override
public void onLoaderReset(final Loader<SingleResponse<ParcelableUserList>> loader) {
}
@Override
public void onViewCreated(final View view, final Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mHeaderDrawerLayout = (HeaderDrawerLayout) view.findViewById(R.id.details_container);
mErrorRetryContainer = view.findViewById(R.id.error_retry_container);
mProgressContainer = view.findViewById(R.id.progress_container);
final View headerView = mHeaderDrawerLayout.getHeader();
final View contentView = mHeaderDrawerLayout.getContent();
mProfileContainer = (ColorLabelRelativeLayout) headerView.findViewById(R.id.profile);
mListNameView = (TextView) headerView.findViewById(R.id.list_name);
mCreatedByView = (TextView) headerView.findViewById(R.id.created_by);
mDescriptionView = (TextView) headerView.findViewById(R.id.description);
mProfileImageView = (ImageView) headerView.findViewById(R.id.profile_image);
mDescriptionContainer = headerView.findViewById(R.id.description_container);
mRetryButton = (Button) mErrorRetryContainer.findViewById(R.id.retry);
mErrorMessageView = (TextView) mErrorRetryContainer.findViewById(R.id.error_message);
mViewPager = (ViewPager) contentView.findViewById(R.id.view_pager);
mPagerIndicator = (PagerSlidingTabStrip) contentView.findViewById(R.id.view_pager_tabs);
}
private void setMenu(final Menu menu) {
final AsyncTwitterWrapper twitter = getTwitterWrapper();
final ParcelableUserList userList = mUserList;
final MenuItem followItem = menu.findItem(MENU_FOLLOW);
if (followItem != null) {
followItem.setEnabled(userList != null);
if (userList == null) {
followItem.setIcon(android.R.color.transparent);
}
@Override
protected void fitSystemWindows(Rect insets) {
super.fitSystemWindows(insets);
final View progress = mProgressContainer, error = mErrorRetryContainer;
final HeaderDrawerLayout content = mHeaderDrawerLayout;
if (progress == null || error == null || content == null) {
return;
}
if (twitter == null || userList == null) return;
final boolean isMyList = userList.user_id == userList.account_id;
setMenuItemAvailability(menu, MENU_EDIT, isMyList);
setMenuItemAvailability(menu, MENU_ADD, isMyList);
setMenuItemAvailability(menu, MENU_DELETE, isMyList);
final boolean isFollowing = userList.is_following;
if (followItem != null) {
followItem.setVisible(!isMyList);
if (isFollowing) {
followItem.setIcon(R.drawable.ic_action_cancel);
followItem.setTitle(R.string.unsubscribe);
} else {
followItem.setIcon(R.drawable.ic_action_add);
followItem.setTitle(R.string.subscribe);
}
}
menu.removeGroup(MENU_GROUP_USER_LIST_EXTENSION);
final Intent extensionsIntent = new Intent(INTENT_ACTION_EXTENSION_OPEN_USER_LIST);
extensionsIntent.setExtrasClassLoader(getActivity().getClassLoader());
extensionsIntent.putExtra(EXTRA_USER_LIST, mUserList);
addIntentToMenu(getActivity(), menu, extensionsIntent, MENU_GROUP_USER_LIST_EXTENSION);
progress.setPadding(insets.left, insets.top, insets.right, insets.bottom);
error.setPadding(insets.left, insets.top, insets.right, insets.bottom);
content.setPadding(insets.left, insets.top, insets.right, insets.bottom);
content.setClipToPadding(false);
}
@Override
public void fling(float velocity) {
}
@Override
public void scrollBy(float dy) {
}
@Override
public boolean canScroll(float dy) {
return false;
}
@Override
public boolean isScrollContent(float x, float y) {
return false;
}
@Override
public void cancelTouch() {
}
@Override
public void topChanged(int offset) {
}
@Override
public boolean getSystemWindowsInsets(Rect insets) {
return false;
}
public static class EditUserListDialogFragment extends BaseSupportDialogFragment implements
@ -451,6 +503,7 @@ public class UserListDetailsFragment extends BaseSupportListFragment implements
}
@NonNull
@Override
public Dialog onCreateDialog(final Bundle savedInstanceState) {
mTwitterWrapper = getApplication().getTwitterWrapper();
@ -459,7 +512,7 @@ public class UserListDetailsFragment extends BaseSupportListFragment implements
mListId = bundle != null ? bundle.getLong(EXTRA_LIST_ID, -1) : -1;
mName = bundle != null ? bundle.getString(EXTRA_LIST_NAME) : null;
mDescription = bundle != null ? bundle.getString(EXTRA_DESCRIPTION) : null;
mIsPublic = bundle != null ? bundle.getBoolean(EXTRA_IS_PUBLIC, true) : true;
mIsPublic = bundle == null || bundle.getBoolean(EXTRA_IS_PUBLIC, true);
final Context wrapped = ThemeUtils.getDialogThemedContext(getActivity());
final AlertDialog.Builder builder = new AlertDialog.Builder(wrapped);
final View view = LayoutInflater.from(wrapped).inflate(R.layout.edit_user_list_detail, null);
@ -492,73 +545,6 @@ public class UserListDetailsFragment extends BaseSupportListFragment implements
}
class ListMembersAction extends ListAction {
public ListMembersAction(final int order) {
super(order);
}
@Override
public String getName() {
return getString(R.string.list_members);
}
@Override
public String getSummary() {
if (mUserList == null) return null;
return getLocalizedNumber(mLocale, mUserList.members_count);
}
@Override
public void onClick() {
openUserListMembers(getActivity(), mUserList);
}
}
class ListSubscribersAction extends ListAction {
public ListSubscribersAction(final int order) {
super(order);
}
@Override
public String getName() {
return getString(R.string.list_subscribers);
}
@Override
public String getSummary() {
if (mUserList == null) return null;
return getLocalizedNumber(mLocale, mUserList.subscribers_count);
}
@Override
public void onClick() {
openUserListSubscribers(getActivity(), mUserList);
}
}
class ListTimelineAction extends ListAction {
public ListTimelineAction(final int order) {
super(order);
}
@Override
public String getName() {
return getString(R.string.list_timeline);
}
@Override
public void onClick() {
if (mUserList == null) return;
openUserListTimeline(getActivity(), mUserList);
}
}
static class ParcelableUserListLoader extends AsyncTaskLoader<SingleResponse<ParcelableUserList>> {
private final boolean mOmitIntentExtra;
@ -598,9 +584,9 @@ public class UserListDetailsFragment extends BaseSupportListFragment implements
list = twitter.showUserList(mListName, mScreenName);
} else
return SingleResponse.getInstance();
return new SingleResponse<ParcelableUserList>(new ParcelableUserList(list, mAccountId), null);
return SingleResponse.getInstance(new ParcelableUserList(list, mAccountId));
} catch (final TwitterException e) {
return new SingleResponse<ParcelableUserList>(null, e);
return SingleResponse.getInstance(e);
}
}

View File

@ -19,29 +19,30 @@
package org.mariotaku.twidere.fragment.support;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.astuetz.PagerSlidingTabStrip;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.support.SupportTabsAdapter;
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback;
import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface;
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.view.ExtendedViewPager;
import org.mariotaku.twidere.view.LinePageIndicator;
public class UserListsFragment extends BaseSupportFragment implements OnPageChangeListener,
RefreshScrollTopInterface, SupportFragmentCallback {
public class UserListsFragment extends BaseSupportFragment implements RefreshScrollTopInterface,
SupportFragmentCallback, SystemWindowsInsetsCallback {
private ExtendedViewPager mViewPager;
private ViewPager mViewPager;
private SupportTabsAdapter mAdapter;
private LinePageIndicator mPagerIndicator;
private PagerSlidingTabStrip mPagerIndicator;
private Fragment mCurrentVisibleFragment;
@ -59,21 +60,18 @@ public class UserListsFragment extends BaseSupportFragment implements OnPageChan
final Bundle args = getArguments();
final FragmentActivity activity = getActivity();
mAdapter = new SupportTabsAdapter(activity, getChildFragmentManager(), null, 1);
mAdapter.addTab(UserListsListFragment.class, args, getString(R.string.lists),
R.drawable.ic_action_twitter, 0);
mAdapter.addTab(UserListsListFragment.class, args, getString(R.string.lists), null, 0);
mAdapter.addTab(UserListMembershipsListFragment.class, args,
getString(R.string.lists_following_user), R.drawable.ic_action_user, 1);
getString(R.string.lists_following_user), 0, 1);
mViewPager.setAdapter(mAdapter);
mViewPager.setOnPageChangeListener(this);
mViewPager.setOffscreenPageLimit(2);
mPagerIndicator.setSelectedColor(ThemeUtils.getThemeColor(activity));
mPagerIndicator.setViewPager(mViewPager);
}
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_search, container, false);
return inflater.inflate(R.layout.fragment_content_pages, container, false);
}
@Override
@ -81,18 +79,6 @@ public class UserListsFragment extends BaseSupportFragment implements OnPageChan
}
@Override
public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) {
}
@Override
public void onPageScrollStateChanged(final int state) {
}
@Override
public void onPageSelected(final int position) {
}
@Override
public void onSetUserVisibleHint(final Fragment fragment, final boolean isVisibleToUser) {
if (isVisibleToUser) {
@ -103,8 +89,8 @@ public class UserListsFragment extends BaseSupportFragment implements OnPageChan
@Override
public void onViewCreated(final View view, final Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mViewPager = (ExtendedViewPager) view.findViewById(R.id.search_pager);
mPagerIndicator = (LinePageIndicator) view.findViewById(R.id.search_pager_indicator);
mViewPager = (ViewPager) view.findViewById(R.id.view_pager);
mPagerIndicator = (PagerSlidingTabStrip) view.findViewById(R.id.view_pager_tabs);
}
@Override
@ -124,9 +110,24 @@ public class UserListsFragment extends BaseSupportFragment implements OnPageChan
return true;
}
@Override
protected void fitSystemWindows(Rect insets) {
super.fitSystemWindows(insets);
final View view = getView();
if (view == null) {
return;
}
view.setPadding(insets.left, insets.top, insets.right, insets.bottom);
}
@Override
public boolean triggerRefresh(final int position) {
return false;
}
@Override
public boolean getSystemWindowsInsets(Rect insets) {
return false;
}
}

View File

@ -26,7 +26,7 @@ import org.mariotaku.twidere.loader.support.UserTimelineLoader;
import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.UserProfileDrawer.DrawerCallback;
import org.mariotaku.twidere.view.HeaderDrawerLayout.DrawerCallback;
import java.util.List;

View File

@ -29,6 +29,7 @@ import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.PorterDuff.Mode;
import android.graphics.Typeface;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.os.Build;
@ -92,6 +93,15 @@ public class ThemeUtils implements Constants {
actionBar.setStackedBackgroundDrawable(getActionBarStackedBackground(context, themeRes));
}
public static void applyActionBarBackground(final ActionBar actionBar, final Context context,
final int themeRes, final int accentColor) {
if (actionBar == null || context == null) return;
actionBar.setBackgroundDrawable(getActionBarBackground(context, themeRes, accentColor));
actionBar.setSplitBackgroundDrawable(getActionBarSplitBackground(context, themeRes));
actionBar.setStackedBackgroundDrawable(getActionBarStackedBackground(context, themeRes));
}
public static void applyBackground(final View view) {
if (view == null) return;
applyBackground(view, getUserAccentColor(view.getContext()));
@ -227,6 +237,19 @@ public class ThemeUtils implements Constants {
return applyActionBarDrawable(context, d, isTransparentBackground(themeRes));
}
public static Drawable getActionBarBackground(final Context context, final int themeRes,
final int accentColor) {
if (!isDarkTheme(themeRes)) {
final ColorDrawable d = new ColorDrawable(accentColor);
return applyActionBarDrawable(context, d, isTransparentBackground(themeRes));
}
final TypedArray a = context.obtainStyledAttributes(null, new int[]{android.R.attr.background},
android.R.attr.actionBarStyle, themeRes);
final Drawable d = a.getDrawable(0);
a.recycle();
return applyActionBarDrawable(context, d, isTransparentBackground(themeRes));
}
public static Context getActionBarContext(final Context context) {
final TypedArray a = context.obtainStyledAttributes(new int[]{android.R.attr.actionBarTheme,
android.R.attr.actionBarWidgetTheme});

View File

@ -19,6 +19,7 @@
package org.mariotaku.twidere.util;
import android.annotation.TargetApi;
import android.app.ActionBar;
import android.app.Activity;
import android.content.ContentResolver;
@ -63,12 +64,14 @@ import android.provider.BaseColumns;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.ActivityOptionsCompat;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.ListFragment;
import android.support.v4.util.LongSparseArray;
import android.support.v4.util.Pair;
import android.support.v4.view.accessibility.AccessibilityEventCompat;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
@ -77,6 +80,8 @@ import android.text.format.DateUtils;
import android.text.format.Time;
import android.text.style.CharacterStyle;
import android.text.style.StyleSpan;
import android.transition.Transition;
import android.transition.TransitionInflater;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
@ -136,8 +141,9 @@ import org.mariotaku.twidere.fragment.support.StatusesListFragment;
import org.mariotaku.twidere.fragment.support.UserBlocksListFragment;
import org.mariotaku.twidere.fragment.support.UserFavoritesFragment;
import org.mariotaku.twidere.fragment.support.UserFollowersFragment;
import org.mariotaku.twidere.fragment.support.UserFragment;
import org.mariotaku.twidere.fragment.support.UserFriendsFragment;
import org.mariotaku.twidere.fragment.support.UserListDetailsFragment;
import org.mariotaku.twidere.fragment.support.UserListFragment;
import org.mariotaku.twidere.fragment.support.UserListMembersFragment;
import org.mariotaku.twidere.fragment.support.UserListMembershipsListFragment;
import org.mariotaku.twidere.fragment.support.UserListSubscribersFragment;
@ -145,7 +151,6 @@ import org.mariotaku.twidere.fragment.support.UserListTimelineFragment;
import org.mariotaku.twidere.fragment.support.UserListsFragment;
import org.mariotaku.twidere.fragment.support.UserMediaTimelineFragment;
import org.mariotaku.twidere.fragment.support.UserMentionsFragment;
import org.mariotaku.twidere.fragment.support.UserProfileFragment;
import org.mariotaku.twidere.fragment.support.UserTimelineFragment;
import org.mariotaku.twidere.fragment.support.UsersListFragment;
import org.mariotaku.twidere.graphic.PaddingDrawable;
@ -729,7 +734,7 @@ public final class Utils implements Constants, TwitterConstants {
break;
}
case LINK_ID_USER: {
fragment = new UserProfileFragment();
fragment = new UserFragment();
final String paramScreenName = uri.getQueryParameter(QUERY_PARAM_SCREEN_NAME);
final String param_user_id = uri.getQueryParameter(QUERY_PARAM_USER_ID);
if (!args.containsKey(EXTRA_SCREEN_NAME)) {
@ -839,7 +844,7 @@ public final class Utils implements Constants, TwitterConstants {
break;
}
case LINK_ID_USER_LIST: {
fragment = new UserListDetailsFragment();
fragment = new UserListFragment();
final String paramScreenName = uri.getQueryParameter(QUERY_PARAM_SCREEN_NAME);
final String param_user_id = uri.getQueryParameter(QUERY_PARAM_USER_ID);
final String param_list_id = uri.getQueryParameter(QUERY_PARAM_LIST_ID);
@ -3991,4 +3996,30 @@ public final class Utils implements Constants, TwitterConstants {
}
return null;
}
@SafeVarargs
public static Bundle makeSceneTransitionOption(final Activity activity,
final Pair<View, String>... sharedElements) {
if (ThemeUtils.isTransparentBackground(activity)) return null;
return ActivityOptionsCompat.makeSceneTransitionAnimation(activity, sharedElements).toBundle();
}
public static void setSharedElementTransition(Context context, Window window, int transitionRes) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return;
UtilsL.setSharedElementTransition(context, window, transitionRes);
}
static class UtilsL {
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
static void setSharedElementTransition(Context context, Window window, int transitionRes) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return;
window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);
final TransitionInflater inflater = TransitionInflater.from(context);
final Transition transition = inflater.inflateTransition(transitionRes);
window.setSharedElementEnterTransition(transition);
window.setSharedElementExitTransition(transition);
}
}
}

View File

@ -1,3 +1,22 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.view;
import android.annotation.SuppressLint;
@ -20,11 +39,11 @@ import org.mariotaku.twidere.R;
import org.mariotaku.twidere.util.MathUtils;
/**
* Created by mariotaku on 14/11/27.
* Custom ViewGroup for user profile page like Google+ but with tab swipe
*
* @author mariotaku
*/
public class UserProfileDrawer extends ViewGroup {
static final String LOGTAG = "UserProfileDrawer";
public class HeaderDrawerLayout extends ViewGroup {
private final ViewDragHelper mDragHelper;
private final ScrollerCompat mScroller;
@ -40,11 +59,11 @@ public class UserProfileDrawer extends ViewGroup {
private int mHeaderOffset;
public UserProfileDrawer(Context context, AttributeSet attrs, int defStyleAttr) {
public HeaderDrawerLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.UserProfileDrawer);
final int headerLayoutId = a.getResourceId(R.styleable.UserProfileDrawer_headerLayout, 0);
final int contentLayoutId = a.getResourceId(R.styleable.UserProfileDrawer_contentLayout, 0);
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.HeaderDrawerLayout);
final int headerLayoutId = a.getResourceId(R.styleable.HeaderDrawerLayout_headerLayout, 0);
final int contentLayoutId = a.getResourceId(R.styleable.HeaderDrawerLayout_contentLayout, 0);
addView(mContainer = new InternalContainer(this, context, headerLayoutId, contentLayoutId),
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
a.recycle();
@ -53,11 +72,11 @@ public class UserProfileDrawer extends ViewGroup {
mScroller = ScrollerCompat.create(context);
}
public UserProfileDrawer(Context context, AttributeSet attrs) {
public HeaderDrawerLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public UserProfileDrawer(Context context) {
public HeaderDrawerLayout(Context context) {
this(context, null);
}
@ -270,12 +289,12 @@ public class UserProfileDrawer extends ViewGroup {
private static class DragCallback extends ViewDragHelper.Callback {
private final UserProfileDrawer mDrawer;
private final HeaderDrawerLayout mDrawer;
private long mTime;
private float mDx, mDy, mVelocity;
private boolean mScrollingHeaderByHelper;
public DragCallback(UserProfileDrawer drawer) {
public DragCallback(HeaderDrawerLayout drawer) {
mDrawer = drawer;
mTime = -1;
mDx = Float.NaN;
@ -376,9 +395,9 @@ public class UserProfileDrawer extends ViewGroup {
private static class GestureListener extends SimpleOnGestureListener {
private final UserProfileDrawer mDrawer;
private final HeaderDrawerLayout mDrawer;
public GestureListener(UserProfileDrawer drawer) {
public GestureListener(HeaderDrawerLayout drawer) {
mDrawer = drawer;
}
@ -434,10 +453,10 @@ public class UserProfileDrawer extends ViewGroup {
@SuppressLint("ViewConstructor")
private static class InternalContainer extends ViewGroup {
private final UserProfileDrawer mParent;
private final HeaderDrawerLayout mParent;
private final View mHeaderView, mContentView;
public InternalContainer(UserProfileDrawer parent, Context context, int headerLayoutId, int contentLayoutId) {
public InternalContainer(HeaderDrawerLayout parent, Context context, int headerLayoutId, int contentLayoutId) {
super(context);
mParent = parent;
final LayoutInflater inflater = LayoutInflater.from(context);

View File

@ -1,69 +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.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.widget.FrameLayout;
/**
* Created by mariotaku on 14/11/26.
*/
public class HomeContentFrameLayout extends FrameLayout {
private final Paint mPaint;
private int mStatusBarHeight;
public HomeContentFrameLayout(Context context) {
this(context, null);
}
public HomeContentFrameLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public HomeContentFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
setWillNotDraw(false);
}
public void setColor(int color, int alpha) {
mPaint.setColor(color);
mPaint.setAlpha(alpha);
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawRect(0, 0, canvas.getWidth(), mStatusBarHeight, mPaint);
}
public void setStatusBarHeight(int height) {
mStatusBarHeight = height;
setPadding(0, height, 0, 0);
invalidate();
}
}

View File

@ -3,12 +3,11 @@ package org.mariotaku.twidere.view;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.widget.FrameLayout;
/**
* Created by mariotaku on 14/10/20.
*/
public class MainFrameLayout extends FrameLayout {
public class MainFrameLayout extends TintedStatusFrameLayout {
public MainFrameLayout(Context context) {
super(context);
}
@ -22,15 +21,11 @@ public class MainFrameLayout extends FrameLayout {
}
@Override
protected boolean fitSystemWindows(Rect insets) {
final Context context = getContext();
if (context instanceof FitSystemWindowsCallback) {
((FitSystemWindowsCallback) context).fitSystemWindows(insets);
}
return super.fitSystemWindows(insets);
public void setStatusBarHeight(int height) {
setPadding(0, height, 0, 0);
super.setStatusBarHeight(height);
}
public static interface FitSystemWindowsCallback {
void fitSystemWindows(Rect insets);
}

View File

@ -30,11 +30,12 @@ import android.widget.FrameLayout;
import org.mariotaku.twidere.util.MathUtils;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.MainFrameLayout.FitSystemWindowsCallback;
/**
* Created by mariotaku on 14/11/26.
*/
public class UserProfileContentFrameLayout extends FrameLayout {
public class TintedStatusFrameLayout extends FrameLayout {
private final Paint mBlackPaint, mShadowPaint, mColorPaint;
@ -43,15 +44,15 @@ public class UserProfileContentFrameLayout extends FrameLayout {
private int mColorAlpha, mShadowAlpha;
private boolean mDrawShadow, mDrawColor;
public UserProfileContentFrameLayout(Context context) {
public TintedStatusFrameLayout(Context context) {
this(context, null);
}
public UserProfileContentFrameLayout(Context context, AttributeSet attrs) {
public TintedStatusFrameLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public UserProfileContentFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
public TintedStatusFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mBlackPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBlackPaint.setColor(Color.BLACK);
@ -60,9 +61,14 @@ public class UserProfileContentFrameLayout extends FrameLayout {
setWillNotDraw(false);
}
public void setColor(int color) {
setColor(color, Color.alpha(color));
}
public void setColor(int color, int alpha) {
mColorPaint.setColor(color);
mColorAlpha = Color.alpha(color);
mColorAlpha = alpha;
updateAlpha();
}
@ -75,6 +81,10 @@ public class UserProfileContentFrameLayout extends FrameLayout {
@Override
protected boolean fitSystemWindows(Rect insets) {
setStatusBarHeight(Utils.getInsetsTopWithoutActionBarHeight(getContext(), insets.top));
final Context context = getContext();
if (context instanceof FitSystemWindowsCallback) {
((FitSystemWindowsCallback) context).fitSystemWindows(insets);
}
return false;
}
@ -89,7 +99,7 @@ public class UserProfileContentFrameLayout extends FrameLayout {
canvas.drawRect(0, 0, canvas.getWidth(), mStatusBarHeight, mDrawColor ? mColorPaint : mBlackPaint);
}
private void setStatusBarHeight(int height) {
protected void setStatusBarHeight(int height) {
mStatusBarHeight = height;
invalidate();
}

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<org.mariotaku.twidere.view.MainFrameLayout
android:id="@+id/content_fragment"
<org.mariotaku.twidere.view.TintedStatusFrameLayout
android:id="@+id/main_content"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<org.mariotaku.twidere.view.HomeContentFrameLayout
<org.mariotaku.twidere.view.MainFrameLayout
android:id="@+id/home_content"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
@ -34,4 +34,4 @@
</LinearLayout>
<include layout="@layout/layout_home_actions_button"/>
</org.mariotaku.twidere.view.HomeContentFrameLayout>
</org.mariotaku.twidere.view.MainFrameLayout>

View File

@ -1,58 +1,67 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--
~ 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/>.
-->
<LinearLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.mariotaku.twidere.view.ExtendedFrameLayout
android:id="@+id/details_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<org.mariotaku.twidere.view.ActionBarSplitThemedContainer
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout="@layout/fragment_details_bottombar"/>
</LinearLayout>
<org.mariotaku.twidere.view.ExtendedFrameLayout
android:id="@+id/details_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<ProgressBar
android:id="@+id/details_load_progress"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"/>
<LinearLayout
android:id="@+id/error_retry_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:padding="16dp"
android:visibility="gone">
<ProgressBar
android:id="@+id/details_load_progress"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"/>
<TextView
android:id="@+id/error_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:visibility="gone"/>
<LinearLayout
android:id="@+id/error_retry_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:padding="16dp"
android:visibility="gone">
<Button
android:id="@+id/retry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="48dp"
android:minWidth="84dp"
android:text="@string/retry"
android:textAppearance="?android:attr/textAppearanceSmall"/>
</LinearLayout>
<TextView
android:id="@+id/error_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:visibility="gone"/>
<Button
android:id="@+id/retry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="48dp"
android:minWidth="84dp"
android:text="@string/retry"
android:textAppearance="?android:attr/textAppearanceSmall"/>
</LinearLayout>
</FrameLayout>

View File

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<org.mariotaku.twidere.view.ExtendedFrameLayout
android:id="@+id/details_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<org.mariotaku.twidere.view.ActionBarSplitThemedContainer
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout="@layout/fragment_details_bottombar"/>
</LinearLayout>
<ProgressBar
android:id="@+id/details_load_progress"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"/>
<LinearLayout
android:id="@+id/error_retry_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:padding="16dp"
android:visibility="gone">
<TextView
android:id="@+id/error_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:visibility="gone"/>
<Button
android:id="@+id/retry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="48dp"
android:minWidth="84dp"
android:text="@string/retry"
android:textAppearance="?android:attr/textAppearanceSmall"/>
</LinearLayout>
</FrameLayout>

View File

@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragment.SearchFragment">
<org.mariotaku.twidere.view.ExtendedViewPager
android:id="@+id/search_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<org.mariotaku.twidere.view.LinePageIndicator
android:id="@+id/search_pager_indicator"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:padding="@dimen/element_spacing_normal"/>
</FrameLayout>

View File

@ -0,0 +1,51 @@
<?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/>.
-->
<FrameLayout
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:animateLayoutChanges="true">
<org.mariotaku.twidere.view.ExtendedFrameLayout
android:id="@+id/details_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.mariotaku.twidere.view.ProfileBannerImageView
android:id="@+id/profile_banner"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:scaleType="centerCrop"/>
<org.mariotaku.twidere.view.HeaderDrawerLayout
android:id="@+id/user_profile_drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentLayout="@layout/fragment_content_pages"
app:headerLayout="@layout/header_user"/>
</org.mariotaku.twidere.view.ExtendedFrameLayout>
<include layout="@layout/layout_content_fragment_common"/>
</FrameLayout>

View File

@ -0,0 +1,37 @@
<?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/>.
-->
<FrameLayout
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:animateLayoutChanges="true">
<org.mariotaku.twidere.view.HeaderDrawerLayout
android:id="@+id/details_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentLayout="@layout/fragment_content_pages"
app:headerLayout="@layout/header_user_list_details"/>
<include layout="@layout/layout_content_fragment_common"/>
</FrameLayout>

View File

@ -306,4 +306,21 @@
</LinearLayout>
</android.support.v7.widget.CardView>
<org.mariotaku.twidere.view.AssetFontTextView
android:id="@+id/uucky_footer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/card"
android:alpha="0.2"
android:gravity="center"
android:padding="@dimen/element_spacing_small"
android:text="- Luna meae es -"
android:textColor="?android:textColorPrimary"
android:textSize="10sp"
android:textStyle="italic"
android:typeface="serif"
android:visibility="gone"
app:fontPath="fonts/LibreBaskerville-Italic.ttf"/>
</RelativeLayout>

View File

@ -1,94 +1,103 @@
<?xml version="1.0" encoding="utf-8"?>
<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:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:activatedBackgroundIndicator"
tools:context=".fragment.support.UserListDetailsFragment">
<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:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".fragment.support.UserListDetailsFragment">
<org.mariotaku.twidere.view.CardItemLinearLayout
android:id="@+id/card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="@dimen/element_spacing_normal"
android:splitMotionEvents="false">
<android.support.v7.widget.CardView
android:id="@+id/card"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_margin="@dimen/element_spacing_normal"
app:cardBackgroundColor="?cardItemBackgroundColor"
app:cardCornerRadius="@dimen/corner_radius_card"
app:cardElevation="@dimen/elevation_card">
<org.mariotaku.twidere.view.ColorLabelRelativeLayout
android:id="@+id/profile"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:selectableItemBackground"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="@dimen/element_spacing_normal"
app:ignorePadding="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="@dimen/element_spacing_normal"
android:splitMotionEvents="false">
<org.mariotaku.twidere.view.CircularImageView
android:id="@+id/profile_image"
android:layout_width="@dimen/icon_size_card_details"
android:layout_height="@dimen/icon_size_card_details"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:contentDescription="@string/profile_image"
android:foreground="?android:selectableItemBackground"
android:scaleType="fitCenter"
android:src="@drawable/ic_profile_image_default"/>
<org.mariotaku.twidere.view.ColorLabelRelativeLayout
android:id="@+id/profile"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:selectableItemBackground"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="@dimen/element_spacing_normal"
app:ignorePadding="true">
<LinearLayout
android:id="@+id/name_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="@id/profile_image"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingLeft="@dimen/element_spacing_normal">
<org.mariotaku.twidere.view.CircularImageView
android:id="@+id/profile_image"
android:layout_width="@dimen/icon_size_card_details"
android:layout_height="@dimen/icon_size_card_details"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:contentDescription="@string/profile_image"
android:foreground="?android:selectableItemBackground"
android:scaleType="fitCenter"
android:src="@drawable/ic_profile_image_default"/>
<org.mariotaku.twidere.view.themed.ThemedTextView
android:id="@+id/list_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<LinearLayout
android:id="@+id/name_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="@id/profile_image"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingLeft="@dimen/element_spacing_normal">
<org.mariotaku.twidere.view.themed.ThemedTextView
android:id="@+id/created_by"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"/>
</LinearLayout>
</org.mariotaku.twidere.view.ColorLabelRelativeLayout>
<org.mariotaku.twidere.view.themed.ThemedTextView
android:id="@+id/list_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<View
android:layout_width="match_parent"
android:layout_height="0.2dp"
android:background="#40808080"/>
<org.mariotaku.twidere.view.themed.ThemedTextView
android:id="@+id/created_by"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"/>
</LinearLayout>
</org.mariotaku.twidere.view.ColorLabelRelativeLayout>
<LinearLayout
android:id="@+id/description_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:selectableItemBackground"
android:orientation="vertical"
android:padding="@dimen/element_spacing_small">
<View
android:layout_width="match_parent"
android:layout_height="0.2dp"
android:background="#40808080"/>
<org.mariotaku.twidere.view.themed.ThemedTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/description"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<LinearLayout
android:id="@+id/description_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:selectableItemBackground"
android:orientation="vertical"
android:padding="@dimen/element_spacing_small">
<org.mariotaku.twidere.view.themed.ThemedTextView
android:id="@+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"/>
</LinearLayout>
</org.mariotaku.twidere.view.CardItemLinearLayout>
<org.mariotaku.twidere.view.themed.ThemedTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/description"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<org.mariotaku.twidere.view.themed.ThemedTextView
android:id="@+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"/>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
</FrameLayout>

View File

@ -18,34 +18,7 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<org.mariotaku.twidere.view.UserProfileContentFrameLayout
android:id="@+id/user_profile_fragment"
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:animateLayoutChanges="true">
<org.mariotaku.twidere.view.ExtendedFrameLayout
android:id="@+id/details_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.mariotaku.twidere.view.ProfileBannerImageView
android:id="@+id/profile_banner"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:scaleType="centerCrop"/>
<org.mariotaku.twidere.view.UserProfileDrawer
android:id="@+id/user_profile_drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentLayout="@layout/fragment_user_profile_pages"
app:headerLayout="@layout/header_user_profile"/>
</org.mariotaku.twidere.view.ExtendedFrameLayout>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<FrameLayout
android:id="@+id/progress_container"
@ -86,4 +59,4 @@
</LinearLayout>
</org.mariotaku.twidere.view.UserProfileContentFrameLayout>
</merge>

View File

@ -83,7 +83,7 @@
<attr name="borderColor" format="color"/>
<attr name="elevation" format="dimension"/>
</declare-styleable>
<declare-styleable name="UserProfileDrawer">
<declare-styleable name="HeaderDrawerLayout">
<attr name="headerLayout" format="reference"/>
<attr name="contentLayout" format="reference"/>
</declare-styleable>