redesigned account select button
improved actionbar shadow appearance on android L
This commit is contained in:
parent
cc2f794025
commit
10ac7ccf52
|
@ -0,0 +1,40 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2013 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<!-- package name must be unique so suffix with "tests" so package loader doesn't ignore us -->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.mariotaku.twidere.test"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
|
||||
<!-- Min/target SDK versions (<uses-sdk>) managed by build.gradle -->
|
||||
|
||||
<!-- We add an application tag here just so that we can indicate that
|
||||
this package needs to link against the android.test library,
|
||||
which is needed when building test cases. -->
|
||||
<application>
|
||||
<uses-library android:name="android.test.runner"/>
|
||||
</application>
|
||||
|
||||
<!--
|
||||
Specifies the instrumentation test runner used to run the tests.
|
||||
-->
|
||||
<instrumentation
|
||||
android:name="android.test.InstrumentationTestRunner"
|
||||
android:targetPackage="org.mariotaku.twidere"
|
||||
android:label="Tests for org.mariotaku.twidere"/>
|
||||
|
||||
</manifest>
|
|
@ -1,13 +0,0 @@
|
|||
package org.mariotaku.myapplication;
|
||||
|
||||
import android.app.Application;
|
||||
import android.test.ApplicationTestCase;
|
||||
|
||||
/**
|
||||
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
|
||||
*/
|
||||
public class ApplicationTest extends ApplicationTestCase<Application> {
|
||||
public ApplicationTest() {
|
||||
super(Application.class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package org.mariotaku.twidere.test;
|
||||
|
||||
import android.test.ApplicationTestCase;
|
||||
|
||||
import org.mariotaku.twidere.app.TwidereApplication;
|
||||
|
||||
/**
|
||||
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
|
||||
*/
|
||||
public class TwidereApplicationTest extends ApplicationTestCase<TwidereApplication> {
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public TwidereApplicationTest() {
|
||||
super(TwidereApplication.class);
|
||||
}
|
||||
|
||||
}
|
|
@ -97,12 +97,12 @@ public abstract class BaseSupportThemedActivity extends FragmentActivity impleme
|
|||
@Override
|
||||
protected void onTitleChanged(CharSequence title, int color) {
|
||||
final SpannableStringBuilder builder = new SpannableStringBuilder(title);
|
||||
super.onTitleChanged(title, color);
|
||||
final int themeResId = getCurrentThemeResourceId();
|
||||
final int themeColor = getThemeColor(), contrastColor = Utils.getContrastYIQ(themeColor, 192);
|
||||
if (!ThemeUtils.isDarkTheme(themeResId)) {
|
||||
builder.setSpan(new ForegroundColorSpan(contrastColor), 0, builder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
super.onTitleChanged(title, color);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -105,7 +105,7 @@ import org.mariotaku.twidere.util.ThemeUtils;
|
|||
import org.mariotaku.twidere.util.TwidereValidator;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.util.accessor.ViewAccessor;
|
||||
import org.mariotaku.twidere.view.ColorLabelFrameLayout;
|
||||
import org.mariotaku.twidere.view.ComposeSelectAccountButton;
|
||||
import org.mariotaku.twidere.view.StatusTextCountView;
|
||||
import org.mariotaku.twidere.view.TwidereMenuBar;
|
||||
import org.mariotaku.twidere.view.holder.StatusListViewHolder;
|
||||
|
@ -132,7 +132,6 @@ import static org.mariotaku.twidere.util.ThemeUtils.getWindowContentOverlayForCo
|
|||
import static org.mariotaku.twidere.util.UserColorNicknameUtils.getUserColor;
|
||||
import static org.mariotaku.twidere.util.Utils.addIntentToMenu;
|
||||
import static org.mariotaku.twidere.util.Utils.copyStream;
|
||||
import static org.mariotaku.twidere.util.Utils.getAccountColors;
|
||||
import static org.mariotaku.twidere.util.Utils.getAccountIds;
|
||||
import static org.mariotaku.twidere.util.Utils.getAccountName;
|
||||
import static org.mariotaku.twidere.util.Utils.getAccountScreenName;
|
||||
|
@ -180,7 +179,7 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa
|
|||
private ProgressBar mProgress;
|
||||
private View mSendView;
|
||||
private StatusTextCountView mSendTextCountView;
|
||||
private ColorLabelFrameLayout mSelectAccountButton;
|
||||
private ComposeSelectAccountButton mSelectAccountAccounts;
|
||||
|
||||
private MediaPreviewAdapter mMediaPreviewAdapter;
|
||||
|
||||
|
@ -438,7 +437,7 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa
|
|||
final View composeBottomBar = findViewById(R.id.compose_bottombar);
|
||||
mSendView = composeBottomBar.findViewById(R.id.send);
|
||||
mSendTextCountView = (StatusTextCountView) mSendView.findViewById(R.id.status_text_count);
|
||||
mSelectAccountButton = (ColorLabelFrameLayout) composeActionBar.findViewById(R.id.select_account);
|
||||
mSelectAccountAccounts = (ComposeSelectAccountButton) composeActionBar.findViewById(R.id.select_account);
|
||||
ViewAccessor.setBackground(findViewById(R.id.compose_content), getWindowContentOverlayForCompose(this));
|
||||
ViewAccessor.setBackground(composeActionBar, getActionBarBackground(this, getCurrentThemeResourceId()));
|
||||
}
|
||||
|
@ -581,12 +580,12 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa
|
|||
mAccountSelectorPopup.setModal(true);
|
||||
mAccountSelectorPopup.setContentWidth(getResources().getDimensionPixelSize(R.dimen.account_selector_popup_width));
|
||||
mAccountSelectorPopup.setAdapter(accountAdapter);
|
||||
mAccountSelectorPopup.setAnchorView(mSelectAccountButton);
|
||||
mAccountSelectorPopup.setAnchorView(mSelectAccountAccounts);
|
||||
// mSelectAccountButton.setOnTouchListener(ListPopupWindowCompat.createDragToOpenListener(
|
||||
// mAccountSelectorPopup, mSelectAccountButton));
|
||||
|
||||
mSelectAccountButton.setOnClickListener(this);
|
||||
mSelectAccountButton.setOnLongClickListener(this);
|
||||
mSelectAccountAccounts.setOnClickListener(this);
|
||||
mSelectAccountAccounts.setOnLongClickListener(this);
|
||||
|
||||
mMediaPreviewAdapter = new MediaPreviewAdapter(this);
|
||||
mMediaPreviewGrid.setAdapter(mMediaPreviewAdapter);
|
||||
|
@ -1032,7 +1031,7 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa
|
|||
editor.putString(KEY_COMPOSE_ACCOUNTS, ArrayUtils.toString(mSendAccountIds, ',', false));
|
||||
editor.apply();
|
||||
}
|
||||
mSelectAccountButton.drawEnd(getAccountColors(this, mSendAccountIds));
|
||||
mSelectAccountAccounts.setSelectedAccounts(mSendAccountIds);
|
||||
}
|
||||
|
||||
private void updateMediaPreview() {
|
||||
|
@ -1492,4 +1491,6 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa
|
|||
return Collections.unmodifiableList(getObjects());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -105,9 +105,6 @@ import org.mariotaku.twidere.view.TabPagerIndicator;
|
|||
import org.mariotaku.twidere.view.TintedStatusFrameLayout;
|
||||
import org.mariotaku.twidere.view.iface.IHomeActionButton;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import edu.ucdavis.earlybird.ProfilingUtil;
|
||||
|
||||
import static org.mariotaku.twidere.util.CompareUtils.classEquals;
|
||||
|
@ -132,8 +129,6 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
|
|||
|
||||
private final ContentObserver mAccountChangeObserver = new AccountChangeObserver(this, mHandler);
|
||||
|
||||
private final ArrayList<SupportTabSpec> mCustomTabs = new ArrayList<>();
|
||||
|
||||
private final SparseArray<Fragment> mAttachedFragments = new SparseArray<>();
|
||||
private ParcelableAccount mSelectedAccountToSearch;
|
||||
|
||||
|
@ -645,7 +640,7 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
|
|||
resolver.registerContentObserver(Accounts.CONTENT_URI, true, mAccountChangeObserver);
|
||||
final Bus bus = TwidereApplication.getInstance(this).getMessageBus();
|
||||
bus.register(this);
|
||||
if (isTabsChanged(getHomeTabs(this)) || getTabDisplayOptionInt(this) != mTabDisplayOption) {
|
||||
if (getTabDisplayOptionInt(this) != mTabDisplayOption) {
|
||||
restart();
|
||||
}
|
||||
// UCD
|
||||
|
@ -725,13 +720,11 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
|
|||
}
|
||||
|
||||
private void setupHomeTabs() {
|
||||
final List<SupportTabSpec> tabs = getHomeTabs(this);
|
||||
mCustomTabs.clear();
|
||||
mCustomTabs.addAll(tabs);
|
||||
mPagerAdapter.clear();
|
||||
mPagerAdapter.addTabs(tabs);
|
||||
mEmptyTabHint.setVisibility(tabs.isEmpty() ? View.VISIBLE : View.GONE);
|
||||
mViewPager.setVisibility(tabs.isEmpty() ? View.GONE : View.VISIBLE);
|
||||
mPagerAdapter.addTabs(getHomeTabs(this));
|
||||
final boolean hasNoTab = mPagerAdapter.getCount() == 0;
|
||||
mEmptyTabHint.setVisibility(hasNoTab ? View.VISIBLE : View.GONE);
|
||||
mViewPager.setVisibility(hasNoTab ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
|
||||
private void initUnreadCount() {
|
||||
|
@ -740,15 +733,6 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
|
|||
}
|
||||
}
|
||||
|
||||
private boolean isTabsChanged(final List<SupportTabSpec> tabs) {
|
||||
if (mCustomTabs.size() == 0 && tabs == null) return false;
|
||||
if (mCustomTabs.size() != tabs.size()) return true;
|
||||
for (int i = 0, size = mCustomTabs.size(); i < size; i++) {
|
||||
if (!mCustomTabs.get(i).equals(tabs.get(i))) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void openAccountsDrawer() {
|
||||
if (mSlidingMenu == null) return;
|
||||
mSlidingMenu.showMenu();
|
||||
|
|
|
@ -211,10 +211,10 @@ public class LinkHandlerActivity extends BaseSupportActivity implements OnClickL
|
|||
transitionRes = R.transition.transition_user;
|
||||
break;
|
||||
}
|
||||
case LINK_ID_STATUS: {
|
||||
transitionRes = R.transition.transition_status;
|
||||
break;
|
||||
}
|
||||
// case LINK_ID_STATUS: {
|
||||
// transitionRes = R.transition.transition_status;
|
||||
// break;
|
||||
// }
|
||||
default: {
|
||||
transitionRes = 0;
|
||||
break;
|
||||
|
|
|
@ -40,7 +40,7 @@ public abstract class AbsStatusesAdapter<D> extends Adapter<ViewHolder> implemen
|
|||
private final int mCardLayoutResource;
|
||||
private boolean mLoadMoreIndicatorEnabled;
|
||||
|
||||
private EventListener mEventListener;
|
||||
private StatusAdapterListener mStatusAdapterListener;
|
||||
|
||||
public AbsStatusesAdapter(Context context, boolean compact) {
|
||||
mContext = context;
|
||||
|
@ -127,8 +127,8 @@ public abstract class AbsStatusesAdapter<D> extends Adapter<ViewHolder> implemen
|
|||
|
||||
@Override
|
||||
public final void onStatusClick(StatusViewHolder holder, int position) {
|
||||
if (mEventListener != null) {
|
||||
mEventListener.onStatusClick(holder, position);
|
||||
if (mStatusAdapterListener != null) {
|
||||
mStatusAdapterListener.onStatusClick(holder, position);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -150,15 +150,15 @@ public abstract class AbsStatusesAdapter<D> extends Adapter<ViewHolder> implemen
|
|||
|
||||
@Override
|
||||
public void onItemActionClick(ViewHolder holder, int id, int position) {
|
||||
if (mEventListener != null) {
|
||||
mEventListener.onStatusActionClick((StatusViewHolder) holder, id, position);
|
||||
if (mStatusAdapterListener != null) {
|
||||
mStatusAdapterListener.onStatusActionClick((StatusViewHolder) holder, id, position);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemMenuClick(ViewHolder holder, int position) {
|
||||
if (mEventListener != null) {
|
||||
mEventListener.onStatusMenuClick((StatusViewHolder) holder, position);
|
||||
if (mStatusAdapterListener != null) {
|
||||
mStatusAdapterListener.onStatusMenuClick((StatusViewHolder) holder, position);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -166,18 +166,18 @@ public abstract class AbsStatusesAdapter<D> extends Adapter<ViewHolder> implemen
|
|||
|
||||
public abstract D getData();
|
||||
|
||||
public void setEventListener(EventListener listener) {
|
||||
mEventListener = listener;
|
||||
public void setEventListener(StatusAdapterListener listener) {
|
||||
mStatusAdapterListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onGapClick(ViewHolder holder, int position) {
|
||||
if (mEventListener != null) {
|
||||
mEventListener.onGapClick((GapViewHolder) holder, position);
|
||||
if (mStatusAdapterListener != null) {
|
||||
mStatusAdapterListener.onGapClick((GapViewHolder) holder, position);
|
||||
}
|
||||
}
|
||||
|
||||
public static interface EventListener {
|
||||
public static interface StatusAdapterListener {
|
||||
void onStatusActionClick(StatusViewHolder holder, int id, int position);
|
||||
|
||||
void onStatusClick(StatusViewHolder holder, int position);
|
||||
|
|
|
@ -8,10 +8,8 @@ import android.content.SharedPreferences;
|
|||
import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.support.v4.util.Pair;
|
||||
import android.support.v4.widget.SwipeRefreshLayout;
|
||||
import android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
|
@ -23,7 +21,7 @@ import android.view.ViewGroup;
|
|||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.AbsStatusesAdapter;
|
||||
import org.mariotaku.twidere.adapter.AbsStatusesAdapter.EventListener;
|
||||
import org.mariotaku.twidere.adapter.AbsStatusesAdapter.StatusAdapterListener;
|
||||
import org.mariotaku.twidere.adapter.decorator.DividerItemDecoration;
|
||||
import org.mariotaku.twidere.constant.IntentConstants;
|
||||
import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface;
|
||||
|
@ -40,7 +38,7 @@ import org.mariotaku.twidere.view.holder.StatusViewHolder;
|
|||
* Created by mariotaku on 14/11/5.
|
||||
*/
|
||||
public abstract class AbsStatusesFragment<Data> extends BaseSupportFragment implements LoaderCallbacks<Data>,
|
||||
OnRefreshListener, DrawerCallback, RefreshScrollTopInterface, EventListener {
|
||||
OnRefreshListener, DrawerCallback, RefreshScrollTopInterface, StatusAdapterListener {
|
||||
|
||||
|
||||
private final BroadcastReceiver mStateReceiver = new BroadcastReceiver() {
|
||||
|
@ -204,19 +202,7 @@ public abstract class AbsStatusesFragment<Data> extends BaseSupportFragment impl
|
|||
|
||||
@Override
|
||||
public void onStatusClick(StatusViewHolder holder, int position) {
|
||||
final FragmentActivity activity = getActivity();
|
||||
final Bundle activityOption = Utils.makeSceneTransitionOption(activity,
|
||||
new Pair<View, String>(holder.getProfileImageView(), StatusFragment.TRANSITION_NAME_PROFILE_IMAGE),
|
||||
new Pair<View, String>(holder.getProfileTypeView(), StatusFragment.TRANSITION_NAME_PROFILE_TYPE));
|
||||
Utils.openStatus(getActivity(), mAdapter.getStatus(position), activityOption);
|
||||
// final View cardView = holder.getCardView();
|
||||
// if (cardView != null && context instanceof FragmentActivity) {
|
||||
// final Bundle options = Utils.makeSceneTransitionOption((FragmentActivity) context,
|
||||
// new Pair<>(cardView, StatusFragment.TRANSITION_NAME_CARD));
|
||||
// Utils.openStatus(context, getStatus(position), options);
|
||||
// } else {
|
||||
// Utils.openStatus(context, getStatus(position), null);
|
||||
// }
|
||||
Utils.openStatus(getActivity(), mAdapter.getStatus(position), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -494,7 +494,7 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement
|
|||
|
||||
@Override
|
||||
public AccountProfileImageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
final View view = mInflater.inflate(R.layout.adapter_item_compose_account, parent, false);
|
||||
final View view = mInflater.inflate(R.layout.adapter_item_dashboard_account, parent, false);
|
||||
return new AccountProfileImageViewHolder(this, view);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,11 +19,13 @@
|
|||
|
||||
package org.mariotaku.twidere.fragment.support;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
|
@ -32,7 +34,6 @@ import android.support.v4.app.FragmentActivity;
|
|||
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.support.v4.util.Pair;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.support.v7.widget.CardView;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
|
@ -73,6 +74,7 @@ import org.mariotaku.twidere.task.TwidereAsyncTask.Status;
|
|||
import org.mariotaku.twidere.text.method.StatusContentMovementMethod;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
import org.mariotaku.twidere.util.ClipboardUtils;
|
||||
import org.mariotaku.twidere.util.CompareUtils;
|
||||
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
||||
import org.mariotaku.twidere.util.ImageLoadingHandler;
|
||||
import org.mariotaku.twidere.util.MediaPreviewUtils;
|
||||
|
@ -94,15 +96,18 @@ import java.util.Locale;
|
|||
import twitter4j.TwitterException;
|
||||
|
||||
import static android.text.TextUtils.isEmpty;
|
||||
import static org.mariotaku.twidere.util.UserColorNicknameUtils.clearUserColor;
|
||||
import static org.mariotaku.twidere.util.UserColorNicknameUtils.clearUserNickname;
|
||||
import static org.mariotaku.twidere.util.UserColorNicknameUtils.getUserColor;
|
||||
import static org.mariotaku.twidere.util.UserColorNicknameUtils.getUserNickname;
|
||||
import static org.mariotaku.twidere.util.UserColorNicknameUtils.setUserColor;
|
||||
import static org.mariotaku.twidere.util.Utils.cancelRetweet;
|
||||
import static org.mariotaku.twidere.util.Utils.findStatus;
|
||||
import static org.mariotaku.twidere.util.Utils.formatToLongTimeString;
|
||||
import static org.mariotaku.twidere.util.Utils.getLocalizedNumber;
|
||||
import static org.mariotaku.twidere.util.Utils.getUserTypeIconRes;
|
||||
import static org.mariotaku.twidere.util.Utils.isMyRetweet;
|
||||
import static org.mariotaku.twidere.util.Utils.openStatus;
|
||||
import static org.mariotaku.twidere.util.Utils.openUserProfile;
|
||||
import static org.mariotaku.twidere.util.Utils.setMenuForStatus;
|
||||
import static org.mariotaku.twidere.util.Utils.showErrorMessage;
|
||||
|
@ -115,9 +120,6 @@ import static org.mariotaku.twidere.util.Utils.startStatusShareChooser;
|
|||
public class StatusFragment extends BaseSupportFragment
|
||||
implements LoaderCallbacks<SingleResponse<ParcelableStatus>>, OnMediaClickListener {
|
||||
|
||||
public static final String TRANSITION_NAME_PROFILE_IMAGE = "profile_image";
|
||||
public static final String TRANSITION_NAME_PROFILE_TYPE = "profile_type";
|
||||
|
||||
private static final int LOADER_ID_DETAIL_STATUS = 1;
|
||||
private static final int LOADER_ID_STATUS_REPLIES = 2;
|
||||
|
||||
|
@ -153,6 +155,34 @@ public class StatusFragment extends BaseSupportFragment
|
|||
};
|
||||
private LinearLayoutManager mLayoutManager;
|
||||
|
||||
@Override
|
||||
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
|
||||
switch (requestCode) {
|
||||
case REQUEST_SET_COLOR: {
|
||||
final ParcelableStatus status = mStatusAdapter.getStatus();
|
||||
if (status == null) return;
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
if (data == null) return;
|
||||
final int color = data.getIntExtra(EXTRA_COLOR, Color.TRANSPARENT);
|
||||
setUserColor(getActivity(), status.user_id, color);
|
||||
} else if (resultCode == ColorPickerDialogActivity.RESULT_CLEARED) {
|
||||
clearUserColor(getActivity(), status.user_id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case REQUEST_SELECT_ACCOUNT: {
|
||||
final ParcelableStatus status = mStatusAdapter.getStatus();
|
||||
if (status == null) return;
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
if (data == null || !data.hasExtra(EXTRA_ID)) return;
|
||||
final long accountId = data.getLongExtra(EXTRA_ID, -1);
|
||||
openStatus(getActivity(), accountId, status.id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(final LayoutInflater inflater, @Nullable final ViewGroup container,
|
||||
@Nullable final Bundle savedInstanceState) {
|
||||
|
@ -174,8 +204,7 @@ public class StatusFragment extends BaseSupportFragment
|
|||
if (view == null) throw new AssertionError();
|
||||
final Context context = view.getContext();
|
||||
final boolean compact = Utils.isCompactCards(context);
|
||||
mLayoutManager = new MyLinearLayoutManager(context, mRecyclerView);
|
||||
mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
|
||||
mLayoutManager = new StatusListLinearLayoutManager(context, mRecyclerView);
|
||||
if (compact) {
|
||||
mRecyclerView.addItemDecoration(new DividerItemDecoration(context, mLayoutManager.getOrientation()));
|
||||
}
|
||||
|
@ -189,24 +218,31 @@ public class StatusFragment extends BaseSupportFragment
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(final Loader<SingleResponse<ParcelableStatus>> loader,
|
||||
final SingleResponse<ParcelableStatus> data) {
|
||||
if (data.hasData()) {
|
||||
final ParcelableStatus status = data.getData();
|
||||
mStatusAdapter.setConversation(null);
|
||||
mStatusAdapter.setReplies(null);
|
||||
mStatusAdapter.setStatus(status);
|
||||
mLayoutManager.scrollToPositionWithOffset(1, 0);
|
||||
loadReplies(status);
|
||||
loadConversation(status);
|
||||
} else {
|
||||
//TODO show errors
|
||||
}
|
||||
public void onMediaClick(View view, ParcelableMedia media) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaClick(View view, ParcelableMedia media) {
|
||||
|
||||
public void onLoadFinished(final Loader<SingleResponse<ParcelableStatus>> loader,
|
||||
final SingleResponse<ParcelableStatus> data) {
|
||||
if (data.hasData()) {
|
||||
final long itemId = mStatusAdapter.getItemId(mLayoutManager.findFirstVisibleItemPosition());
|
||||
final View firstChild = mLayoutManager.getChildAt(0);
|
||||
final int top = firstChild != null ? firstChild.getTop() : 0;
|
||||
final ParcelableStatus status = data.getData();
|
||||
if (mStatusAdapter.setStatus(status)) {
|
||||
mLayoutManager.scrollToPositionWithOffset(1, 0);
|
||||
mStatusAdapter.setConversation(null);
|
||||
mStatusAdapter.setReplies(null);
|
||||
loadReplies(status);
|
||||
loadConversation(status);
|
||||
} else {
|
||||
final int position = mStatusAdapter.findPositionById(itemId);
|
||||
mLayoutManager.scrollToPositionWithOffset(position, top);
|
||||
}
|
||||
} else {
|
||||
//TODO show errors
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -222,11 +258,6 @@ public class StatusFragment extends BaseSupportFragment
|
|||
getView().setPadding(insets.left, insets.top, insets.right, insets.bottom);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(final Loader<SingleResponse<ParcelableStatus>> loader) {
|
||||
|
||||
}
|
||||
|
||||
private void loadConversation(ParcelableStatus status) {
|
||||
if (mLoadConversationTask != null && mLoadConversationTask.getStatus() == Status.RUNNING) {
|
||||
mLoadConversationTask.cancel(true);
|
||||
|
@ -249,6 +280,11 @@ public class StatusFragment extends BaseSupportFragment
|
|||
mRepliesLoaderInitialized = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(final Loader<SingleResponse<ParcelableStatus>> loader) {
|
||||
|
||||
}
|
||||
|
||||
private void setConversation(List<ParcelableStatus> data) {
|
||||
if (mLayoutManager.getChildCount() != 0) {
|
||||
final long itemId = mStatusAdapter.getItemId(mLayoutManager.findFirstVisibleItemPosition());
|
||||
|
@ -356,7 +392,7 @@ public class StatusFragment extends BaseSupportFragment
|
|||
|
||||
@Override
|
||||
public void onStatusClick(StatusViewHolder holder, int position) {
|
||||
|
||||
openStatus(mFragment.getActivity(), getStatus(position), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -369,6 +405,17 @@ public class StatusFragment extends BaseSupportFragment
|
|||
|
||||
}
|
||||
|
||||
public ParcelableStatus getStatus() {
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
public boolean setStatus(ParcelableStatus status) {
|
||||
final ParcelableStatus old = mStatus;
|
||||
mStatus = status;
|
||||
notifyDataSetChanged();
|
||||
return !CompareUtils.objectEquals(old, status);
|
||||
}
|
||||
|
||||
public boolean isDetailMediaExpanded() {
|
||||
return mDetailMediaExpanded;
|
||||
}
|
||||
|
@ -491,11 +538,6 @@ public class StatusFragment extends BaseSupportFragment
|
|||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void setStatus(ParcelableStatus status) {
|
||||
mStatus = status;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private int getConversationCount() {
|
||||
return mConversation != null ? mConversation.size() : 1;
|
||||
}
|
||||
|
@ -505,6 +547,7 @@ public class StatusFragment extends BaseSupportFragment
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static class LoadConversationTask extends TwidereAsyncTask<ParcelableStatus, ParcelableStatus,
|
||||
ListResponse<ParcelableStatus>> {
|
||||
|
||||
|
@ -666,13 +709,13 @@ public class StatusFragment extends BaseSupportFragment
|
|||
case MENU_QUOTE: {
|
||||
final Intent intent = new Intent(INTENT_ACTION_QUOTE);
|
||||
intent.putExtra(EXTRA_STATUS, status);
|
||||
activity.startActivity(intent);
|
||||
fragment.startActivity(intent);
|
||||
break;
|
||||
}
|
||||
case MENU_REPLY: {
|
||||
final Intent intent = new Intent(INTENT_ACTION_REPLY);
|
||||
intent.putExtra(EXTRA_STATUS, status);
|
||||
activity.startActivity(intent);
|
||||
fragment.startActivity(intent);
|
||||
break;
|
||||
}
|
||||
case MENU_FAVORITE: {
|
||||
|
@ -726,13 +769,13 @@ public class StatusFragment extends BaseSupportFragment
|
|||
final Intent intent = new Intent(INTENT_ACTION_SELECT_ACCOUNT);
|
||||
intent.setClass(activity, AccountSelectorActivity.class);
|
||||
intent.putExtra(EXTRA_SINGLE_SELECTION, true);
|
||||
activity.startActivityForResult(intent, REQUEST_SELECT_ACCOUNT);
|
||||
fragment.startActivityForResult(intent, REQUEST_SELECT_ACCOUNT);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
if (item.getIntent() != null) {
|
||||
try {
|
||||
activity.startActivity(item.getIntent());
|
||||
fragment.startActivity(item.getIntent());
|
||||
} catch (final ActivityNotFoundException e) {
|
||||
Log.w(LOGTAG, e);
|
||||
return false;
|
||||
|
@ -744,11 +787,6 @@ public class StatusFragment extends BaseSupportFragment
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaClick(View view, ParcelableMedia media) {
|
||||
adapter.mFragment.onMediaClick(view, media);
|
||||
}
|
||||
|
||||
public void showStatus(ParcelableStatus status) {
|
||||
if (status == null) return;
|
||||
progressContainer.setVisibility(View.GONE);
|
||||
|
@ -830,28 +868,39 @@ public class StatusFragment extends BaseSupportFragment
|
|||
menuBar.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaClick(View view, ParcelableMedia media) {
|
||||
adapter.mFragment.onMediaClick(view, media);
|
||||
}
|
||||
|
||||
private void initViews() {
|
||||
menuBar.setOnMenuItemClickListener(this);
|
||||
menuBar.inflate(R.menu.menu_status);
|
||||
mediaPreviewLoad.setOnClickListener(this);
|
||||
profileContainer.setOnClickListener(this);
|
||||
|
||||
ViewCompat.setTransitionName(profileImageView, TRANSITION_NAME_PROFILE_IMAGE);
|
||||
ViewCompat.setTransitionName(profileTypeView, TRANSITION_NAME_PROFILE_TYPE);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private static class MyLinearLayoutManager extends LinearLayoutManager {
|
||||
private static class StatusListLinearLayoutManager extends LinearLayoutManager {
|
||||
|
||||
private final RecyclerView recyclerView;
|
||||
|
||||
public MyLinearLayoutManager(Context context, RecyclerView recyclerView) {
|
||||
public StatusListLinearLayoutManager(Context context, RecyclerView recyclerView) {
|
||||
super(context);
|
||||
setOrientation(LinearLayoutManager.VERTICAL);
|
||||
this.recyclerView = recyclerView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOrientation(int orientation) {
|
||||
if (orientation != VERTICAL)
|
||||
throw new IllegalArgumentException("Only VERTICAL orientation supported");
|
||||
super.setOrientation(orientation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDecoratedMeasuredHeight(View child) {
|
||||
final int height = super.getDecoratedMeasuredHeight(child);
|
||||
|
|
|
@ -78,6 +78,7 @@ import com.squareup.otto.Subscribe;
|
|||
import org.mariotaku.menucomponent.internal.menu.MenuUtils;
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.activity.iface.IThemedActivity;
|
||||
import org.mariotaku.twidere.activity.support.AccountSelectorActivity;
|
||||
import org.mariotaku.twidere.activity.support.ColorPickerDialogActivity;
|
||||
import org.mariotaku.twidere.activity.support.LinkHandlerActivity;
|
||||
|
@ -87,6 +88,7 @@ import org.mariotaku.twidere.adapter.support.SupportTabsAdapter;
|
|||
import org.mariotaku.twidere.app.TwidereApplication;
|
||||
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback;
|
||||
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback;
|
||||
import org.mariotaku.twidere.graphic.ActionBarColorDrawable;
|
||||
import org.mariotaku.twidere.loader.support.ParcelableUserLoader;
|
||||
import org.mariotaku.twidere.model.ParcelableUser;
|
||||
import org.mariotaku.twidere.model.ParcelableUserList;
|
||||
|
@ -204,9 +206,8 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
|||
|
||||
@Subscribe
|
||||
public void notifyFriendshipUpdated(FriendshipUpdatedEvent event) {
|
||||
if (event.user != null && event.user.equals(mUser)) {
|
||||
getFriendship();
|
||||
}
|
||||
if (!event.user.equals(mUser)) return;
|
||||
getFriendship();
|
||||
}
|
||||
|
||||
private void updateRefreshState() {
|
||||
|
@ -344,7 +345,6 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
|||
};
|
||||
|
||||
public void displayUser(final ParcelableUser user) {
|
||||
mRelationship = null;
|
||||
mUser = null;
|
||||
if (user == null || user.id <= 0 || getActivity() == null) return;
|
||||
final Resources res = getResources();
|
||||
|
@ -853,7 +853,15 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
|||
protected void fitSystemWindows(Rect insets) {
|
||||
super.fitSystemWindows(insets);
|
||||
mHeaderDrawerLayout.setPadding(insets.left, insets.top, insets.right, insets.bottom);
|
||||
mHeaderDrawerLayout.setClipToPadding(ThemeUtils.isTransparentBackground(getActivity()));
|
||||
final FragmentActivity activity = getActivity();
|
||||
final boolean isTransparentBackground;
|
||||
if (activity instanceof IThemedActivity) {
|
||||
final int themeRes = ((IThemedActivity) activity).getCurrentThemeResourceId();
|
||||
isTransparentBackground = ThemeUtils.isTransparentBackground(themeRes);
|
||||
} else {
|
||||
isTransparentBackground = ThemeUtils.isTransparentBackground(getActivity());
|
||||
}
|
||||
mHeaderDrawerLayout.setClipToPadding(isTransparentBackground);
|
||||
}
|
||||
|
||||
public void setListShown(boolean shown) {
|
||||
|
@ -867,6 +875,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
|||
}
|
||||
|
||||
private void getFriendship() {
|
||||
mRelationship = null;
|
||||
final ParcelableUser user = mUser;
|
||||
final LoaderManager lm = getLoaderManager();
|
||||
lm.destroyLoader(LOADER_ID_FRIENDSHIP);
|
||||
|
@ -1225,7 +1234,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
|||
public ActionBarDrawable(Resources resources, Drawable shadow, Drawable background,
|
||||
boolean colorLineOnly) {
|
||||
super(new Drawable[]{shadow, background, new LineBackgroundDrawable(resources, 2.0f),
|
||||
new ColorDrawable()});
|
||||
new ActionBarColorDrawable()});
|
||||
mShadowDrawable = shadow;
|
||||
mBackgroundDrawable = getDrawable(1);
|
||||
mLineDrawable = (LineBackgroundDrawable) getDrawable(2);
|
||||
|
@ -1243,11 +1252,11 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
|||
} else {
|
||||
mBackgroundDrawable.getOutline(outline);
|
||||
}
|
||||
outline.setAlpha(mFactor * 0.99f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
super.setAlpha(alpha);
|
||||
mAlpha = alpha;
|
||||
setFactor(mFactor);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* 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.graphic;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.graphics.Outline;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Build;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/12/8.
|
||||
*/
|
||||
public class ActionBarColorDrawable extends ColorDrawable {
|
||||
|
||||
public ActionBarColorDrawable() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ActionBarColorDrawable(int color) {
|
||||
super(color);
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
@Override
|
||||
public void getOutline(Outline outline) {
|
||||
final Rect bounds = getBounds();
|
||||
// Very very dirty hack to make outline shadow in action bar not visible beneath status bar
|
||||
outline.setRect(bounds.left - bounds.width() / 2, -bounds.height(),
|
||||
bounds.right + bounds.width() / 2, bounds.bottom);
|
||||
outline.setAlpha(getAlpha() / 255f);
|
||||
}
|
||||
}
|
|
@ -19,247 +19,257 @@
|
|||
|
||||
package org.mariotaku.twidere.util;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public final class ArrayUtils {
|
||||
|
||||
private ArrayUtils() {
|
||||
throw new AssertionError("You are trying to create an instance for this utility class!");
|
||||
}
|
||||
private ArrayUtils() {
|
||||
throw new AssertionError("You are trying to create an instance for this utility class!");
|
||||
}
|
||||
|
||||
public static boolean contains(final int[] array, final int value) {
|
||||
if (array == null) return false;
|
||||
for (final int item : array) {
|
||||
if (item == value) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static boolean contains(final int[] array, final int value) {
|
||||
if (array == null) return false;
|
||||
for (final int item : array) {
|
||||
if (item == value) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean contains(final long[] array, final long value) {
|
||||
if (array == null) return false;
|
||||
for (final long item : array) {
|
||||
if (item == value) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static boolean contains(final long[] array, final long value) {
|
||||
if (array == null) return false;
|
||||
for (final long item : array) {
|
||||
if (item == value) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean contains(final Object[] array, final Object value) {
|
||||
if (array == null || value == null) return false;
|
||||
return contains(array, new Object[] { value });
|
||||
}
|
||||
public static boolean contains(final Object[] array, final Object value) {
|
||||
if (array == null || value == null) return false;
|
||||
return contains(array, new Object[]{value});
|
||||
}
|
||||
|
||||
public static boolean contains(final Object[] array, final Object[] values) {
|
||||
if (array == null || values == null) return false;
|
||||
for (final Object item : array) {
|
||||
for (final Object value : values) {
|
||||
if (item == null || value == null) {
|
||||
if (item == value) return true;
|
||||
continue;
|
||||
}
|
||||
if (item.equals(value)) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static boolean contains(final Object[] array, final Object[] values) {
|
||||
if (array == null || values == null) return false;
|
||||
for (final Object item : array) {
|
||||
for (final Object value : values) {
|
||||
if (item == null || value == null) {
|
||||
if (item == value) return true;
|
||||
continue;
|
||||
}
|
||||
if (item.equals(value)) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean contentMatch(final Object[] array1, final Object[] array2) {
|
||||
if (array1 == null || array2 == null) return array1 == array2;
|
||||
if (array1.length != array2.length) return false;
|
||||
final int length = array1.length;
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (!contains(array2, array1[i])) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public static boolean contentMatch(final Object[] array1, final Object[] array2) {
|
||||
if (array1 == null || array2 == null) return array1 == array2;
|
||||
if (array1.length != array2.length) return false;
|
||||
final int length = array1.length;
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (!contains(array2, array1[i])) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static long[] fromList(final List<Long> list) {
|
||||
if (list == null) return null;
|
||||
final int count = list.size();
|
||||
final long[] array = new long[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
array[i] = list.get(i);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
public static long[] fromList(final List<Long> list) {
|
||||
if (list == null) return null;
|
||||
final int count = list.size();
|
||||
final long[] array = new long[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
array[i] = list.get(i);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public static int indexOf(final int[] array, final int value) {
|
||||
final int length = array.length;
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (array[i] == value) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
public static int indexOf(final int[] array, final int value) {
|
||||
final int length = array.length;
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (array[i] == value) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static int indexOf(final long[] array, final long value) {
|
||||
final int length = array.length;
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (array[i] == value) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
public static int indexOf(final long[] array, final long value) {
|
||||
final int length = array.length;
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (array[i] == value) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static int indexOf(final Object[] array, final Object value) {
|
||||
final int length = array.length;
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (array[i].equals(value)) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
public static int indexOf(final Object[] array, final Object value) {
|
||||
final int length = array.length;
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (array[i].equals(value)) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static long[] intersection(final long[] array1, final long[] array2) {
|
||||
if (array1 == null || array2 == null) return new long[0];
|
||||
final List<Long> list1 = new ArrayList<Long>();
|
||||
for (final long item : array1) {
|
||||
list1.add(item);
|
||||
}
|
||||
final List<Long> list2 = new ArrayList<Long>();
|
||||
for (final long item : array2) {
|
||||
list2.add(item);
|
||||
}
|
||||
list1.retainAll(list2);
|
||||
return fromList(list1);
|
||||
}
|
||||
public static long[] intersection(final long[] array1, final long[] array2) {
|
||||
if (array1 == null || array2 == null) return new long[0];
|
||||
final List<Long> list1 = new ArrayList<Long>();
|
||||
for (final long item : array1) {
|
||||
list1.add(item);
|
||||
}
|
||||
final List<Long> list2 = new ArrayList<Long>();
|
||||
for (final long item : array2) {
|
||||
list2.add(item);
|
||||
}
|
||||
list1.retainAll(list2);
|
||||
return fromList(list1);
|
||||
}
|
||||
|
||||
public static void mergeArray(final Object[] dest, final Object[]... arrays) {
|
||||
if (arrays == null || arrays.length == 0) return;
|
||||
if (arrays.length == 1) {
|
||||
final Object[] array = arrays[0];
|
||||
System.arraycopy(array, 0, dest, 0, array.length);
|
||||
return;
|
||||
}
|
||||
for (int i = 0, j = arrays.length - 1; i < j; i++) {
|
||||
final Object[] array1 = arrays[i], array2 = arrays[i + 1];
|
||||
System.arraycopy(array1, 0, dest, 0, array1.length);
|
||||
System.arraycopy(array2, 0, dest, array1.length, array2.length);
|
||||
}
|
||||
}
|
||||
public static void mergeArray(final Object[] dest, final Object[]... arrays) {
|
||||
if (arrays == null || arrays.length == 0) return;
|
||||
if (arrays.length == 1) {
|
||||
final Object[] array = arrays[0];
|
||||
System.arraycopy(array, 0, dest, 0, array.length);
|
||||
return;
|
||||
}
|
||||
for (int i = 0, j = arrays.length - 1; i < j; i++) {
|
||||
final Object[] array1 = arrays[i], array2 = arrays[i + 1];
|
||||
System.arraycopy(array1, 0, dest, 0, array1.length);
|
||||
System.arraycopy(array2, 0, dest, array1.length, array2.length);
|
||||
}
|
||||
}
|
||||
|
||||
public static String mergeArrayToString(final String[] array) {
|
||||
if (array == null) return null;
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
for (final String c : array) {
|
||||
builder.append(c);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
public static String mergeArrayToString(final String[] array) {
|
||||
if (array == null) return null;
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
for (final String c : array) {
|
||||
builder.append(c);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static long min(final long[] array) {
|
||||
if (array == null || array.length == 0) throw new IllegalArgumentException();
|
||||
long min = array[0];
|
||||
for (int i = 1, j = array.length; i < j; i++) {
|
||||
if (min > array[i]) {
|
||||
min = array[i];
|
||||
}
|
||||
}
|
||||
return min;
|
||||
}
|
||||
public static long min(final long[] array) {
|
||||
if (array == null || array.length == 0) throw new IllegalArgumentException();
|
||||
long min = array[0];
|
||||
for (int i = 1, j = array.length; i < j; i++) {
|
||||
if (min > array[i]) {
|
||||
min = array[i];
|
||||
}
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
public static long[] parseLongArray(final String string, final char token) {
|
||||
if (string == null) return new long[0];
|
||||
final String[] items_string_array = string.split(String.valueOf(token));
|
||||
final ArrayList<Long> items_list = new ArrayList<Long>();
|
||||
for (final String id_string : items_string_array) {
|
||||
try {
|
||||
items_list.add(Long.parseLong(id_string));
|
||||
} catch (final NumberFormatException e) {
|
||||
// Ignore.
|
||||
}
|
||||
}
|
||||
final int list_size = items_list.size();
|
||||
final long[] array = new long[list_size];
|
||||
for (int i = 0; i < list_size; i++) {
|
||||
array[i] = items_list.get(i);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
public static long[] parseLongArray(final String string, final char token) {
|
||||
if (string == null) return new long[0];
|
||||
final String[] items_string_array = string.split(String.valueOf(token));
|
||||
final ArrayList<Long> items_list = new ArrayList<Long>();
|
||||
for (final String id_string : items_string_array) {
|
||||
try {
|
||||
items_list.add(Long.parseLong(id_string));
|
||||
} catch (final NumberFormatException e) {
|
||||
// Ignore.
|
||||
}
|
||||
}
|
||||
final int list_size = items_list.size();
|
||||
final long[] array = new long[list_size];
|
||||
for (int i = 0; i < list_size; i++) {
|
||||
array[i] = items_list.get(i);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public static int[] subArray(final int[] array, final int start, final int end) {
|
||||
final int length = end - start;
|
||||
if (length < 0) throw new IllegalArgumentException();
|
||||
final int[] result = new int[length];
|
||||
System.arraycopy(array, start, result, 0, length);
|
||||
return result;
|
||||
}
|
||||
public static void reverse(@NonNull Object[] array) {
|
||||
for (int i = 0; i < array.length / 2; i++) {
|
||||
Object temp = array[i];
|
||||
array[i] = array[array.length - i - 1];
|
||||
array[array.length - i - 1] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
public static long[] subArray(final long[] array, final int start, final int end) {
|
||||
final int length = end - start;
|
||||
if (length < 0) throw new IllegalArgumentException();
|
||||
final long[] result = new long[length];
|
||||
System.arraycopy(array, start, result, 0, length);
|
||||
return result;
|
||||
}
|
||||
public static int[] subArray(final int[] array, final int start, final int end) {
|
||||
final int length = end - start;
|
||||
if (length < 0) throw new IllegalArgumentException();
|
||||
final int[] result = new int[length];
|
||||
System.arraycopy(array, start, result, 0, length);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Object[] subArray(final Object[] array, final int start, final int end) {
|
||||
final int length = end - start;
|
||||
if (length < 0) throw new IllegalArgumentException();
|
||||
final Object[] result = new Object[length];
|
||||
System.arraycopy(array, start, result, 0, length);
|
||||
return result;
|
||||
}
|
||||
public static long[] subArray(final long[] array, final int start, final int end) {
|
||||
final int length = end - start;
|
||||
if (length < 0) throw new IllegalArgumentException();
|
||||
final long[] result = new long[length];
|
||||
System.arraycopy(array, start, result, 0, length);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String[] subArray(final String[] array, final int start, final int end) {
|
||||
final int length = end - start;
|
||||
if (length < 0) throw new IllegalArgumentException();
|
||||
final String[] result = new String[length];
|
||||
System.arraycopy(array, start, result, 0, length);
|
||||
return result;
|
||||
}
|
||||
public static Object[] subArray(final Object[] array, final int start, final int end) {
|
||||
final int length = end - start;
|
||||
if (length < 0) throw new IllegalArgumentException();
|
||||
final Object[] result = new Object[length];
|
||||
System.arraycopy(array, start, result, 0, length);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String toString(final long[] array, final char token, final boolean include_space) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
final int length = array.length;
|
||||
for (int i = 0; i < length; i++) {
|
||||
final String id_string = String.valueOf(array[i]);
|
||||
if (id_string != null) {
|
||||
if (i > 0) {
|
||||
builder.append(include_space ? token + " " : token);
|
||||
}
|
||||
builder.append(id_string);
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
public static String[] subArray(final String[] array, final int start, final int end) {
|
||||
final int length = end - start;
|
||||
if (length < 0) throw new IllegalArgumentException();
|
||||
final String[] result = new String[length];
|
||||
System.arraycopy(array, start, result, 0, length);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String toString(final Object[] array, final char token, final boolean include_space) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
final int length = array.length;
|
||||
for (int i = 0; i < length; i++) {
|
||||
final String id_string = String.valueOf(array[i]);
|
||||
if (id_string != null) {
|
||||
if (i > 0) {
|
||||
builder.append(include_space ? token + " " : token);
|
||||
}
|
||||
builder.append(id_string);
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
public static String toString(final long[] array, final char token, final boolean include_space) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
final int length = array.length;
|
||||
for (int i = 0; i < length; i++) {
|
||||
final String id_string = String.valueOf(array[i]);
|
||||
if (id_string != null) {
|
||||
if (i > 0) {
|
||||
builder.append(include_space ? token + " " : token);
|
||||
}
|
||||
builder.append(id_string);
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static String[] toStringArray(final Object[] array) {
|
||||
if (array == null) return null;
|
||||
final int length = array.length;
|
||||
final String[] string_array = new String[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
string_array[i] = ParseUtils.parseString(array[i]);
|
||||
}
|
||||
return string_array;
|
||||
}
|
||||
public static String toString(final Object[] array, final char token, final boolean include_space) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
final int length = array.length;
|
||||
for (int i = 0; i < length; i++) {
|
||||
final String id_string = String.valueOf(array[i]);
|
||||
if (id_string != null) {
|
||||
if (i > 0) {
|
||||
builder.append(include_space ? token + " " : token);
|
||||
}
|
||||
builder.append(id_string);
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static String[] toStringArray(final String s) {
|
||||
if (s == null) return null;
|
||||
return s.split("(?!^)");
|
||||
}
|
||||
public static String[] toStringArray(final Object[] array) {
|
||||
if (array == null) return null;
|
||||
final int length = array.length;
|
||||
final String[] string_array = new String[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
string_array[i] = ParseUtils.parseString(array[i]);
|
||||
}
|
||||
return string_array;
|
||||
}
|
||||
|
||||
public static String toStringForSQL(final String[] array) {
|
||||
final int size = array != null ? array.length : 0;
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (i > 0) {
|
||||
builder.append(',');
|
||||
}
|
||||
builder.append('?');
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
public static String[] toStringArray(final String s) {
|
||||
if (s == null) return null;
|
||||
return s.split("(?!^)");
|
||||
}
|
||||
|
||||
public static String toStringForSQL(final String[] array) {
|
||||
final int size = array != null ? array.length : 0;
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (i > 0) {
|
||||
builder.append(',');
|
||||
}
|
||||
builder.append('?');
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,43 +26,42 @@ import java.lang.reflect.Method;
|
|||
|
||||
public final class FlymeUtils {
|
||||
|
||||
private static String[] SMARTBAR_SUPPORTED_DEVICES = { "mx2", "mx3" };
|
||||
private static String[] SMARTBAR_SUPPORTED_DEVICES = {"mx2", "mx3"};
|
||||
|
||||
public static boolean hasSmartBar() {
|
||||
try {
|
||||
// Invoke Build.hasSmartBar()
|
||||
final Method method = Build.class.getMethod("hasSmartBar");
|
||||
return ((Boolean) method.invoke(null)).booleanValue();
|
||||
} catch (final Exception e) {
|
||||
}
|
||||
// Detect by Build.DEVICE
|
||||
if (isDeviceWithSmartBar(Build.DEVICE)) return true;
|
||||
return false;
|
||||
}
|
||||
public static boolean hasSmartBar() {
|
||||
try {
|
||||
// Invoke Build.hasSmartBar()
|
||||
final Method method = Build.class.getMethod("hasSmartBar");
|
||||
return (Boolean) method.invoke(null);
|
||||
} catch (final Exception ignored) {
|
||||
}
|
||||
// Detect by Build.DEVICE
|
||||
return isDeviceWithSmartBar(Build.DEVICE);
|
||||
}
|
||||
|
||||
public static boolean isDeviceWithSmartBar(final String buildDevice) {
|
||||
for (final String dev : SMARTBAR_SUPPORTED_DEVICES) {
|
||||
if (dev.equals(buildDevice)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static boolean isDeviceWithSmartBar(final String buildDevice) {
|
||||
for (final String dev : SMARTBAR_SUPPORTED_DEVICES) {
|
||||
if (dev.equals(buildDevice)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isFlyme() {
|
||||
try {
|
||||
// Invoke Build.hasSmartBar()
|
||||
final Method method = Build.class.getMethod("hasSmartBar");
|
||||
return method != null;
|
||||
} catch (final Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public static boolean isFlyme() {
|
||||
try {
|
||||
// Invoke Build.hasSmartBar()
|
||||
final Method method = Build.class.getMethod("hasSmartBar");
|
||||
return method != null;
|
||||
} catch (final Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void setActionModeHeaderHidden(final ActionBar actionbar, final boolean hidden) {
|
||||
try {
|
||||
final Method method = ActionBar.class.getMethod("setActionModeHeaderHidden", new Class[] { boolean.class });
|
||||
method.invoke(actionbar, hidden);
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
public static void setActionModeHeaderHidden(final ActionBar actionbar, final boolean hidden) {
|
||||
try {
|
||||
final Method method = ActionBar.class.getMethod("setActionModeHeaderHidden", new Class[]{boolean.class});
|
||||
method.invoke(actionbar, hidden);
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ import org.mariotaku.refreshnow.widget.RefreshNowProgressIndicator.IndicatorConf
|
|||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.activity.iface.IThemedActivity;
|
||||
import org.mariotaku.twidere.graphic.ActionBarColorDrawable;
|
||||
import org.mariotaku.twidere.text.ParagraphSpacingSpan;
|
||||
import org.mariotaku.twidere.util.menu.TwidereMenuInfo;
|
||||
|
||||
|
@ -240,7 +241,7 @@ public class ThemeUtils implements Constants {
|
|||
public static Drawable getActionBarBackground(final Context context, final int themeRes,
|
||||
final int accentColor) {
|
||||
if (!isDarkTheme(themeRes)) {
|
||||
final ColorDrawable d = new ColorDrawable(accentColor);
|
||||
final ColorDrawable d = new ActionBarColorDrawable(accentColor);
|
||||
return applyActionBarDrawable(context, d, isTransparentBackground(themeRes));
|
||||
}
|
||||
final TypedArray a = context.obtainStyledAttributes(null, new int[]{android.R.attr.background},
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,363 +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.util.layout;
|
||||
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
/**
|
||||
* Helper class for LayoutManagers to abstract measurements depending on the View's orientation.
|
||||
* <p/>
|
||||
* It is developed to easily support vertical and horizontal orientations in a LayoutManager but
|
||||
* can also be used to abstract calls around view bounds and child measurements with margins and
|
||||
* decorations.
|
||||
*
|
||||
* @see #createHorizontalHelper(RecyclerView.LayoutManager)
|
||||
* @see #createVerticalHelper(RecyclerView.LayoutManager)
|
||||
*/
|
||||
public abstract class OrientationHelper {
|
||||
|
||||
private static final int INVALID_SIZE = Integer.MIN_VALUE;
|
||||
|
||||
protected final RecyclerView.LayoutManager mLayoutManager;
|
||||
|
||||
public static final int HORIZONTAL = LinearLayout.HORIZONTAL;
|
||||
|
||||
public static final int VERTICAL = LinearLayout.VERTICAL;
|
||||
|
||||
private int mLastTotalSpace = INVALID_SIZE;
|
||||
|
||||
private OrientationHelper(RecyclerView.LayoutManager layoutManager) {
|
||||
mLayoutManager = layoutManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this method after onLayout method is complete if state is NOT pre-layout.
|
||||
* This method records information like layout bounds that might be useful in the next layout
|
||||
* calculations.
|
||||
*/
|
||||
public void onLayoutComplete() {
|
||||
mLastTotalSpace = getTotalSpace();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the layout space change between the previous layout pass and current layout pass.
|
||||
* <p/>
|
||||
* Make sure you call {@link #onLayoutComplete()} at the end of your LayoutManager's
|
||||
* {@link RecyclerView.LayoutManager#onLayoutChildren(RecyclerView.Recycler,
|
||||
* RecyclerView.State)} method.
|
||||
*
|
||||
* @return The difference between the current total space and previous layout's total space.
|
||||
* @see #onLayoutComplete()
|
||||
*/
|
||||
public int getTotalSpaceChange() {
|
||||
return INVALID_SIZE == mLastTotalSpace ? 0 : getTotalSpace() - mLastTotalSpace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the start of the view including its decoration and margin.
|
||||
* <p/>
|
||||
* For example, for the horizontal helper, if a View's left is at pixel 20, has 2px left
|
||||
* decoration and 3px left margin, returned value will be 15px.
|
||||
*
|
||||
* @param view The view element to check
|
||||
* @return The first pixel of the element
|
||||
* @see #getDecoratedEnd(android.view.View)
|
||||
*/
|
||||
public abstract int getDecoratedStart(View view);
|
||||
|
||||
/**
|
||||
* Returns the end of the view including its decoration and margin.
|
||||
* <p/>
|
||||
* For example, for the horizontal helper, if a View's right is at pixel 200, has 2px right
|
||||
* decoration and 3px right margin, returned value will be 205.
|
||||
*
|
||||
* @param view The view element to check
|
||||
* @return The last pixel of the element
|
||||
* @see #getDecoratedStart(android.view.View)
|
||||
*/
|
||||
public abstract int getDecoratedEnd(View view);
|
||||
|
||||
/**
|
||||
* Returns the space occupied by this View in the current orientation including decorations and
|
||||
* margins.
|
||||
*
|
||||
* @param view The view element to check
|
||||
* @return Total space occupied by this view
|
||||
* @see #getDecoratedMeasurementInOther(View)
|
||||
*/
|
||||
public abstract int getDecoratedMeasurement(View view);
|
||||
|
||||
/**
|
||||
* Returns the space occupied by this View in the perpendicular orientation including
|
||||
* decorations and margins.
|
||||
*
|
||||
* @param view The view element to check
|
||||
* @return Total space occupied by this view in the perpendicular orientation to current one
|
||||
* @see #getDecoratedMeasurement(View)
|
||||
*/
|
||||
public abstract int getDecoratedMeasurementInOther(View view);
|
||||
|
||||
/**
|
||||
* Returns the start position of the layout after the start padding is added.
|
||||
*
|
||||
* @return The very first pixel we can draw.
|
||||
*/
|
||||
public abstract int getStartAfterPadding();
|
||||
|
||||
/**
|
||||
* Returns the end position of the layout after the end padding is removed.
|
||||
*
|
||||
* @return The end boundary for this layout.
|
||||
*/
|
||||
public abstract int getEndAfterPadding();
|
||||
|
||||
/**
|
||||
* Returns the end position of the layout without taking padding into account.
|
||||
*
|
||||
* @return The end boundary for this layout without considering padding.
|
||||
*/
|
||||
public abstract int getEnd();
|
||||
|
||||
/**
|
||||
* Offsets all children's positions by the given amount.
|
||||
*
|
||||
* @param amount Value to add to each child's layout parameters
|
||||
*/
|
||||
public abstract void offsetChildren(int amount);
|
||||
|
||||
/**
|
||||
* Returns the total space to layout. This number is the difference between
|
||||
* {@link #getEndAfterPadding()} and {@link #getStartAfterPadding()}.
|
||||
*
|
||||
* @return Total space to layout children
|
||||
*/
|
||||
public abstract int getTotalSpace();
|
||||
|
||||
/**
|
||||
* Offsets the child in this orientation.
|
||||
*
|
||||
* @param view View to offset
|
||||
* @param offset offset amount
|
||||
*/
|
||||
public abstract void offsetChild(View view, int offset);
|
||||
|
||||
/**
|
||||
* Returns the padding at the end of the layout. For horizontal helper, this is the right
|
||||
* padding and for vertical helper, this is the bottom padding. This method does not check
|
||||
* whether the layout is RTL or not.
|
||||
*
|
||||
* @return The padding at the end of the layout.
|
||||
*/
|
||||
public abstract int getEndPadding();
|
||||
|
||||
/**
|
||||
* Creates an OrientationHelper for the given LayoutManager and orientation.
|
||||
*
|
||||
* @param layoutManager LayoutManager to attach to
|
||||
* @param orientation Desired orientation. Should be {@link #HORIZONTAL} or {@link #VERTICAL}
|
||||
* @return A new OrientationHelper
|
||||
*/
|
||||
public static OrientationHelper createOrientationHelper(
|
||||
RecyclerView.LayoutManager layoutManager, int orientation) {
|
||||
switch (orientation) {
|
||||
case HORIZONTAL:
|
||||
return createHorizontalHelper(layoutManager);
|
||||
case VERTICAL:
|
||||
return createVerticalHelper(layoutManager);
|
||||
}
|
||||
throw new IllegalArgumentException("invalid orientation");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a horizontal OrientationHelper for the given LayoutManager.
|
||||
*
|
||||
* @param layoutManager The LayoutManager to attach to.
|
||||
* @return A new OrientationHelper
|
||||
*/
|
||||
public static OrientationHelper createHorizontalHelper(
|
||||
RecyclerView.LayoutManager layoutManager) {
|
||||
return new OrientationHelper(layoutManager) {
|
||||
@Override
|
||||
public int getEndAfterPadding() {
|
||||
return mLayoutManager.getWidth() - mLayoutManager.getPaddingRight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEnd() {
|
||||
return mLayoutManager.getWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void offsetChildren(int amount) {
|
||||
mLayoutManager.offsetChildrenHorizontal(amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStartAfterPadding() {
|
||||
return mLayoutManager.getPaddingLeft();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDecoratedMeasurement(View view) {
|
||||
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
|
||||
view.getLayoutParams();
|
||||
return mLayoutManager.getDecoratedMeasuredWidth(view) + params.leftMargin
|
||||
+ params.rightMargin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDecoratedMeasurementInOther(View view) {
|
||||
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
|
||||
view.getLayoutParams();
|
||||
return mLayoutManager.getDecoratedMeasuredHeight(view) + params.topMargin
|
||||
+ params.bottomMargin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDecoratedEnd(View view) {
|
||||
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
|
||||
view.getLayoutParams();
|
||||
return mLayoutManager.getDecoratedRight(view) + params.rightMargin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDecoratedStart(View view) {
|
||||
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
|
||||
view.getLayoutParams();
|
||||
return mLayoutManager.getDecoratedLeft(view) - params.leftMargin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTotalSpace() {
|
||||
return mLayoutManager.getWidth() - mLayoutManager.getPaddingLeft()
|
||||
- mLayoutManager.getPaddingRight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void offsetChild(View view, int offset) {
|
||||
view.offsetLeftAndRight(offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEndPadding() {
|
||||
return mLayoutManager.getPaddingRight();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a vertical OrientationHelper for the given LayoutManager.
|
||||
*
|
||||
* @param layoutManager The LayoutManager to attach to.
|
||||
* @return A new OrientationHelper
|
||||
*/
|
||||
public static OrientationHelper createVerticalHelper(RecyclerView.LayoutManager layoutManager) {
|
||||
return new OrientationHelper(layoutManager) {
|
||||
|
||||
int diff;
|
||||
|
||||
@Override
|
||||
public int getEndAfterPadding() {
|
||||
int heightSum = 0;
|
||||
for (int i = 0, j = mLayoutManager.getChildCount(); i < j; i++) {
|
||||
final View child = mLayoutManager.getChildAt(i);
|
||||
if (mLayoutManager.getItemViewType(child) == 0 || heightSum != 0) {
|
||||
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
|
||||
child.getLayoutParams();
|
||||
heightSum += mLayoutManager.getDecoratedMeasuredHeight(child)
|
||||
+ params.topMargin + params.bottomMargin;
|
||||
}
|
||||
}
|
||||
final int normalEnd = mLayoutManager.getHeight() - mLayoutManager.getPaddingBottom();
|
||||
if (heightSum == 0) {
|
||||
diff = 0;
|
||||
return normalEnd;
|
||||
}
|
||||
diff = (mLayoutManager.getPaddingTop() + heightSum) - normalEnd;
|
||||
// return normalEnd;
|
||||
return Math.min(mLayoutManager.getPaddingTop() + heightSum, normalEnd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEnd() {
|
||||
return mLayoutManager.getHeight() + Math.max(0, diff);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void offsetChildren(int amount) {
|
||||
mLayoutManager.offsetChildrenVertical(amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStartAfterPadding() {
|
||||
return mLayoutManager.getPaddingTop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDecoratedMeasurement(View view) {
|
||||
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
|
||||
view.getLayoutParams();
|
||||
return mLayoutManager.getDecoratedMeasuredHeight(view) + params.topMargin
|
||||
+ params.bottomMargin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDecoratedMeasurementInOther(View view) {
|
||||
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
|
||||
view.getLayoutParams();
|
||||
return mLayoutManager.getDecoratedMeasuredWidth(view) + params.leftMargin
|
||||
+ params.rightMargin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDecoratedEnd(View view) {
|
||||
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
|
||||
view.getLayoutParams();
|
||||
return mLayoutManager.getDecoratedBottom(view) + params.bottomMargin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDecoratedStart(View view) {
|
||||
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
|
||||
view.getLayoutParams();
|
||||
return mLayoutManager.getDecoratedTop(view) - params.topMargin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTotalSpace() {
|
||||
return mLayoutManager.getHeight() - mLayoutManager.getPaddingTop()
|
||||
- mLayoutManager.getPaddingBottom();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void offsetChild(View view, int offset) {
|
||||
view.offsetTopAndBottom(offset);
|
||||
mLayoutManager.requestLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEndPadding() {
|
||||
return mLayoutManager.getPaddingBottom();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,99 +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.util.layout;
|
||||
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
|
||||
/**
|
||||
* A helper class to do scroll offset calculations.
|
||||
*/
|
||||
class ScrollbarHelper {
|
||||
|
||||
/**
|
||||
* @param startChild View closest to start of the list. (top or left)
|
||||
* @param endChild View closest to end of the list (bottom or right)
|
||||
*/
|
||||
static int computeScrollOffset(RecyclerView.State state, OrientationHelper orientation,
|
||||
View startChild, View endChild, RecyclerView.LayoutManager lm,
|
||||
boolean smoothScrollbarEnabled, boolean reverseLayout) {
|
||||
if (lm.getChildCount() == 0 || state.getItemCount() == 0 || startChild == null ||
|
||||
endChild == null) {
|
||||
return 0;
|
||||
}
|
||||
final int minPosition = Math.min(lm.getPosition(startChild), lm.getPosition(endChild));
|
||||
final int maxPosition = Math.max(lm.getPosition(startChild), lm.getPosition(endChild));
|
||||
final int itemsBefore = reverseLayout
|
||||
? Math.max(0, state.getItemCount() - maxPosition - 1)
|
||||
: Math.max(0, minPosition);
|
||||
if (!smoothScrollbarEnabled) {
|
||||
return itemsBefore;
|
||||
}
|
||||
final int laidOutArea = Math.abs(orientation.getDecoratedEnd(endChild) -
|
||||
orientation.getDecoratedStart(startChild));
|
||||
final int itemRange = Math.abs(lm.getPosition(startChild) - lm.getPosition(endChild)) + 1;
|
||||
final float avgSizePerRow = (float) laidOutArea / itemRange;
|
||||
|
||||
return Math.round(itemsBefore * avgSizePerRow + (orientation.getStartAfterPadding()
|
||||
- orientation.getDecoratedStart(startChild)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param startChild View closest to start of the list. (top or left)
|
||||
* @param endChild View closest to end of the list (bottom or right)
|
||||
*/
|
||||
static int computeScrollExtent(RecyclerView.State state, OrientationHelper orientation,
|
||||
View startChild, View endChild, RecyclerView.LayoutManager lm,
|
||||
boolean smoothScrollbarEnabled) {
|
||||
if (lm.getChildCount() == 0 || state.getItemCount() == 0 || startChild == null ||
|
||||
endChild == null) {
|
||||
return 0;
|
||||
}
|
||||
if (!smoothScrollbarEnabled) {
|
||||
return Math.abs(lm.getPosition(startChild) - lm.getPosition(endChild)) + 1;
|
||||
}
|
||||
final int extend = orientation.getDecoratedEnd(endChild)
|
||||
- orientation.getDecoratedStart(startChild);
|
||||
return Math.min(orientation.getTotalSpace(), extend);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param startChild View closest to start of the list. (top or left)
|
||||
* @param endChild View closest to end of the list (bottom or right)
|
||||
*/
|
||||
static int computeScrollRange(RecyclerView.State state, OrientationHelper orientation,
|
||||
View startChild, View endChild, RecyclerView.LayoutManager lm,
|
||||
boolean smoothScrollbarEnabled) {
|
||||
if (lm.getChildCount() == 0 || state.getItemCount() == 0 || startChild == null ||
|
||||
endChild == null) {
|
||||
return 0;
|
||||
}
|
||||
if (!smoothScrollbarEnabled) {
|
||||
return state.getItemCount();
|
||||
}
|
||||
// smooth scrollbar enabled. try to estimate better.
|
||||
final int laidOutArea = orientation.getDecoratedEnd(endChild) -
|
||||
orientation.getDecoratedStart(startChild);
|
||||
final int laidOutRange = Math.abs(lm.getPosition(startChild) - lm.getPosition(endChild))
|
||||
+ 1;
|
||||
// estimate a size for full list.
|
||||
return (int) ((float) laidOutArea / laidOutRange * state.getItemCount());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,249 @@
|
|||
/*
|
||||
* 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.support.annotation.NonNull;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.RecyclerView.Adapter;
|
||||
import android.support.v7.widget.RecyclerView.Recycler;
|
||||
import android.support.v7.widget.RecyclerView.State;
|
||||
import android.support.v7.widget.RecyclerView.ViewHolder;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.app.TwidereApplication;
|
||||
import org.mariotaku.twidere.model.ParcelableAccount;
|
||||
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
||||
import org.mariotaku.twidere.view.iface.IColorLabelView.Helper;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/12/8.
|
||||
*/
|
||||
public class ComposeSelectAccountButton extends ViewGroup {
|
||||
private final AccountIconsAdapter mAccountIconsAdapter;
|
||||
private final Helper mColorLabelHelper;
|
||||
|
||||
private OnClickListener mOnClickListener;
|
||||
private OnLongClickListener mOnLongClickListener;
|
||||
|
||||
public ComposeSelectAccountButton(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public ComposeSelectAccountButton(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public ComposeSelectAccountButton(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
mColorLabelHelper = new Helper(this, context, attrs, defStyle);
|
||||
mColorLabelHelper.setIgnorePaddings(true);
|
||||
mAccountIconsAdapter = new AccountIconsAdapter(context);
|
||||
final RecyclerView recyclerView = new InternalRecyclerView(context);
|
||||
final LinearLayoutManager linearLayoutManager = new MyLinearLayoutManager(context);
|
||||
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
|
||||
// linearLayoutManager.setReverseLayout(true);
|
||||
recyclerView.setLayoutManager(linearLayoutManager);
|
||||
recyclerView.setAdapter(mAccountIconsAdapter);
|
||||
ViewCompat.setOverScrollMode(recyclerView, ViewCompat.OVER_SCROLL_NEVER);
|
||||
addView(recyclerView);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void dispatchDraw(@NonNull final Canvas canvas) {
|
||||
mColorLabelHelper.dispatchDrawBackground(canvas);
|
||||
super.dispatchDraw(canvas);
|
||||
mColorLabelHelper.dispatchDrawLabels(canvas);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
measureChildren(widthMeasureSpec, heightMeasureSpec);
|
||||
int maxWidth = 0;
|
||||
for (int i = 0, j = getChildCount(); i < j; i++) {
|
||||
final View child = getChildAt(i);
|
||||
maxWidth = Math.max(maxWidth, child.getMeasuredWidth());
|
||||
}
|
||||
if (maxWidth == 0) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
} else {
|
||||
setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec), heightMeasureSpec);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
for (int i = 0, j = getChildCount(); i < j; i++) {
|
||||
final View child = getChildAt(i);
|
||||
child.layout(getPaddingLeft(), getPaddingTop(), r - l - getPaddingRight(),
|
||||
b - t - getPaddingBottom());
|
||||
}
|
||||
}
|
||||
|
||||
static class AccountIconViewHolder extends ViewHolder {
|
||||
|
||||
private final ImageView iconView;
|
||||
|
||||
public AccountIconViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
iconView = (ImageView) itemView.findViewById(android.R.id.icon);
|
||||
}
|
||||
|
||||
public void showAccount(AccountIconsAdapter adapter, ParcelableAccount account) {
|
||||
final ImageLoaderWrapper loader = adapter.getImageLoader();
|
||||
loader.displayProfileImage(iconView, account.profile_image_url);
|
||||
}
|
||||
}
|
||||
|
||||
public void setSelectedAccounts(long[] accountIds) {
|
||||
final ParcelableAccount[] accounts = ParcelableAccount.getAccounts(getContext(), accountIds);
|
||||
if (accounts != null) {
|
||||
final int[] colors = new int[accounts.length];
|
||||
for (int i = 0, j = colors.length; i < j; i++) {
|
||||
colors[i] = accounts[i].color;
|
||||
}
|
||||
mColorLabelHelper.drawEnd(colors);
|
||||
} else {
|
||||
mColorLabelHelper.drawEnd(null);
|
||||
}
|
||||
mAccountIconsAdapter.setSelectedAccounts(accounts);
|
||||
}
|
||||
|
||||
private static class AccountIconsAdapter extends Adapter<AccountIconViewHolder> {
|
||||
private final Context mContext;
|
||||
private final LayoutInflater mInflater;
|
||||
private final ImageLoaderWrapper mImageLoader;
|
||||
private ParcelableAccount[] mAccounts;
|
||||
|
||||
public ImageLoaderWrapper getImageLoader() {
|
||||
return mImageLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccountIconViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
final View view = mInflater.inflate(R.layout.adapter_item_compose_account, parent, false);
|
||||
return new AccountIconViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(AccountIconViewHolder holder, int position) {
|
||||
holder.showAccount(this, mAccounts[position]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mAccounts != null ? mAccounts.length : 0;
|
||||
}
|
||||
|
||||
public void setSelectedAccounts(ParcelableAccount[] accounts) {
|
||||
if (accounts != null) {
|
||||
// ArrayUtils.reverse(accounts);
|
||||
}
|
||||
mAccounts = accounts;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public AccountIconsAdapter(Context context) {
|
||||
mContext = context;
|
||||
mInflater = LayoutInflater.from(context);
|
||||
mImageLoader = TwidereApplication.getInstance(context).getImageLoaderWrapper();
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyLinearLayoutManager extends LinearLayoutManager {
|
||||
private int mWidth, mHeight;
|
||||
|
||||
public MyLinearLayoutManager(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecyclerView.LayoutParams generateLayoutParams(Context c, AttributeSet attrs) {
|
||||
final RecyclerView.LayoutParams layoutParams = super.generateLayoutParams(c, attrs);
|
||||
return layoutParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLayoutChildren(Recycler recycler, State state) {
|
||||
state.getItemCount();
|
||||
super.onLayoutChildren(recycler, state);
|
||||
}
|
||||
|
||||
private int findChildIndex(View view) {
|
||||
for (int i = 0, j = getChildCount(); i < j; i++) {
|
||||
if (getChildAt(i) == view) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void measureChildWithMargins(View child, int widthUsed, int heightUsed) {
|
||||
final RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
|
||||
final int contentWidth = mWidth - getPaddingLeft() - getPaddingRight();
|
||||
final int contentHeight = mHeight - getPaddingTop() - getPaddingBottom();
|
||||
final int itemCount = getItemCount();
|
||||
final int firstVisibleItem = findFirstVisibleItemPosition();
|
||||
final int idx = findChildIndex(child);
|
||||
if (firstVisibleItem < 1 && idx == 0) {
|
||||
// when firstVisibleItem is 0 or -1, assume view with idx == 0 is first view
|
||||
layoutParams.leftMargin = 0;
|
||||
} else {
|
||||
layoutParams.leftMargin = -Math.min((contentHeight * itemCount - contentWidth)
|
||||
/ (itemCount - 1) + child.getPaddingLeft() + child.getPaddingRight(), contentHeight);
|
||||
}
|
||||
super.measureChildWithMargins(child, widthUsed, heightUsed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMeasure(Recycler recycler, State state, int widthSpec, int heightSpec) {
|
||||
final int height = MeasureSpec.getSize(heightSpec), width = Math.round(height * 1.5f);
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
super.onMeasure(recycler, state, MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), heightSpec);
|
||||
}
|
||||
}
|
||||
|
||||
private static class InternalRecyclerView extends RecyclerView {
|
||||
public InternalRecyclerView(Context context) {
|
||||
super(context);
|
||||
setChildrenDrawingOrderEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getChildDrawingOrder(int childCount, int i) {
|
||||
return childCount - i - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchTouchEvent(@NonNull MotionEvent ev) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -35,7 +35,6 @@ public class HomeSlidingMenu extends SlidingMenu implements Constants {
|
|||
mActivity = (HomeActivity) context;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean dispatchTouchEvent(@NonNull final MotionEvent ev) {
|
||||
switch (ev.getActionMasked()) {
|
||||
|
|
|
@ -1,18 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<org.mariotaku.twidere.view.ColorLabelFrameLayout
|
||||
<org.mariotaku.twidere.view.ComposeSelectAccountButton
|
||||
android:id="@+id/select_account"
|
||||
style="?android:actionButtonStyle"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
app:ignorePadding="true">
|
||||
|
||||
<org.mariotaku.twidere.view.ActionIconView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/ic_action_accounts"/>
|
||||
|
||||
</org.mariotaku.twidere.view.ColorLabelFrameLayout>
|
||||
android:layout_weight="0"
|
||||
android:padding="@dimen/element_spacing_small"/>
|
|
@ -6,6 +6,5 @@
|
|||
android:id="@+id/home_menu"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
app:viewAbove="@layout/activity_home_content"/>
|
||||
</merge>
|
|
@ -1,9 +1,28 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Twidere - Twitter client for Android
|
||||
~
|
||||
~ Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
~
|
||||
~ This program is free software: you can redistribute it and/or modify
|
||||
~ it under the terms of the GNU General Public License as published by
|
||||
~ the Free Software Foundation, either version 3 of the License, or
|
||||
~ (at your option) any later version.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
~ GNU General Public License for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License
|
||||
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<org.mariotaku.twidere.view.SquareFrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="@dimen/element_spacing_msmall">
|
||||
android:padding="@dimen/element_spacing_small">
|
||||
|
||||
<org.mariotaku.twidere.view.CircularImageView
|
||||
android:id="@android:id/icon"
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Twidere - Twitter client for Android
|
||||
~
|
||||
~ Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
~
|
||||
~ This program is free software: you can redistribute it and/or modify
|
||||
~ it under the terms of the GNU General Public License as published by
|
||||
~ the Free Software Foundation, either version 3 of the License, or
|
||||
~ (at your option) any later version.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
~ GNU General Public License for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License
|
||||
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<org.mariotaku.twidere.view.SquareFrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="@dimen/element_spacing_msmall">
|
||||
|
||||
<org.mariotaku.twidere.view.CircularImageView
|
||||
android:id="@android:id/icon"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
</org.mariotaku.twidere.view.SquareFrameLayout>
|
|
@ -18,6 +18,7 @@
|
|||
<dimen name="element_spacing_minus_msmall">-6dp</dimen>
|
||||
<dimen name="element_spacing_minus_normal">-8dp</dimen>
|
||||
<dimen name="element_spacing_minus_large">-16dp</dimen>
|
||||
<dimen name="element_spacing_minus_xlarge">-24dp</dimen>
|
||||
<dimen name="icon_size_list_item">56dp</dimen>
|
||||
<dimen name="icon_size_list_item_small">42dp</dimen>
|
||||
<dimen name="icon_size_card_list_item">48dp</dimen>
|
||||
|
|
Loading…
Reference in New Issue