parent
3e383ce492
commit
2d2c94c321
|
@ -1,3 +1,5 @@
|
|||
import java.text.SimpleDateFormat
|
||||
|
||||
apply plugin: 'com.android.application'
|
||||
apply from: rootProject.file('signing.gradle')
|
||||
|
||||
|
@ -10,7 +12,7 @@ android {
|
|||
minSdkVersion 14
|
||||
targetSdkVersion 21
|
||||
versionCode 99
|
||||
versionName "0.3.0-dev"
|
||||
versionName "0.3.0"
|
||||
multiDexEnabled true
|
||||
}
|
||||
compileOptions {
|
||||
|
@ -32,10 +34,14 @@ android {
|
|||
}
|
||||
productFlavors {
|
||||
google {
|
||||
versionName = versionName + '-google'
|
||||
}
|
||||
fdroid {
|
||||
versionName = versionName + '-fdroid'
|
||||
}
|
||||
}
|
||||
buildTypes {
|
||||
debug {
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd")
|
||||
versionNameSuffix String.format(" (dev %s)", format.format(new Date()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -569,9 +569,9 @@
|
|||
</activity>
|
||||
<activity
|
||||
android:name=".activity.TestActivity"
|
||||
android:enabled="false"
|
||||
android:enabled="true"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/Theme.Test"
|
||||
android:theme="@android:style/Theme.DeviceDefault.Dialog"
|
||||
android:label="Twidere test"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<intent-filter>
|
||||
|
|
|
@ -23,12 +23,14 @@ import android.app.Activity;
|
|||
import android.os.Bundle;
|
||||
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.R;
|
||||
|
||||
public class TestActivity extends Activity implements Constants {
|
||||
|
||||
@Override
|
||||
protected void onCreate(final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_test);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ import android.content.Intent;
|
|||
import android.content.SharedPreferences;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.PorterDuff.Mode;
|
||||
import android.graphics.Rect;
|
||||
import android.location.Criteria;
|
||||
import android.location.Location;
|
||||
|
@ -52,6 +53,7 @@ import android.support.v4.app.FragmentActivity;
|
|||
import android.support.v4.app.NotificationCompat;
|
||||
import android.support.v4.app.NotificationCompat.Action;
|
||||
import android.support.v4.util.LongSparseArray;
|
||||
import android.support.v7.internal.view.SupportMenuInflater;
|
||||
import android.support.v7.widget.ActionMenuView;
|
||||
import android.support.v7.widget.ActionMenuView.OnMenuItemClickListener;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
|
@ -60,6 +62,7 @@ import android.support.v7.widget.RecyclerView.Adapter;
|
|||
import android.support.v7.widget.RecyclerView.ItemDecoration;
|
||||
import android.support.v7.widget.RecyclerView.State;
|
||||
import android.support.v7.widget.RecyclerView.ViewHolder;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
|
@ -86,7 +89,6 @@ import org.mariotaku.dynamicgridview.DraggableArrayAdapter;
|
|||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.app.TwidereApplication;
|
||||
import org.mariotaku.twidere.fragment.support.BaseSupportDialogFragment;
|
||||
import org.mariotaku.twidere.graphic.ActionIconDrawable;
|
||||
import org.mariotaku.twidere.model.DraftItem;
|
||||
import org.mariotaku.twidere.model.ParcelableAccount;
|
||||
import org.mariotaku.twidere.model.ParcelableLocation;
|
||||
|
@ -112,7 +114,7 @@ import org.mariotaku.twidere.util.TwidereValidator;
|
|||
import org.mariotaku.twidere.util.UserColorNameUtils;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.util.accessor.ViewAccessor;
|
||||
import org.mariotaku.twidere.util.menu.TwidereMenuInfo;
|
||||
import org.mariotaku.twidere.view.ActionIconView;
|
||||
import org.mariotaku.twidere.view.BadgeView;
|
||||
import org.mariotaku.twidere.view.ShapedImageView;
|
||||
import org.mariotaku.twidere.view.StatusTextCountView;
|
||||
|
@ -190,6 +192,10 @@ public class ComposeActivity extends ThemedActionBarActivity implements TextWatc
|
|||
private BadgeView mCountView;
|
||||
private View mAccountSelectorButton;
|
||||
private ImageLoaderWrapper mImageLoader;
|
||||
private View mLocationContainer;
|
||||
private ActionIconView mLocationIcon;
|
||||
private SupportMenuInflater mMenuInflater;
|
||||
private Toolbar mToolbar;
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after) {
|
||||
|
@ -252,15 +258,7 @@ public class ComposeActivity extends ThemedActionBarActivity implements TextWatc
|
|||
break;
|
||||
}
|
||||
case MENU_ADD_LOCATION: {
|
||||
final boolean attachLocation = mPreferences.getBoolean(KEY_ATTACH_LOCATION, false);
|
||||
if (!attachLocation) {
|
||||
getLocation();
|
||||
} else {
|
||||
mLocationManager.removeUpdates(this);
|
||||
}
|
||||
mPreferences.edit().putBoolean(KEY_ATTACH_LOCATION, !attachLocation).apply();
|
||||
setMenu();
|
||||
updateTextCount();
|
||||
toggleLocation();
|
||||
break;
|
||||
}
|
||||
case MENU_DRAFTS: {
|
||||
|
@ -336,6 +334,29 @@ public class ComposeActivity extends ThemedActionBarActivity implements TextWatc
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
private void toggleLocation() {
|
||||
final boolean attachLocation = mPreferences.getBoolean(KEY_ATTACH_LOCATION, false);
|
||||
if (!attachLocation) {
|
||||
getLocation();
|
||||
} else {
|
||||
mLocationManager.removeUpdates(this);
|
||||
}
|
||||
mPreferences.edit().putBoolean(KEY_ATTACH_LOCATION, !attachLocation).apply();
|
||||
setMenu();
|
||||
updateLocationState();
|
||||
updateTextCount();
|
||||
}
|
||||
|
||||
private void updateLocationState() {
|
||||
final boolean attachLocation = mPreferences.getBoolean(KEY_ATTACH_LOCATION, false);
|
||||
if (attachLocation) {
|
||||
mLocationIcon.setColorFilter(getCurrentThemeColor(), Mode.SRC_ATOP);
|
||||
} else {
|
||||
mLocationIcon.setColorFilter(mLocationIcon.getDefaultColor(), Mode.SRC_ATOP);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(final int requestCode, final int resultCode, final Intent intent) {
|
||||
switch (requestCode) {
|
||||
|
@ -438,6 +459,10 @@ public class ComposeActivity extends ThemedActionBarActivity implements TextWatc
|
|||
mAccountSelectorContainer.setVisibility(isVisible ? View.GONE : View.VISIBLE);
|
||||
break;
|
||||
}
|
||||
case R.id.location_container: {
|
||||
toggleLocation();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -511,6 +536,7 @@ public class ComposeActivity extends ThemedActionBarActivity implements TextWatc
|
|||
@Override
|
||||
public void onSupportContentChanged() {
|
||||
super.onSupportContentChanged();
|
||||
mToolbar = (Toolbar) findViewById(R.id.compose_actionbar);
|
||||
mEditText = (EditText) findViewById(R.id.edit_text);
|
||||
mMediaPreviewGrid = (GridView) findViewById(R.id.media_thumbnail_preview);
|
||||
mMenuBar = (ActionMenuView) findViewById(R.id.menu_bar);
|
||||
|
@ -522,6 +548,8 @@ public class ComposeActivity extends ThemedActionBarActivity implements TextWatc
|
|||
mProfileImageView = (ShapedImageView) findViewById(R.id.account_profile_image);
|
||||
mCountView = (BadgeView) findViewById(R.id.accounts_count);
|
||||
mAccountSelectorButton = findViewById(R.id.account_selector_button);
|
||||
mLocationContainer = findViewById(R.id.location_container);
|
||||
mLocationIcon = (ActionIconView) findViewById(R.id.location_icon);
|
||||
ViewAccessor.setBackground(findViewById(R.id.compose_content), getWindowContentOverlayForCompose(this));
|
||||
}
|
||||
|
||||
|
@ -559,7 +587,8 @@ public class ComposeActivity extends ThemedActionBarActivity implements TextWatc
|
|||
mValidator = new TwidereValidator(this);
|
||||
mImageLoader = app.getImageLoaderWrapper();
|
||||
setContentView(R.layout.activity_compose);
|
||||
setProgressBarIndeterminateVisibility(false);
|
||||
setSupportActionBar(mToolbar);
|
||||
setSupportProgressBarIndeterminateVisibility(false);
|
||||
setFinishOnTouchOutside(false);
|
||||
final long[] defaultAccountIds = getAccountIds(this);
|
||||
if (defaultAccountIds.length <= 0) {
|
||||
|
@ -575,6 +604,7 @@ public class ComposeActivity extends ThemedActionBarActivity implements TextWatc
|
|||
mEditText.addTextChangedListener(this);
|
||||
mAccountSelectorContainer.setOnClickListener(this);
|
||||
mAccountSelectorButton.setOnClickListener(this);
|
||||
mLocationContainer.setOnClickListener(this);
|
||||
|
||||
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
|
||||
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
|
||||
|
@ -643,6 +673,7 @@ public class ComposeActivity extends ThemedActionBarActivity implements TextWatc
|
|||
addIntentToMenu(this, mediaMenuItem.getSubMenu(), imageExtensionsIntent, MENU_GROUP_IMAGE_EXTENSION);
|
||||
}
|
||||
setMenu();
|
||||
updateLocationState();
|
||||
updateMediaPreview();
|
||||
notifyAccountSelectionChanged();
|
||||
}
|
||||
|
@ -997,24 +1028,6 @@ public class ComposeActivity extends ThemedActionBarActivity implements TextWatc
|
|||
private void setMenu() {
|
||||
if (mMenuBar == null) return;
|
||||
final Menu menu = mMenuBar.getMenu();
|
||||
final MenuItem itemAttachLocation = menu.findItem(MENU_ADD_LOCATION);
|
||||
if (itemAttachLocation != null) {
|
||||
final boolean attachLocation = mPreferences.getBoolean(KEY_ATTACH_LOCATION, false);
|
||||
final int menuHighlight = ThemeUtils.getUserAccentColor(this);
|
||||
if (attachLocation && getLocation()) {
|
||||
itemAttachLocation.setChecked(true);
|
||||
ActionIconDrawable.setMenuHighlight(itemAttachLocation, new TwidereMenuInfo(true, menuHighlight));
|
||||
} else {
|
||||
setProgressVisibility(false);
|
||||
mPreferences.edit().putBoolean(KEY_ATTACH_LOCATION, false).apply();
|
||||
itemAttachLocation.setChecked(false);
|
||||
ActionIconDrawable.setMenuHighlight(itemAttachLocation, new TwidereMenuInfo(false, menuHighlight));
|
||||
}
|
||||
}
|
||||
final MenuItem viewItem = menu.findItem(MENU_VIEW);
|
||||
if (viewItem != null) {
|
||||
viewItem.setVisible(mInReplyToStatus != null);
|
||||
}
|
||||
final boolean hasMedia = hasMedia(), hasInReplyTo = mInReplyToStatus != null;
|
||||
|
||||
/*
|
||||
|
|
|
@ -17,19 +17,22 @@
|
|||
package org.mariotaku.twidere.activity.support;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnLayoutChangeListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
import com.diegocarloslima.byakugallery.lib.TileBitmapDrawable;
|
||||
import com.diegocarloslima.byakugallery.lib.TileBitmapDrawable.OnInitializeListener;
|
||||
import com.diegocarloslima.byakugallery.lib.TouchImageView;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
@ -38,6 +41,7 @@ import org.mariotaku.twidere.R;
|
|||
import org.mariotaku.twidere.adapter.support.SupportFixedFragmentStatePagerAdapter;
|
||||
import org.mariotaku.twidere.fragment.support.BaseSupportFragment;
|
||||
import org.mariotaku.twidere.loader.support.TileImageLoader;
|
||||
import org.mariotaku.twidere.loader.support.TileImageLoader.DownloadListener;
|
||||
import org.mariotaku.twidere.loader.support.TileImageLoader.Result;
|
||||
import org.mariotaku.twidere.model.ParcelableMedia;
|
||||
import org.mariotaku.twidere.util.ThemeUtils;
|
||||
|
@ -77,13 +81,20 @@ public final class MediaViewerActivity extends BaseSupportActivity implements Co
|
|||
}
|
||||
|
||||
public static final class MediaPageFragment extends BaseSupportFragment
|
||||
implements TileImageLoader.DownloadListener, LoaderManager.LoaderCallbacks<TileImageLoader.Result> {
|
||||
implements DownloadListener, LoaderCallbacks<Result>, OnLayoutChangeListener {
|
||||
|
||||
private TouchImageView mImageView;
|
||||
private ProgressBar mProgressBar;
|
||||
private boolean mLoaderInitialized;
|
||||
private long mContentLength;
|
||||
|
||||
@Override
|
||||
public void onBaseViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onBaseViewCreated(view, savedInstanceState);
|
||||
mImageView = (TouchImageView) view.findViewById(R.id.image_view);
|
||||
mProgressBar = (ProgressBar) view.findViewById(R.id.progress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loader<Result> onCreateLoader(final int id, final Bundle args) {
|
||||
mProgressBar.setVisibility(View.VISIBLE);
|
||||
|
@ -94,11 +105,69 @@ public final class MediaViewerActivity extends BaseSupportActivity implements Co
|
|||
return new TileImageLoader(getActivity(), this, accountId, Uri.parse(media.media_url));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(final Loader<TileImageLoader.Result> loader, final TileImageLoader.Result data) {
|
||||
if (data.hasData()) {
|
||||
mImageView.setVisibility(View.VISIBLE);
|
||||
if (data.useDecoder) {
|
||||
TileBitmapDrawable.attachTileBitmapDrawable(mImageView, data.file.getAbsolutePath(),
|
||||
null, new OnInitializeListener() {
|
||||
@Override
|
||||
public void onStartInitialization() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEndInitialization() {
|
||||
mImageView.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateScaleLimit();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
mImageView.setImageBitmap(data.bitmap);
|
||||
updateScaleLimit();
|
||||
}
|
||||
} else {
|
||||
mImageView.setVisibility(View.GONE);
|
||||
Utils.showErrorMessage(getActivity(), null, data.exception, true);
|
||||
}
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
mProgressBar.setProgress(0);
|
||||
invalidateOptionsMenu();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(final Loader<TileImageLoader.Result> loader) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.fragment_media_page, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
loadImage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
mImageView.addOnLayoutChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
mImageView.removeOnLayoutChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownloadError(final Throwable t) {
|
||||
mContentLength = 0;
|
||||
|
@ -116,31 +185,6 @@ public final class MediaViewerActivity extends BaseSupportActivity implements Co
|
|||
mProgressBar.setMax(total > 0 ? (int) (total / 1024) : 0);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(final Loader<TileImageLoader.Result> loader) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(final Loader<TileImageLoader.Result> loader, final TileImageLoader.Result data) {
|
||||
if (data.hasData()) {
|
||||
mImageView.setVisibility(View.VISIBLE);
|
||||
if (data.useDecoder) {
|
||||
TileBitmapDrawable.attachTileBitmapDrawable(mImageView, data.file.getAbsolutePath(),
|
||||
null, null);
|
||||
} else {
|
||||
mImageView.setImageBitmap(data.bitmap);
|
||||
}
|
||||
} else {
|
||||
mImageView.setVisibility(View.GONE);
|
||||
Utils.showErrorMessage(getActivity(), null, data.exception, true);
|
||||
}
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
mProgressBar.setProgress(0);
|
||||
invalidateOptionsMenu();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressUpdate(final long downloaded) {
|
||||
if (mContentLength == 0) {
|
||||
|
@ -152,16 +196,8 @@ public final class MediaViewerActivity extends BaseSupportActivity implements Co
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onBaseViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onBaseViewCreated(view, savedInstanceState);
|
||||
mImageView = (TouchImageView) view.findViewById(R.id.image_view);
|
||||
mProgressBar = (ProgressBar) view.findViewById(R.id.progress);
|
||||
}
|
||||
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
loadImage();
|
||||
}
|
||||
|
||||
private void loadImage() {
|
||||
|
@ -173,6 +209,18 @@ public final class MediaViewerActivity extends BaseSupportActivity implements Co
|
|||
getLoaderManager().restartLoader(0, getArguments(), this);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateScaleLimit() {
|
||||
final int viewWidth = mImageView.getWidth(), viewHeight = mImageView.getHeight();
|
||||
final Drawable drawable = mImageView.getDrawable();
|
||||
if (drawable == null || viewWidth <= 0 || viewHeight <= 0) return;
|
||||
final int drawableWidth = drawable.getIntrinsicWidth();
|
||||
final int drawableHeight = drawable.getIntrinsicHeight();
|
||||
if (drawableWidth <= 0 || drawableHeight <= 0) return;
|
||||
final float widthRatio = viewWidth / (float) drawableWidth;
|
||||
final float heightRatio = viewHeight / (float) drawableHeight;
|
||||
mImageView.setMaxScale(Math.max(1, Math.max(heightRatio, widthRatio)));
|
||||
}
|
||||
}
|
||||
|
||||
private static class MediaPagerAdapter extends SupportFixedFragmentStatePagerAdapter {
|
||||
|
|
|
@ -1,319 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.activity.support;
|
||||
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.ActionBar.OnMenuVisibilityListener;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
import com.diegocarloslima.byakugallery.lib.TileBitmapDrawable;
|
||||
import com.diegocarloslima.byakugallery.lib.TileBitmapDrawable.OnInitializeListener;
|
||||
import com.diegocarloslima.byakugallery.lib.TouchImageView;
|
||||
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.loader.support.TileImageLoader;
|
||||
import org.mariotaku.twidere.util.SaveImageTask;
|
||||
import org.mariotaku.twidere.util.ThemeUtils;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public final class MediaViewerActivityOld extends BaseSupportActivity implements Constants,
|
||||
TileImageLoader.DownloadListener, LoaderManager.LoaderCallbacks<TileImageLoader.Result>,
|
||||
OnMenuVisibilityListener {
|
||||
|
||||
|
||||
private ActionBar mActionBar;
|
||||
|
||||
private ProgressBar mProgress;
|
||||
private TouchImageView mImageView;
|
||||
|
||||
private long mContentLength;
|
||||
|
||||
private File mImageFile;
|
||||
private boolean mLoaderInitialized;
|
||||
|
||||
@Override
|
||||
public int getThemeResourceId() {
|
||||
return ThemeUtils.getViewerThemeResource(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onSupportContentChanged() {
|
||||
super.onSupportContentChanged();
|
||||
mImageView = (TouchImageView) findViewById(R.id.image_viewer);
|
||||
mProgress = (ProgressBar) findViewById(R.id.progress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loader<TileImageLoader.Result> onCreateLoader(final int id, final Bundle args) {
|
||||
mProgress.setVisibility(View.VISIBLE);
|
||||
mProgress.setIndeterminate(true);
|
||||
invalidateOptionsMenu();
|
||||
final Uri uri = args.getParcelable(EXTRA_URI);
|
||||
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
return new TileImageLoader(this, this, accountId, uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(final Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_image_viewer_action_bar, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onDownloadError(final Throwable t) {
|
||||
mContentLength = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownloadFinished() {
|
||||
mContentLength = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownloadStart(final long total) {
|
||||
mContentLength = total;
|
||||
mProgress.setIndeterminate(total <= 0);
|
||||
mProgress.setMax(total > 0 ? (int) (total / 1024) : 0);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(final Loader<TileImageLoader.Result> loader) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(final Loader<TileImageLoader.Result> loader, final TileImageLoader.Result data) {
|
||||
if (data.hasData()) {
|
||||
mImageView.setVisibility(View.VISIBLE);
|
||||
// mImageView.setBitmapRegionDecoder(data.decoder, data.bitmap);
|
||||
// mImageView.setScale(1);
|
||||
if (data.useDecoder) {
|
||||
TileBitmapDrawable.attachTileBitmapDrawable(mImageView, data.file.getAbsolutePath(), null, new OnInitializeListener() {
|
||||
@Override
|
||||
public void onStartInitialization() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEndInitialization() {
|
||||
|
||||
}
|
||||
});
|
||||
} else {
|
||||
mImageView.setImageBitmap(data.bitmap);
|
||||
}
|
||||
mImageFile = data.file;
|
||||
} else {
|
||||
mImageView.setVisibility(View.GONE);
|
||||
mImageFile = null;
|
||||
Utils.showErrorMessage(this, null, data.exception, true);
|
||||
}
|
||||
mProgress.setVisibility(View.GONE);
|
||||
mProgress.setProgress(0);
|
||||
invalidateOptionsMenu();
|
||||
updateShareIntent();
|
||||
}
|
||||
|
||||
// @Override
|
||||
public boolean onMenuItemClick(final MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case MENU_SAVE: {
|
||||
if (mImageFile != null) {
|
||||
new SaveImageTask(this, mImageFile).execute();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MENU_OPEN_IN_BROWSER: {
|
||||
final Intent intent = getIntent();
|
||||
intent.setExtrasClassLoader(getClassLoader());
|
||||
final Uri uri = intent.getData();
|
||||
final Uri orig = intent.getParcelableExtra(EXTRA_URI_ORIG);
|
||||
final Uri uriPreferred = orig != null ? orig : uri;
|
||||
if (uriPreferred == null) return false;
|
||||
final String scheme = uriPreferred.getScheme();
|
||||
if ("http".equals(scheme) || "https".equals(scheme)) {
|
||||
final Intent open_intent = new Intent(Intent.ACTION_VIEW, uriPreferred);
|
||||
open_intent.addCategory(Intent.CATEGORY_BROWSABLE);
|
||||
try {
|
||||
startActivity(open_intent);
|
||||
} catch (final ActivityNotFoundException e) {
|
||||
// Ignore.
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
final Intent intent = item.getIntent();
|
||||
if (intent != null) {
|
||||
try {
|
||||
startActivity(intent);
|
||||
} catch (final ActivityNotFoundException e) {
|
||||
// Ignore.
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMenuVisibilityChanged(final boolean isVisible) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case MENU_HOME: {
|
||||
onBackPressed();
|
||||
break;
|
||||
}
|
||||
case MENU_REFRESH: {
|
||||
loadImage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(final Menu menu) {
|
||||
final LoaderManager lm = getSupportLoaderManager();
|
||||
Utils.setMenuItemAvailability(menu, MENU_REFRESH, !lm.hasRunningLoaders());
|
||||
return super.onPrepareOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressUpdate(final long downloaded) {
|
||||
if (mContentLength == 0) {
|
||||
mProgress.setIndeterminate(true);
|
||||
return;
|
||||
}
|
||||
mProgress.setIndeterminate(false);
|
||||
mProgress.setProgress((int) (downloaded / 1024));
|
||||
}
|
||||
|
||||
|
||||
public void showProgress() {
|
||||
mProgress.setVisibility(View.VISIBLE);
|
||||
mProgress.setIndeterminate(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.image_viewer_old);
|
||||
mActionBar = getSupportActionBar();
|
||||
mActionBar.setDisplayHomeAsUpEnabled(true);
|
||||
mActionBar.addOnMenuVisibilityListener(this);
|
||||
if (savedInstanceState == null) {
|
||||
loadImage();
|
||||
}
|
||||
|
||||
// mImageView.setScaleToFit(false);
|
||||
mImageView.setMaxScale(2);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
mActionBar.removeOnMenuVisibilityListener(this);
|
||||
super.onDestroy();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNewIntent(final Intent intent) {
|
||||
setIntent(intent);
|
||||
loadImage();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void loadImage() {
|
||||
getSupportLoaderManager().destroyLoader(0);
|
||||
final Intent intent = getIntent();
|
||||
final Uri uri = intent.getData();
|
||||
final long accountId = intent.getLongExtra(EXTRA_ACCOUNT_ID, -1);
|
||||
if (uri == null) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
final Bundle args = new Bundle();
|
||||
args.putParcelable(EXTRA_URI, uri);
|
||||
args.putLong(EXTRA_ACCOUNT_ID, accountId);
|
||||
if (!mLoaderInitialized) {
|
||||
getSupportLoaderManager().initLoader(0, args, this);
|
||||
mLoaderInitialized = true;
|
||||
} else {
|
||||
getSupportLoaderManager().restartLoader(0, args, this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void updateShareIntent() {
|
||||
// final MenuItem item = mMenuBar.getMenu().findItem(MENU_SHARE);
|
||||
// if (item == null || !item.hasSubMenu()) return;
|
||||
// final SubMenu subMenu = item.getSubMenu();
|
||||
// subMenu.clear();
|
||||
// final Intent intent = getIntent();
|
||||
// final Uri uri = intent.getData();
|
||||
// final Intent shareIntent = new Intent(Intent.ACTION_SEND);
|
||||
// if (mImageFile != null && mImageFile.exists()) {
|
||||
// shareIntent.setType("image/*");
|
||||
// shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(mImageFile));
|
||||
// } else {
|
||||
// shareIntent.setType("text/plain");
|
||||
// shareIntent.putExtra(Intent.EXTRA_TEXT, uri.toString());
|
||||
// }
|
||||
// Utils.addIntentToMenu(this, subMenu, shareIntent);
|
||||
}
|
||||
|
||||
}
|
|
@ -52,6 +52,7 @@ import android.widget.Spinner;
|
|||
import android.widget.TextView;
|
||||
import android.widget.TextView.OnEditorActionListener;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.mariotaku.querybuilder.Columns.Column;
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.querybuilder.OrderBy;
|
||||
|
@ -68,8 +69,11 @@ import org.mariotaku.twidere.provider.TwidereDataStore.SavedSearches;
|
|||
import org.mariotaku.twidere.provider.TwidereDataStore.SearchHistory;
|
||||
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
||||
import org.mariotaku.twidere.util.ParseUtils;
|
||||
import org.mariotaku.twidere.util.SwipeDismissListViewTouchListener;
|
||||
import org.mariotaku.twidere.util.SwipeDismissListViewTouchListener.DismissCallbacks;
|
||||
import org.mariotaku.twidere.util.ThemeUtils;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.util.content.ContentResolverUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -80,7 +84,7 @@ import static org.mariotaku.twidere.util.UserColorNameUtils.getUserNickname;
|
|||
* Created by mariotaku on 15/1/6.
|
||||
*/
|
||||
public class QuickSearchBarActivity extends BaseSupportActivity implements OnClickListener,
|
||||
OnEditorActionListener, LoaderCallbacks<List<SuggestionItem>>, TextWatcher, OnItemSelectedListener, OnItemClickListener {
|
||||
OnEditorActionListener, LoaderCallbacks<List<SuggestionItem>>, TextWatcher, OnItemSelectedListener, OnItemClickListener, DismissCallbacks {
|
||||
|
||||
private Spinner mAccountSpinner;
|
||||
private EditText mSearchQuery;
|
||||
|
@ -93,6 +97,27 @@ public class QuickSearchBarActivity extends BaseSupportActivity implements OnCli
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDismiss(int position) {
|
||||
return position < getHistorySize(mSearchQuery.getText());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDismiss(ListView listView, int[] reverseSortedPositions) {
|
||||
final long[] ids = new long[reverseSortedPositions.length];
|
||||
for (int i = 0, j = reverseSortedPositions.length; i < j; i++) {
|
||||
final int position = reverseSortedPositions[i];
|
||||
final SearchHistoryItem item = (SearchHistoryItem) mUsersSearchAdapter.getItem(position);
|
||||
mUsersSearchAdapter.removeItemAt(position);
|
||||
ids[i] = item.getCursorId();
|
||||
}
|
||||
final ContentResolver cr = getContentResolver();
|
||||
final Long[] idsObject = ArrayUtils.toObject(ids);
|
||||
ContentResolverUtils.bulkDelete(cr, SearchHistory.CONTENT_URI, SearchHistory._ID, idsObject,
|
||||
null, false);
|
||||
getSupportLoaderManager().restartLoader(0, null, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
final SuggestionItem item = mUsersSearchAdapter.getItem(position);
|
||||
|
@ -134,6 +159,9 @@ public class QuickSearchBarActivity extends BaseSupportActivity implements OnCli
|
|||
mUsersSearchAdapter = new SuggestionsAdapter(this);
|
||||
mSuggestionsList.setAdapter(mUsersSearchAdapter);
|
||||
mSuggestionsList.setOnItemClickListener(this);
|
||||
final SwipeDismissListViewTouchListener listener = new SwipeDismissListViewTouchListener(mSuggestionsList, this);
|
||||
mSuggestionsList.setOnTouchListener(listener);
|
||||
mSuggestionsList.setOnScrollListener(listener.makeScrollListener());
|
||||
mSearchSubmit.setOnClickListener(this);
|
||||
mSearchQuery.setOnEditorActionListener(this);
|
||||
mSearchQuery.addTextChangedListener(this);
|
||||
|
@ -272,9 +300,15 @@ public class QuickSearchBarActivity extends BaseSupportActivity implements OnCli
|
|||
static class SearchHistoryItem extends BaseClickableItem {
|
||||
|
||||
static final int ITEM_VIEW_TYPE = 1;
|
||||
private final long mCursorId;
|
||||
private final String mQuery;
|
||||
|
||||
public SearchHistoryItem(String query) {
|
||||
public long getCursorId() {
|
||||
return mCursorId;
|
||||
}
|
||||
|
||||
public SearchHistoryItem(long cursorId, String query) {
|
||||
mCursorId = cursorId;
|
||||
mQuery = query;
|
||||
}
|
||||
|
||||
|
@ -467,12 +501,22 @@ public class QuickSearchBarActivity extends BaseSupportActivity implements OnCli
|
|||
return mNicknameOnly;
|
||||
}
|
||||
|
||||
public void removeItemAt(int position) {
|
||||
if (mData == null) return;
|
||||
mData.remove(position);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void setData(List<SuggestionItem> data) {
|
||||
mData = data;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private static int getHistorySize(CharSequence query) {
|
||||
return TextUtils.isEmpty(query) ? 3 : 2;
|
||||
}
|
||||
|
||||
public static class SuggestionsLoader extends AsyncTaskLoader<List<SuggestionItem>> {
|
||||
|
||||
private final long mAccountId;
|
||||
|
@ -490,12 +534,12 @@ public class QuickSearchBarActivity extends BaseSupportActivity implements OnCli
|
|||
final Context context = getContext();
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
final List<SuggestionItem> result = new ArrayList<>();
|
||||
final String[] historyProjection = {SearchHistory.QUERY};
|
||||
final String[] historyProjection = {SearchHistory._ID, SearchHistory.QUERY};
|
||||
final Cursor historyCursor = resolver.query(SearchHistory.CONTENT_URI,
|
||||
historyProjection, null, null, SearchHistory.DEFAULT_SORT_ORDER);
|
||||
for (int i = 0, j = Math.min(emptyQuery ? 3 : 2, historyCursor.getCount()); i < j; i++) {
|
||||
for (int i = 0, j = Math.min(getHistorySize(mQuery), historyCursor.getCount()); i < j; i++) {
|
||||
historyCursor.moveToPosition(i);
|
||||
result.add(new SearchHistoryItem(historyCursor.getString(0)));
|
||||
result.add(new SearchHistoryItem(historyCursor.getLong(0), historyCursor.getString(1)));
|
||||
}
|
||||
historyCursor.close();
|
||||
if (!emptyQuery) {
|
||||
|
|
|
@ -103,7 +103,8 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement
|
|||
private TextView mAppMenuSectionView;
|
||||
private View mAccountSelectorView;
|
||||
private RecyclerView mAccountsSelector;
|
||||
private ImageView mAccountProfileBannerView, mAccountProfileImageView;
|
||||
private ImageView mAccountProfileBannerView;
|
||||
private ShapedImageView mAccountProfileImageView;
|
||||
private TextView mAccountProfileNameView, mAccountProfileScreenNameView;
|
||||
private Switch mAccountsToggle;
|
||||
private View mAccountProfileContainer;
|
||||
|
@ -317,7 +318,7 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement
|
|||
mAccountsSelector.setLayoutManager(layoutManager);
|
||||
mAccountsSelector.setAdapter(mAccountsAdapter);
|
||||
mAccountProfileContainer = mAccountSelectorView.findViewById(R.id.profile_container);
|
||||
mAccountProfileImageView = (ImageView) mAccountSelectorView.findViewById(R.id.profile_image);
|
||||
mAccountProfileImageView = (ShapedImageView) mAccountSelectorView.findViewById(R.id.profile_image);
|
||||
mAccountProfileBannerView = (ImageView) mAccountSelectorView.findViewById(R.id.account_profile_banner);
|
||||
mAccountProfileNameView = (TextView) mAccountSelectorView.findViewById(R.id.name);
|
||||
mAccountProfileScreenNameView = (TextView) mAccountSelectorView.findViewById(R.id.screen_name);
|
||||
|
@ -391,6 +392,7 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement
|
|||
mAccountProfileScreenNameView.setText("@" + account.screen_name);
|
||||
mAccountsToggle.setChecked(account.is_activated);
|
||||
mImageLoader.displayProfileImage(mAccountProfileImageView, account.profile_image_url);
|
||||
mAccountProfileImageView.setBorderColors(account.color);
|
||||
final int bannerWidth = mAccountProfileBannerView.getWidth();
|
||||
final Resources res = getResources();
|
||||
final int defWidth = res.getDisplayMetrics().widthPixels;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
package org.mariotaku.twidere.preference;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.preference.Preference.OnPreferenceClickListener;
|
||||
import android.provider.SearchRecentSuggestions;
|
||||
|
@ -26,28 +27,31 @@ import android.util.AttributeSet;
|
|||
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.provider.RecentSearchProvider;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.SearchHistory;
|
||||
|
||||
public class ClearSearchHistoryPreference extends AsyncTaskPreference implements Constants, OnPreferenceClickListener {
|
||||
|
||||
public ClearSearchHistoryPreference(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
public ClearSearchHistoryPreference(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public ClearSearchHistoryPreference(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, android.R.attr.preferenceStyle);
|
||||
}
|
||||
public ClearSearchHistoryPreference(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, android.R.attr.preferenceStyle);
|
||||
}
|
||||
|
||||
public ClearSearchHistoryPreference(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
public ClearSearchHistoryPreference(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doInBackground() {
|
||||
final Context context = getContext();
|
||||
if (context == null) return;
|
||||
final SearchRecentSuggestions suggestions = new SearchRecentSuggestions(context,
|
||||
RecentSearchProvider.AUTHORITY, RecentSearchProvider.MODE);
|
||||
suggestions.clearHistory();
|
||||
}
|
||||
@Override
|
||||
protected void doInBackground() {
|
||||
final Context context = getContext();
|
||||
if (context == null) return;
|
||||
final SearchRecentSuggestions suggestions = new SearchRecentSuggestions(context,
|
||||
RecentSearchProvider.AUTHORITY, RecentSearchProvider.MODE);
|
||||
suggestions.clearHistory();
|
||||
final ContentResolver cr = context.getContentResolver();
|
||||
cr.delete(SearchHistory.CONTENT_URI, null, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,399 @@
|
|||
/*
|
||||
* Copyright 2013 Google Inc.
|
||||
*
|
||||
* 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 org.mariotaku.twidere.util;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.graphics.Rect;
|
||||
import android.os.SystemClock;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.VelocityTracker;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewPropertyAnimator;
|
||||
import android.widget.AbsListView;
|
||||
import android.widget.ListView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A {@link View.OnTouchListener} that makes the list items in a {@link ListView}
|
||||
* dismissable. {@link ListView} is given special treatment because by default it handles touches
|
||||
* for its list items... i.e. it's in charge of drawing the pressed state (the list selector),
|
||||
* handling list item clicks, etc.
|
||||
* <p/>
|
||||
* <p>After creating the listener, the caller should also call
|
||||
* {@link ListView#setOnScrollListener(AbsListView.OnScrollListener)}, passing
|
||||
* in the scroll listener returned by {@link #makeScrollListener()}. If a scroll listener is
|
||||
* already assigned, the caller should still pass scroll changes through to this listener. This will
|
||||
* ensure that this {@link SwipeDismissListViewTouchListener} is paused during list view
|
||||
* scrolling.</p>
|
||||
* <p/>
|
||||
* <p>Example usage:</p>
|
||||
* <p/>
|
||||
* <pre>
|
||||
* SwipeDismissListViewTouchListener touchListener =
|
||||
* new SwipeDismissListViewTouchListener(
|
||||
* listView,
|
||||
* new SwipeDismissListViewTouchListener.OnDismissCallback() {
|
||||
* public void onDismiss(ListView listView, int[] reverseSortedPositions) {
|
||||
* for (int position : reverseSortedPositions) {
|
||||
* adapter.remove(adapter.getItem(position));
|
||||
* }
|
||||
* adapter.notifyDataSetChanged();
|
||||
* }
|
||||
* });
|
||||
* listView.setOnTouchListener(touchListener);
|
||||
* listView.setOnScrollListener(touchListener.makeScrollListener());
|
||||
* </pre>
|
||||
* <p/>
|
||||
* <p>This class Requires API level 12 or later due to use of {@link
|
||||
* ViewPropertyAnimator}.</p>
|
||||
*/
|
||||
public class SwipeDismissListViewTouchListener implements View.OnTouchListener {
|
||||
// Cached ViewConfiguration and system-wide constant values
|
||||
private int mSlop;
|
||||
private int mMinFlingVelocity;
|
||||
private int mMaxFlingVelocity;
|
||||
private long mAnimationTime;
|
||||
|
||||
// Fixed properties
|
||||
private ListView mListView;
|
||||
private DismissCallbacks mCallbacks;
|
||||
private int mViewWidth = 1; // 1 and not 0 to prevent dividing by zero
|
||||
|
||||
// Transient properties
|
||||
private List<PendingDismissData> mPendingDismisses = new ArrayList<PendingDismissData>();
|
||||
private int mDismissAnimationRefCount = 0;
|
||||
private float mDownX;
|
||||
private float mDownY;
|
||||
private boolean mSwiping;
|
||||
private int mSwipingSlop;
|
||||
private VelocityTracker mVelocityTracker;
|
||||
private int mDownPosition;
|
||||
private View mDownView;
|
||||
private boolean mPaused;
|
||||
|
||||
/**
|
||||
* The callback interface used by {@link SwipeDismissListViewTouchListener} to inform its client
|
||||
* about a successful dismissal of one or more list item positions.
|
||||
*/
|
||||
public interface DismissCallbacks {
|
||||
/**
|
||||
* Called to determine whether the given position can be dismissed.
|
||||
*/
|
||||
boolean canDismiss(int position);
|
||||
|
||||
/**
|
||||
* Called when the user has indicated they she would like to dismiss one or more list item
|
||||
* positions.
|
||||
*
|
||||
* @param listView The originating {@link ListView}.
|
||||
* @param reverseSortedPositions An array of positions to dismiss, sorted in descending
|
||||
* order for convenience.
|
||||
*/
|
||||
void onDismiss(ListView listView, int[] reverseSortedPositions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new swipe-to-dismiss touch listener for the given list view.
|
||||
*
|
||||
* @param listView The list view whose items should be dismissable.
|
||||
* @param callbacks The callback to trigger when the user has indicated that she would like to
|
||||
* dismiss one or more list items.
|
||||
*/
|
||||
public SwipeDismissListViewTouchListener(ListView listView, DismissCallbacks callbacks) {
|
||||
ViewConfiguration vc = ViewConfiguration.get(listView.getContext());
|
||||
mSlop = vc.getScaledTouchSlop();
|
||||
mMinFlingVelocity = vc.getScaledMinimumFlingVelocity() * 16;
|
||||
mMaxFlingVelocity = vc.getScaledMaximumFlingVelocity();
|
||||
mAnimationTime = listView.getContext().getResources().getInteger(
|
||||
android.R.integer.config_shortAnimTime);
|
||||
mListView = listView;
|
||||
mCallbacks = callbacks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables (pauses or resumes) watching for swipe-to-dismiss gestures.
|
||||
*
|
||||
* @param enabled Whether or not to watch for gestures.
|
||||
*/
|
||||
public void setEnabled(boolean enabled) {
|
||||
mPaused = !enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@link AbsListView.OnScrollListener} to be added to the {@link
|
||||
* ListView} using {@link ListView#setOnScrollListener(AbsListView.OnScrollListener)}.
|
||||
* If a scroll listener is already assigned, the caller should still pass scroll changes through
|
||||
* to this listener. This will ensure that this {@link SwipeDismissListViewTouchListener} is
|
||||
* paused during list view scrolling.</p>
|
||||
*
|
||||
* @see SwipeDismissListViewTouchListener
|
||||
*/
|
||||
public AbsListView.OnScrollListener makeScrollListener() {
|
||||
return new AbsListView.OnScrollListener() {
|
||||
@Override
|
||||
public void onScrollStateChanged(AbsListView absListView, int scrollState) {
|
||||
setEnabled(scrollState != AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScroll(AbsListView absListView, int i, int i1, int i2) {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View view, MotionEvent motionEvent) {
|
||||
if (mViewWidth < 2) {
|
||||
mViewWidth = mListView.getWidth();
|
||||
}
|
||||
|
||||
switch (motionEvent.getActionMasked()) {
|
||||
case MotionEvent.ACTION_DOWN: {
|
||||
if (mPaused) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: ensure this is a finger, and set a flag
|
||||
|
||||
// Find the child view that was touched (perform a hit test)
|
||||
Rect rect = new Rect();
|
||||
int childCount = mListView.getChildCount();
|
||||
int[] listViewCoords = new int[2];
|
||||
mListView.getLocationOnScreen(listViewCoords);
|
||||
int x = (int) motionEvent.getRawX() - listViewCoords[0];
|
||||
int y = (int) motionEvent.getRawY() - listViewCoords[1];
|
||||
View child;
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
child = mListView.getChildAt(i);
|
||||
child.getHitRect(rect);
|
||||
if (rect.contains(x, y)) {
|
||||
mDownView = child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mDownView != null) {
|
||||
mDownX = motionEvent.getRawX();
|
||||
mDownY = motionEvent.getRawY();
|
||||
mDownPosition = mListView.getPositionForView(mDownView);
|
||||
if (mCallbacks.canDismiss(mDownPosition)) {
|
||||
mVelocityTracker = VelocityTracker.obtain();
|
||||
mVelocityTracker.addMovement(motionEvent);
|
||||
} else {
|
||||
mDownView = null;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
case MotionEvent.ACTION_CANCEL: {
|
||||
if (mVelocityTracker == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (mDownView != null && mSwiping) {
|
||||
// cancel
|
||||
mDownView.animate()
|
||||
.translationX(0)
|
||||
.alpha(1)
|
||||
.setDuration(mAnimationTime)
|
||||
.setListener(null);
|
||||
}
|
||||
mVelocityTracker.recycle();
|
||||
mVelocityTracker = null;
|
||||
mDownX = 0;
|
||||
mDownY = 0;
|
||||
mDownView = null;
|
||||
mDownPosition = ListView.INVALID_POSITION;
|
||||
mSwiping = false;
|
||||
break;
|
||||
}
|
||||
|
||||
case MotionEvent.ACTION_UP: {
|
||||
if (mVelocityTracker == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
float deltaX = motionEvent.getRawX() - mDownX;
|
||||
mVelocityTracker.addMovement(motionEvent);
|
||||
mVelocityTracker.computeCurrentVelocity(1000);
|
||||
float velocityX = mVelocityTracker.getXVelocity();
|
||||
float absVelocityX = Math.abs(velocityX);
|
||||
float absVelocityY = Math.abs(mVelocityTracker.getYVelocity());
|
||||
boolean dismiss = false;
|
||||
boolean dismissRight = false;
|
||||
if (Math.abs(deltaX) > mViewWidth / 2 && mSwiping) {
|
||||
dismiss = true;
|
||||
dismissRight = deltaX > 0;
|
||||
} else if (mMinFlingVelocity <= absVelocityX && absVelocityX <= mMaxFlingVelocity
|
||||
&& absVelocityY < absVelocityX && mSwiping) {
|
||||
// dismiss only if flinging in the same direction as dragging
|
||||
dismiss = (velocityX < 0) == (deltaX < 0);
|
||||
dismissRight = mVelocityTracker.getXVelocity() > 0;
|
||||
}
|
||||
if (dismiss && mDownPosition != ListView.INVALID_POSITION) {
|
||||
// dismiss
|
||||
final View downView = mDownView; // mDownView gets null'd before animation ends
|
||||
final int downPosition = mDownPosition;
|
||||
++mDismissAnimationRefCount;
|
||||
mDownView.animate()
|
||||
.translationX(dismissRight ? mViewWidth : -mViewWidth)
|
||||
.alpha(0)
|
||||
.setDuration(mAnimationTime)
|
||||
.setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
performDismiss(downView, downPosition);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// cancel
|
||||
mDownView.animate()
|
||||
.translationX(0)
|
||||
.alpha(1)
|
||||
.setDuration(mAnimationTime)
|
||||
.setListener(null);
|
||||
}
|
||||
mVelocityTracker.recycle();
|
||||
mVelocityTracker = null;
|
||||
mDownX = 0;
|
||||
mDownY = 0;
|
||||
mDownView = null;
|
||||
mDownPosition = ListView.INVALID_POSITION;
|
||||
mSwiping = false;
|
||||
break;
|
||||
}
|
||||
|
||||
case MotionEvent.ACTION_MOVE: {
|
||||
if (mVelocityTracker == null || mPaused) {
|
||||
break;
|
||||
}
|
||||
|
||||
mVelocityTracker.addMovement(motionEvent);
|
||||
float deltaX = motionEvent.getRawX() - mDownX;
|
||||
float deltaY = motionEvent.getRawY() - mDownY;
|
||||
if (Math.abs(deltaX) > mSlop && Math.abs(deltaY) < Math.abs(deltaX) / 2) {
|
||||
mSwiping = true;
|
||||
mSwipingSlop = (deltaX > 0 ? mSlop : -mSlop);
|
||||
mListView.requestDisallowInterceptTouchEvent(true);
|
||||
|
||||
// Cancel ListView's touch (un-highlighting the item)
|
||||
MotionEvent cancelEvent = MotionEvent.obtain(motionEvent);
|
||||
cancelEvent.setAction(MotionEvent.ACTION_CANCEL |
|
||||
(motionEvent.getActionIndex()
|
||||
<< MotionEvent.ACTION_POINTER_INDEX_SHIFT));
|
||||
mListView.onTouchEvent(cancelEvent);
|
||||
cancelEvent.recycle();
|
||||
}
|
||||
|
||||
if (mSwiping) {
|
||||
mDownView.setTranslationX(deltaX - mSwipingSlop);
|
||||
mDownView.setAlpha(Math.max(0f, Math.min(1f,
|
||||
1f - 2f * Math.abs(deltaX) / mViewWidth)));
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
class PendingDismissData implements Comparable<PendingDismissData> {
|
||||
public int position;
|
||||
public View view;
|
||||
|
||||
public PendingDismissData(int position, View view) {
|
||||
this.position = position;
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(PendingDismissData other) {
|
||||
// Sort by descending position
|
||||
return other.position - position;
|
||||
}
|
||||
}
|
||||
|
||||
private void performDismiss(final View dismissView, final int dismissPosition) {
|
||||
// Animate the dismissed list item to zero-height and fire the dismiss callback when
|
||||
// all dismissed list item animations have completed. This triggers layout on each animation
|
||||
// frame; in the future we may want to do something smarter and more performant.
|
||||
|
||||
final ViewGroup.LayoutParams lp = dismissView.getLayoutParams();
|
||||
final int originalHeight = dismissView.getHeight();
|
||||
|
||||
ValueAnimator animator = ValueAnimator.ofInt(originalHeight, 1).setDuration(mAnimationTime);
|
||||
|
||||
animator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
--mDismissAnimationRefCount;
|
||||
if (mDismissAnimationRefCount == 0) {
|
||||
// No active animations, process all pending dismisses.
|
||||
// Sort by descending position
|
||||
Collections.sort(mPendingDismisses);
|
||||
|
||||
int[] dismissPositions = new int[mPendingDismisses.size()];
|
||||
for (int i = mPendingDismisses.size() - 1; i >= 0; i--) {
|
||||
dismissPositions[i] = mPendingDismisses.get(i).position;
|
||||
}
|
||||
mCallbacks.onDismiss(mListView, dismissPositions);
|
||||
|
||||
// Reset mDownPosition to avoid MotionEvent.ACTION_UP trying to start a dismiss
|
||||
// animation with a stale position
|
||||
mDownPosition = ListView.INVALID_POSITION;
|
||||
|
||||
ViewGroup.LayoutParams lp;
|
||||
for (PendingDismissData pendingDismiss : mPendingDismisses) {
|
||||
// Reset view presentation
|
||||
pendingDismiss.view.setAlpha(1f);
|
||||
pendingDismiss.view.setTranslationX(0);
|
||||
lp = pendingDismiss.view.getLayoutParams();
|
||||
lp.height = originalHeight;
|
||||
pendingDismiss.view.setLayoutParams(lp);
|
||||
}
|
||||
|
||||
// Send a cancel event
|
||||
long time = SystemClock.uptimeMillis();
|
||||
MotionEvent cancelEvent = MotionEvent.obtain(time, time,
|
||||
MotionEvent.ACTION_CANCEL, 0, 0, 0);
|
||||
mListView.dispatchTouchEvent(cancelEvent);
|
||||
|
||||
mPendingDismisses.clear();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator valueAnimator) {
|
||||
lp.height = (Integer) valueAnimator.getAnimatedValue();
|
||||
dismissView.setLayoutParams(lp);
|
||||
}
|
||||
});
|
||||
|
||||
mPendingDismisses.add(new PendingDismissData(dismissPosition, dismissView));
|
||||
animator.start();
|
||||
}
|
||||
}
|
|
@ -27,21 +27,21 @@ import android.widget.ImageView;
|
|||
|
||||
public class ActionBarHomeAsUpIndicator extends ImageView {
|
||||
|
||||
public ActionBarHomeAsUpIndicator(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
public ActionBarHomeAsUpIndicator(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public ActionBarHomeAsUpIndicator(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
public ActionBarHomeAsUpIndicator(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public ActionBarHomeAsUpIndicator(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
final TypedArray a = context.obtainStyledAttributes(new int[] { android.R.attr.homeAsUpIndicator });
|
||||
final Drawable d = a.getDrawable(0);
|
||||
a.recycle();
|
||||
setImageDrawable(d);
|
||||
setScaleType(ScaleType.CENTER);
|
||||
}
|
||||
public ActionBarHomeAsUpIndicator(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
final TypedArray a = context.obtainStyledAttributes(new int[]{android.R.attr.homeAsUpIndicator});
|
||||
final Drawable d = a.getDrawable(0);
|
||||
a.recycle();
|
||||
setImageDrawable(d);
|
||||
setScaleType(ScaleType.CENTER);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,21 +26,21 @@ import android.widget.TextView;
|
|||
|
||||
public class ActionBarSubtitleView extends TextView {
|
||||
|
||||
public ActionBarSubtitleView(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
public ActionBarSubtitleView(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public ActionBarSubtitleView(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
public ActionBarSubtitleView(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public ActionBarSubtitleView(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
final TypedArray a = context.obtainStyledAttributes(null, new int[] { android.R.attr.subtitleTextStyle },
|
||||
android.R.attr.actionBarStyle, android.R.style.Widget_Holo_ActionBar);
|
||||
final int textAppearance = a.getResourceId(0, android.R.style.Widget_Holo_ActionBar);
|
||||
a.recycle();
|
||||
setTextAppearance(context, textAppearance);
|
||||
}
|
||||
public ActionBarSubtitleView(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
final TypedArray a = context.obtainStyledAttributes(null, new int[]{android.R.attr.subtitleTextStyle},
|
||||
android.R.attr.actionBarStyle, android.R.style.Widget_Holo_ActionBar);
|
||||
final int textAppearance = a.getResourceId(0, android.R.style.Widget_Holo_ActionBar);
|
||||
a.recycle();
|
||||
setTextAppearance(context, textAppearance);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,61 +31,61 @@ import org.mariotaku.twidere.R;
|
|||
|
||||
public class ActionBarTabView extends FrameLayout {
|
||||
|
||||
private CharSequence mTitle;
|
||||
private Drawable mIcon;
|
||||
private CharSequence mTitle;
|
||||
private Drawable mIcon;
|
||||
|
||||
public ActionBarTabView(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
public ActionBarTabView(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public ActionBarTabView(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, android.R.attr.actionBarTabStyle);
|
||||
}
|
||||
public ActionBarTabView(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, android.R.attr.actionBarTabStyle);
|
||||
}
|
||||
|
||||
public ActionBarTabView(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
inflate(context, R.layout.tab_item_ab, this);
|
||||
}
|
||||
public ActionBarTabView(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
inflate(context, R.layout.tab_item_ab, this);
|
||||
}
|
||||
|
||||
public void setIcon(final Drawable icon) {
|
||||
mIcon = icon;
|
||||
setIconView(icon);
|
||||
}
|
||||
public void setIcon(final Drawable icon) {
|
||||
mIcon = icon;
|
||||
setIconView(icon);
|
||||
}
|
||||
|
||||
public void setIcon(final int iconRes) {
|
||||
setIcon(getResources().getDrawable(iconRes));
|
||||
}
|
||||
public void setIcon(final int iconRes) {
|
||||
setIcon(getResources().getDrawable(iconRes));
|
||||
}
|
||||
|
||||
public void setIconView(final Drawable icon) {
|
||||
final ImageView iconView = (ImageView) findViewById(android.R.id.icon);
|
||||
if (iconView == null) return;
|
||||
iconView.setVisibility(icon != null ? GONE : VISIBLE);
|
||||
iconView.setImageDrawable(icon);
|
||||
}
|
||||
public void setIconView(final Drawable icon) {
|
||||
final ImageView iconView = (ImageView) findViewById(android.R.id.icon);
|
||||
if (iconView == null) return;
|
||||
iconView.setVisibility(icon != null ? GONE : VISIBLE);
|
||||
iconView.setImageDrawable(icon);
|
||||
}
|
||||
|
||||
public void setTitle(final CharSequence title) {
|
||||
mTitle = title;
|
||||
setTitleView(title);
|
||||
}
|
||||
public void setTitle(final CharSequence title) {
|
||||
mTitle = title;
|
||||
setTitleView(title);
|
||||
}
|
||||
|
||||
public void setTitle(final int titleRes) {
|
||||
setTitle(getResources().getText(titleRes));
|
||||
}
|
||||
public void setTitle(final int titleRes) {
|
||||
setTitle(getResources().getText(titleRes));
|
||||
}
|
||||
|
||||
public void setTitleView(final CharSequence title) {
|
||||
final TextView titleView = (TextView) findViewById(android.R.id.title);
|
||||
final ImageView iconView = (ImageView) findViewById(android.R.id.icon);
|
||||
if (titleView == null || iconView == null) return;
|
||||
titleView.setVisibility(TextUtils.isEmpty(title) ? GONE : VISIBLE);
|
||||
titleView.setText(title);
|
||||
iconView.setContentDescription(title);
|
||||
}
|
||||
public void setTitleView(final CharSequence title) {
|
||||
final TextView titleView = (TextView) findViewById(android.R.id.title);
|
||||
final ImageView iconView = (ImageView) findViewById(android.R.id.icon);
|
||||
if (titleView == null || iconView == null) return;
|
||||
titleView.setVisibility(TextUtils.isEmpty(title) ? GONE : VISIBLE);
|
||||
titleView.setText(title);
|
||||
iconView.setContentDescription(title);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
setTitleView(mTitle);
|
||||
setIconView(mIcon);
|
||||
}
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
setTitleView(mTitle);
|
||||
setIconView(mIcon);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,25 +28,26 @@ import org.mariotaku.twidere.util.ThemeUtils;
|
|||
|
||||
public class ActionBarThemedContainer extends FrameLayout {
|
||||
|
||||
public ActionBarThemedContainer(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
public ActionBarThemedContainer(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public ActionBarThemedContainer(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
public ActionBarThemedContainer(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public ActionBarThemedContainer(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
final TypedArray a = context.obtainStyledAttributes(attrs, new int[] { android.R.attr.layout });
|
||||
final int resId = a.getResourceId(0, 0);
|
||||
a.recycle();
|
||||
if (resId == 0) throw new IllegalArgumentException("You must specify a layout resource in layout XML file.");
|
||||
inflate(getThemedContext(context), resId, this);
|
||||
}
|
||||
public ActionBarThemedContainer(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
final TypedArray a = context.obtainStyledAttributes(attrs, new int[]{android.R.attr.layout});
|
||||
final int resId = a.getResourceId(0, 0);
|
||||
a.recycle();
|
||||
if (resId == 0)
|
||||
throw new IllegalArgumentException("You must specify a layout resource in layout XML file.");
|
||||
inflate(getThemedContext(context), resId, this);
|
||||
}
|
||||
|
||||
private static Context getThemedContext(final Context context) {
|
||||
return ThemeUtils.getActionBarContext(context);
|
||||
}
|
||||
private static Context getThemedContext(final Context context) {
|
||||
return ThemeUtils.getActionBarContext(context);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,21 +26,21 @@ import android.widget.TextView;
|
|||
|
||||
public class ActionBarTitleView extends TextView {
|
||||
|
||||
public ActionBarTitleView(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
public ActionBarTitleView(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public ActionBarTitleView(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
public ActionBarTitleView(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public ActionBarTitleView(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
final TypedArray a = context.obtainStyledAttributes(null, new int[] { android.R.attr.titleTextStyle },
|
||||
android.R.attr.actionBarStyle, android.R.style.Widget_Holo_ActionBar);
|
||||
final int textAppearance = a.getResourceId(0, android.R.style.Widget_Holo_TextView);
|
||||
a.recycle();
|
||||
setTextAppearance(context, textAppearance);
|
||||
}
|
||||
public ActionBarTitleView(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
final TypedArray a = context.obtainStyledAttributes(null, new int[]{android.R.attr.titleTextStyle},
|
||||
android.R.attr.actionBarStyle, android.R.style.Widget_Holo_ActionBar);
|
||||
final int textAppearance = a.getResourceId(0, android.R.style.Widget_Holo_TextView);
|
||||
a.recycle();
|
||||
setTextAppearance(context, textAppearance);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,22 +25,22 @@ import android.widget.CheckBox;
|
|||
|
||||
public class ActivatedCheckBox extends CheckBox {
|
||||
|
||||
public ActivatedCheckBox(final Context context) {
|
||||
super(context);
|
||||
}
|
||||
public ActivatedCheckBox(final Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public ActivatedCheckBox(final Context context, final AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
public ActivatedCheckBox(final Context context, final AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public ActivatedCheckBox(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
public ActivatedCheckBox(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActivated(final boolean activated) {
|
||||
super.setActivated(activated);
|
||||
setChecked(activated);
|
||||
}
|
||||
@Override
|
||||
public void setActivated(final boolean activated) {
|
||||
super.setActivated(activated);
|
||||
setChecked(activated);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,32 +28,32 @@ import android.widget.ImageView;
|
|||
|
||||
public class AutoAdjustHeightImageView extends ImageView {
|
||||
|
||||
public AutoAdjustHeightImageView(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
public AutoAdjustHeightImageView(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public AutoAdjustHeightImageView(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
public AutoAdjustHeightImageView(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public AutoAdjustHeightImageView(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
setScaleType(ScaleType.CENTER_CROP);
|
||||
}
|
||||
public AutoAdjustHeightImageView(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
setScaleType(ScaleType.CENTER_CROP);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||
final int width = MeasureSpec.getSize(widthMeasureSpec);
|
||||
final Drawable d = getDrawable();
|
||||
final Bitmap b = d instanceof BitmapDrawable ? ((BitmapDrawable) d).getBitmap() : null;
|
||||
@Override
|
||||
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||
final int width = MeasureSpec.getSize(widthMeasureSpec);
|
||||
final Drawable d = getDrawable();
|
||||
final Bitmap b = d instanceof BitmapDrawable ? ((BitmapDrawable) d).getBitmap() : null;
|
||||
|
||||
if (b != null) {
|
||||
final int height = Math.round((float) width * (float) b.getHeight() / b.getWidth());
|
||||
setMeasuredDimension(width, height);
|
||||
} else {
|
||||
setMeasuredDimension(width, width);
|
||||
// super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
}
|
||||
if (b != null) {
|
||||
final int height = Math.round((float) width * (float) b.getHeight() / b.getWidth());
|
||||
setMeasuredDimension(width, height);
|
||||
} else {
|
||||
setMeasuredDimension(width, width);
|
||||
// super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -61,6 +61,14 @@ public class BadgeView extends View {
|
|||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
if (!mTextBounds.isEmpty()) {
|
||||
canvas.drawText(mText, mTextX, mTextY, mTextPaint);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTextPosition() {
|
||||
final int width = getWidth(), height = getHeight();
|
||||
if (width == 0 || height == 0) return;
|
||||
|
@ -78,12 +86,4 @@ public class BadgeView extends View {
|
|||
mTextBounds.setEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
if (!mTextBounds.isEmpty()) {
|
||||
canvas.drawText(mText, mTextX, mTextY, mTextPaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,6 +49,15 @@ public class BottomDividerFrameLayout extends FrameLayout {
|
|||
a.recycle();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
final Drawable divider = mDividerDrawable;
|
||||
if (divider != null) {
|
||||
divider.draw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
|
@ -59,13 +68,4 @@ public class BottomDividerFrameLayout extends FrameLayout {
|
|||
divider.setBounds(drawableLeft, drawableTop, drawableRight, drawableBottom);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
final Drawable divider = mDividerDrawable;
|
||||
if (divider != null) {
|
||||
divider.draw(canvas);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,65 +28,65 @@ import org.mariotaku.twidere.view.iface.IColorLabelView;
|
|||
|
||||
public class ColorLabelFrameLayout extends FrameLayout implements IColorLabelView {
|
||||
|
||||
private final Helper mHelper;
|
||||
private final Helper mHelper;
|
||||
|
||||
public ColorLabelFrameLayout(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
public ColorLabelFrameLayout(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public ColorLabelFrameLayout(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
public ColorLabelFrameLayout(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public ColorLabelFrameLayout(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
mHelper = new Helper(this, context, attrs, defStyle);
|
||||
}
|
||||
public ColorLabelFrameLayout(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
mHelper = new Helper(this, context, attrs, defStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawBackground(final int color) {
|
||||
mHelper.drawBackground(color);
|
||||
}
|
||||
@Override
|
||||
public void drawBackground(final int color) {
|
||||
mHelper.drawBackground(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawBottom(final int... colors) {
|
||||
mHelper.drawBottom(colors);
|
||||
}
|
||||
@Override
|
||||
public void drawBottom(final int... colors) {
|
||||
mHelper.drawBottom(colors);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawEnd(final int... colors) {
|
||||
mHelper.drawEnd(colors);
|
||||
}
|
||||
@Override
|
||||
public void drawEnd(final int... colors) {
|
||||
mHelper.drawEnd(colors);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawLabel(final int[] start, final int[] end, final int[] top, final int[] bottom, final int background) {
|
||||
mHelper.drawLabel(start, end, top, bottom, background);
|
||||
}
|
||||
@Override
|
||||
public void drawLabel(final int[] start, final int[] end, final int[] top, final int[] bottom, final int background) {
|
||||
mHelper.drawLabel(start, end, top, bottom, background);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawStart(final int... colors) {
|
||||
mHelper.drawStart(colors);
|
||||
}
|
||||
@Override
|
||||
public void drawStart(final int... colors) {
|
||||
mHelper.drawStart(colors);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawTop(final int... colors) {
|
||||
mHelper.drawTop(colors);
|
||||
}
|
||||
@Override
|
||||
public void drawTop(final int... colors) {
|
||||
mHelper.drawTop(colors);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPaddingsIgnored() {
|
||||
return mHelper.isPaddingsIgnored();
|
||||
}
|
||||
@Override
|
||||
public boolean isPaddingsIgnored() {
|
||||
return mHelper.isPaddingsIgnored();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIgnorePaddings(final boolean ignorePaddings) {
|
||||
mHelper.setIgnorePaddings(ignorePaddings);
|
||||
}
|
||||
@Override
|
||||
public void setIgnorePaddings(final boolean ignorePaddings) {
|
||||
mHelper.setIgnorePaddings(ignorePaddings);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispatchDraw(final Canvas canvas) {
|
||||
mHelper.dispatchDrawBackground(canvas);
|
||||
super.dispatchDraw(canvas);
|
||||
mHelper.dispatchDrawLabels(canvas);
|
||||
}
|
||||
@Override
|
||||
protected void dispatchDraw(final Canvas canvas) {
|
||||
mHelper.dispatchDrawBackground(canvas);
|
||||
super.dispatchDraw(canvas);
|
||||
mHelper.dispatchDrawLabels(canvas);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,65 +28,65 @@ import org.mariotaku.twidere.view.iface.IColorLabelView;
|
|||
|
||||
public class ColorLabelLinearLayout extends LinearLayout implements IColorLabelView {
|
||||
|
||||
private final Helper mHelper;
|
||||
private final Helper mHelper;
|
||||
|
||||
public ColorLabelLinearLayout(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
public ColorLabelLinearLayout(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public ColorLabelLinearLayout(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
public ColorLabelLinearLayout(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public ColorLabelLinearLayout(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
mHelper = new Helper(this, context, attrs, defStyle);
|
||||
}
|
||||
public ColorLabelLinearLayout(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
mHelper = new Helper(this, context, attrs, defStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawBackground(final int color) {
|
||||
mHelper.drawBackground(color);
|
||||
}
|
||||
@Override
|
||||
public void drawBackground(final int color) {
|
||||
mHelper.drawBackground(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawBottom(final int... colors) {
|
||||
mHelper.drawBottom(colors);
|
||||
}
|
||||
@Override
|
||||
public void drawBottom(final int... colors) {
|
||||
mHelper.drawBottom(colors);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawEnd(final int... colors) {
|
||||
mHelper.drawEnd(colors);
|
||||
}
|
||||
@Override
|
||||
public void drawEnd(final int... colors) {
|
||||
mHelper.drawEnd(colors);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawLabel(final int[] start, final int[] end, final int[] top, final int[] bottom, final int background) {
|
||||
mHelper.drawLabel(start, end, top, bottom, background);
|
||||
}
|
||||
@Override
|
||||
public void drawLabel(final int[] start, final int[] end, final int[] top, final int[] bottom, final int background) {
|
||||
mHelper.drawLabel(start, end, top, bottom, background);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawStart(final int... colors) {
|
||||
mHelper.drawStart(colors);
|
||||
}
|
||||
@Override
|
||||
public void drawStart(final int... colors) {
|
||||
mHelper.drawStart(colors);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawTop(final int... colors) {
|
||||
mHelper.drawTop(colors);
|
||||
}
|
||||
@Override
|
||||
public void drawTop(final int... colors) {
|
||||
mHelper.drawTop(colors);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPaddingsIgnored() {
|
||||
return mHelper.isPaddingsIgnored();
|
||||
}
|
||||
@Override
|
||||
public boolean isPaddingsIgnored() {
|
||||
return mHelper.isPaddingsIgnored();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIgnorePaddings(final boolean ignorePaddings) {
|
||||
mHelper.setIgnorePaddings(ignorePaddings);
|
||||
}
|
||||
@Override
|
||||
public void setIgnorePaddings(final boolean ignorePaddings) {
|
||||
mHelper.setIgnorePaddings(ignorePaddings);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispatchDraw(final Canvas canvas) {
|
||||
mHelper.dispatchDrawBackground(canvas);
|
||||
super.dispatchDraw(canvas);
|
||||
mHelper.dispatchDrawLabels(canvas);
|
||||
}
|
||||
@Override
|
||||
protected void dispatchDraw(final Canvas canvas) {
|
||||
mHelper.dispatchDrawBackground(canvas);
|
||||
super.dispatchDraw(canvas);
|
||||
mHelper.dispatchDrawLabels(canvas);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,66 +28,66 @@ import org.mariotaku.twidere.view.iface.IColorLabelView;
|
|||
|
||||
public class ColorLabelRelativeLayout extends RelativeLayout implements IColorLabelView {
|
||||
|
||||
private final Helper mHelper;
|
||||
private final Helper mHelper;
|
||||
|
||||
public ColorLabelRelativeLayout(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
public ColorLabelRelativeLayout(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public ColorLabelRelativeLayout(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
public ColorLabelRelativeLayout(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public ColorLabelRelativeLayout(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
mHelper = new Helper(this, context, attrs, defStyle);
|
||||
}
|
||||
public ColorLabelRelativeLayout(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
mHelper = new Helper(this, context, attrs, defStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawBackground(final int color) {
|
||||
mHelper.drawBackground(color);
|
||||
}
|
||||
@Override
|
||||
public void drawBackground(final int color) {
|
||||
mHelper.drawBackground(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawBottom(final int... colors) {
|
||||
mHelper.drawBottom(colors);
|
||||
}
|
||||
@Override
|
||||
public void drawBottom(final int... colors) {
|
||||
mHelper.drawBottom(colors);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawEnd(final int... colors) {
|
||||
mHelper.drawEnd(colors);
|
||||
}
|
||||
@Override
|
||||
public void drawEnd(final int... colors) {
|
||||
mHelper.drawEnd(colors);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawLabel(final int[] start, final int[] end, final int[] top, final int[] bottom, final int background) {
|
||||
mHelper.drawLabel(start, end, top, bottom, background);
|
||||
}
|
||||
@Override
|
||||
public void drawLabel(final int[] start, final int[] end, final int[] top, final int[] bottom, final int background) {
|
||||
mHelper.drawLabel(start, end, top, bottom, background);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawStart(final int... colors) {
|
||||
mHelper.drawStart(colors);
|
||||
}
|
||||
@Override
|
||||
public void drawStart(final int... colors) {
|
||||
mHelper.drawStart(colors);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawTop(final int... colors) {
|
||||
mHelper.drawTop(colors);
|
||||
}
|
||||
@Override
|
||||
public void drawTop(final int... colors) {
|
||||
mHelper.drawTop(colors);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPaddingsIgnored() {
|
||||
return mHelper.isPaddingsIgnored();
|
||||
}
|
||||
@Override
|
||||
public boolean isPaddingsIgnored() {
|
||||
return mHelper.isPaddingsIgnored();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIgnorePaddings(final boolean ignorePaddings) {
|
||||
mHelper.setIgnorePaddings(ignorePaddings);
|
||||
}
|
||||
@Override
|
||||
public void setIgnorePaddings(final boolean ignorePaddings) {
|
||||
mHelper.setIgnorePaddings(ignorePaddings);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispatchDraw(final Canvas canvas) {
|
||||
mHelper.dispatchDrawBackground(canvas);
|
||||
super.dispatchDraw(canvas);
|
||||
mHelper.dispatchDrawLabels(canvas);
|
||||
}
|
||||
@Override
|
||||
protected void dispatchDraw(final Canvas canvas) {
|
||||
mHelper.dispatchDrawBackground(canvas);
|
||||
super.dispatchDraw(canvas);
|
||||
mHelper.dispatchDrawLabels(canvas);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -50,77 +50,53 @@ import org.mariotaku.twidere.graphic.AlphaPatternDrawable;
|
|||
public class ColorPickerView extends View {
|
||||
|
||||
private final static int PANEL_SAT_VAL = 0;
|
||||
|
||||
private final static int PANEL_HUE = 1;
|
||||
|
||||
private final static int PANEL_ALPHA = 2;
|
||||
|
||||
/**
|
||||
* The width in pixels of the border surrounding all color panels.
|
||||
*/
|
||||
private final static float BORDER_WIDTH_PX = 1;
|
||||
|
||||
/**
|
||||
* The width in dp of the hue panel.
|
||||
*/
|
||||
private float HUE_PANEL_WIDTH = 30f;
|
||||
|
||||
/**
|
||||
* The height in dp of the alpha panel
|
||||
*/
|
||||
private float ALPHA_PANEL_HEIGHT = 20f;
|
||||
|
||||
/**
|
||||
* The distance in dp between the different color panels.
|
||||
*/
|
||||
private float PANEL_SPACING = 10f;
|
||||
|
||||
/**
|
||||
* The radius in dp of the color palette tracker circle.
|
||||
*/
|
||||
private float PALETTE_CIRCLE_TRACKER_RADIUS = 5f;
|
||||
|
||||
/**
|
||||
* The dp which the tracker of the hue or alpha panel will extend outside of
|
||||
* its bounds.
|
||||
*/
|
||||
private float RECTANGLE_TRACKER_OFFSET = 2f;
|
||||
|
||||
private float mDensity = 1f;
|
||||
|
||||
private OnColorChangedListener mOnColorChangedListener;
|
||||
|
||||
private Paint mHuePaint, mSatValPaint;
|
||||
|
||||
private Paint mHueTrackerPaint, mSatValTrackerPaint;
|
||||
|
||||
private Paint mAlphaPaint;
|
||||
|
||||
private Paint mAlphaTextPaint;
|
||||
|
||||
private Paint mBorderPaint;
|
||||
|
||||
private Shader mAlphaShader;
|
||||
|
||||
private Shader mValShader, mSatShader, mHueShader;
|
||||
|
||||
private int mAlpha = 0xff;
|
||||
|
||||
private float mHue = 360f, mSat = 0f, mVal = 0f;
|
||||
|
||||
private String mAlphaSliderText = "";
|
||||
|
||||
private int mSliderTrackerColor = 0xff1c1c1c;
|
||||
private int mBorderColor = 0xff6E6E6E;
|
||||
|
||||
private boolean mShowAlphaPanel = false;
|
||||
|
||||
/*
|
||||
* To remember which panel that has the "focus" when processing hardware
|
||||
* button data.
|
||||
*/
|
||||
private int mLastTouchedPanel = PANEL_SAT_VAL;
|
||||
|
||||
private final static int PANEL_HUE = 1;
|
||||
private final static int PANEL_ALPHA = 2;
|
||||
/**
|
||||
* The width in pixels of the border surrounding all color panels.
|
||||
*/
|
||||
private final static float BORDER_WIDTH_PX = 1;
|
||||
/**
|
||||
* The width in dp of the hue panel.
|
||||
*/
|
||||
private float HUE_PANEL_WIDTH = 30f;
|
||||
/**
|
||||
* The height in dp of the alpha panel
|
||||
*/
|
||||
private float ALPHA_PANEL_HEIGHT = 20f;
|
||||
/**
|
||||
* The distance in dp between the different color panels.
|
||||
*/
|
||||
private float PANEL_SPACING = 10f;
|
||||
/**
|
||||
* The radius in dp of the color palette tracker circle.
|
||||
*/
|
||||
private float PALETTE_CIRCLE_TRACKER_RADIUS = 5f;
|
||||
/**
|
||||
* The dp which the tracker of the hue or alpha panel will extend outside of
|
||||
* its bounds.
|
||||
*/
|
||||
private float RECTANGLE_TRACKER_OFFSET = 2f;
|
||||
private float mDensity = 1f;
|
||||
private OnColorChangedListener mOnColorChangedListener;
|
||||
private Paint mHuePaint, mSatValPaint;
|
||||
private Paint mHueTrackerPaint, mSatValTrackerPaint;
|
||||
private Paint mAlphaPaint;
|
||||
private Paint mAlphaTextPaint;
|
||||
private Paint mBorderPaint;
|
||||
private Shader mAlphaShader;
|
||||
private Shader mValShader, mSatShader, mHueShader;
|
||||
private int mAlpha = 0xff;
|
||||
private float mHue = 360f, mSat = 0f, mVal = 0f;
|
||||
private String mAlphaSliderText = "";
|
||||
private int mSliderTrackerColor = 0xff1c1c1c;
|
||||
private int mBorderColor = 0xff6E6E6E;
|
||||
private boolean mShowAlphaPanel = false;
|
||||
/**
|
||||
* Offset from the edge we must have or else the finger tracker will get
|
||||
* clipped when it is drawn outside of the view.
|
||||
|
@ -164,6 +140,18 @@ public class ColorPickerView extends View {
|
|||
return mAlphaSliderText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text that should be shown in the alpha slider. Set to null to
|
||||
* disable text.
|
||||
*
|
||||
* @param text Text that should be shown.
|
||||
*/
|
||||
public void setAlphaSliderText(final String text) {
|
||||
|
||||
mAlphaSliderText = text;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the color of the border surrounding all panels.
|
||||
*/
|
||||
|
@ -171,6 +159,17 @@ public class ColorPickerView extends View {
|
|||
return mBorderColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the color of the border surrounding all panels.
|
||||
*
|
||||
* @param color
|
||||
*/
|
||||
public void setBorderColor(final int color) {
|
||||
|
||||
mBorderColor = color;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current color this view is showing.
|
||||
*
|
||||
|
@ -181,6 +180,61 @@ public class ColorPickerView extends View {
|
|||
return Color.HSVToColor(new float[]{mHue, mSat, mVal});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the color the view should show.
|
||||
*
|
||||
* @param color The color that should be selected.
|
||||
*/
|
||||
public void setColor(final int color) {
|
||||
|
||||
setColor(color, false);
|
||||
}
|
||||
|
||||
public static Bitmap getColorPreviewBitmap(final Context context, final int color, final boolean border) {
|
||||
if (context == null) return null;
|
||||
final float density = context.getResources().getDisplayMetrics().density;
|
||||
final int width = (int) (32 * density), height = (int) (32 * density);
|
||||
|
||||
final Bitmap bm = Bitmap.createBitmap(width, height, Config.ARGB_8888);
|
||||
final Canvas canvas = new Canvas(bm);
|
||||
|
||||
final int rectrangleSize = (int) (density * 5);
|
||||
final int numRectanglesHorizontal = (int) Math.ceil(width / rectrangleSize);
|
||||
final int numRectanglesVertical = (int) Math.ceil(height / rectrangleSize);
|
||||
final Rect r = new Rect();
|
||||
boolean verticalStartWhite = true;
|
||||
for (int i = 0; i <= numRectanglesVertical; i++) {
|
||||
|
||||
boolean isWhite = verticalStartWhite;
|
||||
for (int j = 0; j <= numRectanglesHorizontal; j++) {
|
||||
|
||||
r.top = i * rectrangleSize;
|
||||
r.left = j * rectrangleSize;
|
||||
r.bottom = r.top + rectrangleSize;
|
||||
r.right = r.left + rectrangleSize;
|
||||
final Paint paint = new Paint();
|
||||
paint.setColor(isWhite ? Color.WHITE : Color.GRAY);
|
||||
|
||||
canvas.drawRect(r, paint);
|
||||
|
||||
isWhite = !isWhite;
|
||||
}
|
||||
|
||||
verticalStartWhite = !verticalStartWhite;
|
||||
|
||||
}
|
||||
canvas.drawColor(color);
|
||||
if (border) {
|
||||
final Paint paint = new Paint();
|
||||
paint.setColor(Color.WHITE);
|
||||
paint.setStrokeWidth(1f * density);
|
||||
final float[] points = new float[]{0, 0, width, 0, 0, 0, 0, height, width, 0, width, height, 0, height,
|
||||
width, height};
|
||||
canvas.drawLines(points, paint);
|
||||
}
|
||||
return bm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the drawing offset of the color picker view. The drawing offset is
|
||||
* the distance from the side of a panel to the side of the view minus the
|
||||
|
@ -197,41 +251,13 @@ public class ColorPickerView extends View {
|
|||
return mSliderTrackerColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(final MotionEvent event) {
|
||||
public void setSliderTrackerColor(final int color) {
|
||||
|
||||
boolean update = false;
|
||||
mSliderTrackerColor = color;
|
||||
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
mStartTouchPoint = new Point((int) event.getX(), (int) event.getY());
|
||||
update = moveTrackersIfNeeded(event);
|
||||
break;
|
||||
mHueTrackerPaint.setColor(mSliderTrackerColor);
|
||||
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
update = moveTrackersIfNeeded(event);
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
mStartTouchPoint = null;
|
||||
update = moveTrackersIfNeeded(event);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (update) {
|
||||
if (mOnColorChangedListener != null) {
|
||||
final int color;
|
||||
if (mShowAlphaPanel) {
|
||||
color = Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal});
|
||||
} else {
|
||||
color = Color.HSVToColor(new float[]{mHue, mSat, mVal});
|
||||
}
|
||||
mOnColorChangedListener.onColorChanged(color);
|
||||
}
|
||||
invalidate();
|
||||
return true;
|
||||
}
|
||||
return super.onTouchEvent(event);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -306,126 +332,57 @@ public class ColorPickerView extends View {
|
|||
return super.onTrackballEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text that should be shown in the alpha slider. Set to null to
|
||||
* disable text.
|
||||
*
|
||||
* @param res string resource id.
|
||||
*/
|
||||
public void setAlphaSliderText(final int res) {
|
||||
@Override
|
||||
public boolean onTouchEvent(final MotionEvent event) {
|
||||
|
||||
final String text = getContext().getString(res);
|
||||
setAlphaSliderText(text);
|
||||
}
|
||||
boolean update = false;
|
||||
|
||||
/**
|
||||
* Set the text that should be shown in the alpha slider. Set to null to
|
||||
* disable text.
|
||||
*
|
||||
* @param text Text that should be shown.
|
||||
*/
|
||||
public void setAlphaSliderText(final String text) {
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
mStartTouchPoint = new Point((int) event.getX(), (int) event.getY());
|
||||
update = moveTrackersIfNeeded(event);
|
||||
break;
|
||||
|
||||
mAlphaSliderText = text;
|
||||
invalidate();
|
||||
}
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
update = moveTrackersIfNeeded(event);
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
mStartTouchPoint = null;
|
||||
update = moveTrackersIfNeeded(event);
|
||||
break;
|
||||
|
||||
/**
|
||||
* Set if the user is allowed to adjust the alpha panel. Default is false.
|
||||
* If it is set to false no alpha will be set.
|
||||
*
|
||||
* @param visible
|
||||
*/
|
||||
public void setAlphaSliderVisible(final boolean visible) {
|
||||
|
||||
if (mShowAlphaPanel != visible) {
|
||||
mShowAlphaPanel = visible;
|
||||
|
||||
/*
|
||||
* Reset all shader to force a recreation. Otherwise they will not
|
||||
* look right after the size of the view has changed.
|
||||
*/
|
||||
mValShader = null;
|
||||
mSatShader = null;
|
||||
mHueShader = null;
|
||||
mAlphaShader = null;
|
||||
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the color of the border surrounding all panels.
|
||||
*
|
||||
* @param color
|
||||
*/
|
||||
public void setBorderColor(final int color) {
|
||||
|
||||
mBorderColor = color;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the color the view should show.
|
||||
*
|
||||
* @param color The color that should be selected.
|
||||
*/
|
||||
public void setColor(final int color) {
|
||||
|
||||
setColor(color, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the color this view should show.
|
||||
*
|
||||
* @param color The color that should be selected.
|
||||
* @param callback If you want to get a callback to your
|
||||
* OnColorChangedListener.
|
||||
*/
|
||||
public void setColor(final int color, final boolean callback) {
|
||||
|
||||
final int alpha = Color.alpha(color);
|
||||
|
||||
final float[] hsv = new float[3];
|
||||
|
||||
Color.colorToHSV(color, hsv);
|
||||
|
||||
if (mShowAlphaPanel) {
|
||||
mAlpha = alpha;
|
||||
} else {
|
||||
mAlpha = 0xff;
|
||||
}
|
||||
mHue = hsv[0];
|
||||
mSat = hsv[1];
|
||||
mVal = hsv[2];
|
||||
|
||||
if (callback) {
|
||||
if (update) {
|
||||
if (mOnColorChangedListener != null) {
|
||||
final int color;
|
||||
if (mShowAlphaPanel) {
|
||||
color = Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal});
|
||||
} else {
|
||||
color = Color.HSVToColor(new float[]{mHue, mSat, mVal});
|
||||
}
|
||||
mOnColorChangedListener.onColorChanged(color);
|
||||
}
|
||||
invalidate();
|
||||
return true;
|
||||
}
|
||||
|
||||
invalidate();
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a OnColorChangedListener to get notified when the color selected by
|
||||
* the user has changed.
|
||||
*
|
||||
* @param listener
|
||||
*/
|
||||
public void setOnColorChangedListener(final OnColorChangedListener listener) {
|
||||
mOnColorChangedListener = listener;
|
||||
}
|
||||
@Override
|
||||
protected void onSizeChanged(final int w, final int h, final int oldw, final int oldh) {
|
||||
|
||||
public void setSliderTrackerColor(final int color) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
|
||||
mSliderTrackerColor = color;
|
||||
mDrawingRect = new RectF();
|
||||
mDrawingRect.left = mDrawingOffset + getPaddingLeft();
|
||||
mDrawingRect.right = w - mDrawingOffset - getPaddingRight();
|
||||
mDrawingRect.top = mDrawingOffset + getPaddingTop();
|
||||
mDrawingRect.bottom = h - mDrawingOffset - getPaddingBottom();
|
||||
|
||||
mHueTrackerPaint.setColor(mSliderTrackerColor);
|
||||
|
||||
invalidate();
|
||||
setUpSatValRect();
|
||||
setUpHueRect();
|
||||
setUpAlphaRect();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -483,20 +440,84 @@ public class ColorPickerView extends View {
|
|||
setMeasuredDimension(width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(final int w, final int h, final int oldw, final int oldh) {
|
||||
/**
|
||||
* Set the text that should be shown in the alpha slider. Set to null to
|
||||
* disable text.
|
||||
*
|
||||
* @param res string resource id.
|
||||
*/
|
||||
public void setAlphaSliderText(final int res) {
|
||||
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
final String text = getContext().getString(res);
|
||||
setAlphaSliderText(text);
|
||||
}
|
||||
|
||||
mDrawingRect = new RectF();
|
||||
mDrawingRect.left = mDrawingOffset + getPaddingLeft();
|
||||
mDrawingRect.right = w - mDrawingOffset - getPaddingRight();
|
||||
mDrawingRect.top = mDrawingOffset + getPaddingTop();
|
||||
mDrawingRect.bottom = h - mDrawingOffset - getPaddingBottom();
|
||||
/**
|
||||
* Set if the user is allowed to adjust the alpha panel. Default is false.
|
||||
* If it is set to false no alpha will be set.
|
||||
*
|
||||
* @param visible
|
||||
*/
|
||||
public void setAlphaSliderVisible(final boolean visible) {
|
||||
|
||||
setUpSatValRect();
|
||||
setUpHueRect();
|
||||
setUpAlphaRect();
|
||||
if (mShowAlphaPanel != visible) {
|
||||
mShowAlphaPanel = visible;
|
||||
|
||||
/*
|
||||
* Reset all shader to force a recreation. Otherwise they will not
|
||||
* look right after the size of the view has changed.
|
||||
*/
|
||||
mValShader = null;
|
||||
mSatShader = null;
|
||||
mHueShader = null;
|
||||
mAlphaShader = null;
|
||||
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the color this view should show.
|
||||
*
|
||||
* @param color The color that should be selected.
|
||||
* @param callback If you want to get a callback to your
|
||||
* OnColorChangedListener.
|
||||
*/
|
||||
public void setColor(final int color, final boolean callback) {
|
||||
|
||||
final int alpha = Color.alpha(color);
|
||||
|
||||
final float[] hsv = new float[3];
|
||||
|
||||
Color.colorToHSV(color, hsv);
|
||||
|
||||
if (mShowAlphaPanel) {
|
||||
mAlpha = alpha;
|
||||
} else {
|
||||
mAlpha = 0xff;
|
||||
}
|
||||
mHue = hsv[0];
|
||||
mSat = hsv[1];
|
||||
mVal = hsv[2];
|
||||
|
||||
if (callback) {
|
||||
if (mOnColorChangedListener != null) {
|
||||
mOnColorChangedListener.onColorChanged(color);
|
||||
}
|
||||
}
|
||||
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a OnColorChangedListener to get notified when the color selected by
|
||||
* the user has changed.
|
||||
*
|
||||
* @param listener
|
||||
*/
|
||||
public void setOnColorChangedListener(final OnColorChangedListener listener) {
|
||||
mOnColorChangedListener = listener;
|
||||
}
|
||||
|
||||
private Point alphaToPoint(final int alpha) {
|
||||
|
@ -897,51 +918,6 @@ public class ColorPickerView extends View {
|
|||
mSatValRect = new RectF(left, top, right, bottom);
|
||||
}
|
||||
|
||||
public static Bitmap getColorPreviewBitmap(final Context context, final int color, final boolean border) {
|
||||
if (context == null) return null;
|
||||
final float density = context.getResources().getDisplayMetrics().density;
|
||||
final int width = (int) (32 * density), height = (int) (32 * density);
|
||||
|
||||
final Bitmap bm = Bitmap.createBitmap(width, height, Config.ARGB_8888);
|
||||
final Canvas canvas = new Canvas(bm);
|
||||
|
||||
final int rectrangleSize = (int) (density * 5);
|
||||
final int numRectanglesHorizontal = (int) Math.ceil(width / rectrangleSize);
|
||||
final int numRectanglesVertical = (int) Math.ceil(height / rectrangleSize);
|
||||
final Rect r = new Rect();
|
||||
boolean verticalStartWhite = true;
|
||||
for (int i = 0; i <= numRectanglesVertical; i++) {
|
||||
|
||||
boolean isWhite = verticalStartWhite;
|
||||
for (int j = 0; j <= numRectanglesHorizontal; j++) {
|
||||
|
||||
r.top = i * rectrangleSize;
|
||||
r.left = j * rectrangleSize;
|
||||
r.bottom = r.top + rectrangleSize;
|
||||
r.right = r.left + rectrangleSize;
|
||||
final Paint paint = new Paint();
|
||||
paint.setColor(isWhite ? Color.WHITE : Color.GRAY);
|
||||
|
||||
canvas.drawRect(r, paint);
|
||||
|
||||
isWhite = !isWhite;
|
||||
}
|
||||
|
||||
verticalStartWhite = !verticalStartWhite;
|
||||
|
||||
}
|
||||
canvas.drawColor(color);
|
||||
if (border) {
|
||||
final Paint paint = new Paint();
|
||||
paint.setColor(Color.WHITE);
|
||||
paint.setStrokeWidth(1f * density);
|
||||
final float[] points = new float[]{0, 0, width, 0, 0, 0, 0, height, width, 0, width, height, 0, height,
|
||||
width, height};
|
||||
canvas.drawLines(points, paint);
|
||||
}
|
||||
return bm;
|
||||
}
|
||||
|
||||
public interface OnColorChangedListener {
|
||||
|
||||
public void onColorChanged(int color);
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
package org.mariotaku.twidere.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.widget.FrameLayout;
|
||||
|
@ -28,64 +30,78 @@ import org.mariotaku.twidere.view.iface.IExtendedView;
|
|||
|
||||
public class ExtendedFrameLayout extends FrameLayout implements IExtendedView {
|
||||
|
||||
private TouchInterceptor mTouchInterceptor;
|
||||
private OnSizeChangedListener mOnSizeChangedListener;
|
||||
private TouchInterceptor mTouchInterceptor;
|
||||
private OnSizeChangedListener mOnSizeChangedListener;
|
||||
private OnFitSystemWindowsListener mOnFitSystemWindowsListener;
|
||||
|
||||
public ExtendedFrameLayout(final Context context) {
|
||||
super(context);
|
||||
}
|
||||
public ExtendedFrameLayout(final Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public ExtendedFrameLayout(final Context context, final AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
public ExtendedFrameLayout(final Context context, final AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public ExtendedFrameLayout(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
public ExtendedFrameLayout(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean dispatchTouchEvent(final MotionEvent event) {
|
||||
if (mTouchInterceptor != null) {
|
||||
final boolean ret = mTouchInterceptor.dispatchTouchEvent(this, event);
|
||||
if (ret) return true;
|
||||
}
|
||||
return super.dispatchTouchEvent(event);
|
||||
}
|
||||
@Override
|
||||
public final boolean dispatchTouchEvent(final MotionEvent event) {
|
||||
if (mTouchInterceptor != null) {
|
||||
final boolean ret = mTouchInterceptor.dispatchTouchEvent(this, event);
|
||||
if (ret) return true;
|
||||
}
|
||||
return super.dispatchTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean onInterceptTouchEvent(final MotionEvent event) {
|
||||
if (mTouchInterceptor != null) {
|
||||
final boolean ret = mTouchInterceptor.onInterceptTouchEvent(this, event);
|
||||
if (ret) return true;
|
||||
}
|
||||
return super.onInterceptTouchEvent(event);
|
||||
}
|
||||
@Override
|
||||
public final boolean onInterceptTouchEvent(final MotionEvent event) {
|
||||
if (mTouchInterceptor != null) {
|
||||
final boolean ret = mTouchInterceptor.onInterceptTouchEvent(this, event);
|
||||
if (ret) return true;
|
||||
}
|
||||
return super.onInterceptTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean onTouchEvent(final MotionEvent event) {
|
||||
if (mTouchInterceptor != null) {
|
||||
final boolean ret = mTouchInterceptor.onTouchEvent(this, event);
|
||||
if (ret) return true;
|
||||
}
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
@Override
|
||||
public void setOnFitSystemWindowsListener(OnFitSystemWindowsListener listener) {
|
||||
mOnFitSystemWindowsListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setOnSizeChangedListener(final OnSizeChangedListener listener) {
|
||||
mOnSizeChangedListener = listener;
|
||||
}
|
||||
@Override
|
||||
public final void setOnSizeChangedListener(final OnSizeChangedListener listener) {
|
||||
mOnSizeChangedListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setTouchInterceptor(final TouchInterceptor listener) {
|
||||
mTouchInterceptor = listener;
|
||||
}
|
||||
@Override
|
||||
public final void setTouchInterceptor(final TouchInterceptor listener) {
|
||||
mTouchInterceptor = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void onSizeChanged(final int w, final int h, final int oldw, final int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
if (mOnSizeChangedListener != null) {
|
||||
mOnSizeChangedListener.onSizeChanged(this, w, h, oldw, oldh);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected boolean fitSystemWindows(@NonNull Rect insets) {
|
||||
if (mOnFitSystemWindowsListener != null) {
|
||||
mOnFitSystemWindowsListener.onFitSystemWindows(insets);
|
||||
}
|
||||
return super.fitSystemWindows(insets);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean onTouchEvent(final MotionEvent event) {
|
||||
if (mTouchInterceptor != null) {
|
||||
final boolean ret = mTouchInterceptor.onTouchEvent(this, event);
|
||||
if (ret) return true;
|
||||
}
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void onSizeChanged(final int w, final int h, final int oldw, final int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
if (mOnSizeChangedListener != null) {
|
||||
mOnSizeChangedListener.onSizeChanged(this, w, h, oldw, oldh);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
package org.mariotaku.twidere.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.widget.ImageView;
|
||||
|
@ -28,55 +30,69 @@ import org.mariotaku.twidere.view.iface.IExtendedView;
|
|||
|
||||
public class ExtendedImageView extends ImageView implements IExtendedView {
|
||||
|
||||
private OnSizeChangedListener mOnSizeChangedListener;
|
||||
private TouchInterceptor mTouchInterceptor;
|
||||
private OnSizeChangedListener mOnSizeChangedListener;
|
||||
private TouchInterceptor mTouchInterceptor;
|
||||
private OnFitSystemWindowsListener mOnFitSystemWindowsListener;
|
||||
|
||||
public ExtendedImageView(final Context context) {
|
||||
super(context);
|
||||
}
|
||||
public ExtendedImageView(final Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public ExtendedImageView(final Context context, final AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
public ExtendedImageView(final Context context, final AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public ExtendedImageView(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
public ExtendedImageView(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean dispatchTouchEvent(final MotionEvent event) {
|
||||
if (mTouchInterceptor != null) {
|
||||
final boolean ret = mTouchInterceptor.dispatchTouchEvent(this, event);
|
||||
if (ret) return true;
|
||||
}
|
||||
return super.dispatchTouchEvent(event);
|
||||
}
|
||||
@Override
|
||||
public void setOnFitSystemWindowsListener(OnFitSystemWindowsListener listener) {
|
||||
mOnFitSystemWindowsListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean onTouchEvent(final MotionEvent event) {
|
||||
if (mTouchInterceptor != null) {
|
||||
final boolean ret = mTouchInterceptor.onTouchEvent(this, event);
|
||||
if (ret) return true;
|
||||
}
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
@Override
|
||||
public final void setOnSizeChangedListener(final OnSizeChangedListener listener) {
|
||||
mOnSizeChangedListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setOnSizeChangedListener(final OnSizeChangedListener listener) {
|
||||
mOnSizeChangedListener = listener;
|
||||
}
|
||||
@Override
|
||||
public final void setTouchInterceptor(final TouchInterceptor listener) {
|
||||
mTouchInterceptor = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setTouchInterceptor(final TouchInterceptor listener) {
|
||||
mTouchInterceptor = listener;
|
||||
}
|
||||
@Override
|
||||
protected boolean fitSystemWindows(@NonNull Rect insets) {
|
||||
if (mOnFitSystemWindowsListener != null) {
|
||||
mOnFitSystemWindowsListener.onFitSystemWindows(insets);
|
||||
}
|
||||
return super.fitSystemWindows(insets);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void onSizeChanged(final int w, final int h, final int oldw, final int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
if (mOnSizeChangedListener != null) {
|
||||
mOnSizeChangedListener.onSizeChanged(this, w, h, oldw, oldh);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public final boolean dispatchTouchEvent(final MotionEvent event) {
|
||||
if (mTouchInterceptor != null) {
|
||||
final boolean ret = mTouchInterceptor.dispatchTouchEvent(this, event);
|
||||
if (ret) return true;
|
||||
}
|
||||
return super.dispatchTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean onTouchEvent(final MotionEvent event) {
|
||||
if (mTouchInterceptor != null) {
|
||||
final boolean ret = mTouchInterceptor.onTouchEvent(this, event);
|
||||
if (ret) return true;
|
||||
}
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void onSizeChanged(final int w, final int h, final int oldw, final int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
if (mOnSizeChangedListener != null) {
|
||||
mOnSizeChangedListener.onSizeChanged(this, w, h, oldw, oldh);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
package org.mariotaku.twidere.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.widget.LinearLayout;
|
||||
|
@ -28,65 +30,78 @@ import org.mariotaku.twidere.view.iface.IExtendedView;
|
|||
|
||||
public class ExtendedLinearLayout extends LinearLayout implements IExtendedView {
|
||||
|
||||
private TouchInterceptor mTouchInterceptor;
|
||||
private OnSizeChangedListener mOnSizeChangedListener;
|
||||
private TouchInterceptor mTouchInterceptor;
|
||||
private OnSizeChangedListener mOnSizeChangedListener;
|
||||
private OnFitSystemWindowsListener mOnFitSystemWindowsListener;
|
||||
|
||||
public ExtendedLinearLayout(final Context context) {
|
||||
super(context);
|
||||
}
|
||||
public ExtendedLinearLayout(final Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public ExtendedLinearLayout(final Context context, final AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
public ExtendedLinearLayout(final Context context, final AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public ExtendedLinearLayout(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
// Workaround for pre-Honeycomb devices.
|
||||
super(context, attrs);
|
||||
}
|
||||
public ExtendedLinearLayout(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean dispatchTouchEvent(final MotionEvent event) {
|
||||
if (mTouchInterceptor != null) {
|
||||
final boolean ret = mTouchInterceptor.dispatchTouchEvent(this, event);
|
||||
if (ret) return true;
|
||||
}
|
||||
return super.dispatchTouchEvent(event);
|
||||
}
|
||||
@Override
|
||||
public final boolean dispatchTouchEvent(final MotionEvent event) {
|
||||
if (mTouchInterceptor != null) {
|
||||
final boolean ret = mTouchInterceptor.dispatchTouchEvent(this, event);
|
||||
if (ret) return true;
|
||||
}
|
||||
return super.dispatchTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean onInterceptTouchEvent(final MotionEvent event) {
|
||||
if (mTouchInterceptor != null) {
|
||||
final boolean ret = mTouchInterceptor.onInterceptTouchEvent(this, event);
|
||||
if (ret) return true;
|
||||
}
|
||||
return super.onInterceptTouchEvent(event);
|
||||
}
|
||||
@Override
|
||||
public final boolean onInterceptTouchEvent(final MotionEvent event) {
|
||||
if (mTouchInterceptor != null) {
|
||||
final boolean ret = mTouchInterceptor.onInterceptTouchEvent(this, event);
|
||||
if (ret) return true;
|
||||
}
|
||||
return super.onInterceptTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean onTouchEvent(final MotionEvent event) {
|
||||
if (mTouchInterceptor != null) {
|
||||
final boolean ret = mTouchInterceptor.onTouchEvent(this, event);
|
||||
if (ret) return true;
|
||||
}
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
@Override
|
||||
public void setOnFitSystemWindowsListener(OnFitSystemWindowsListener listener) {
|
||||
mOnFitSystemWindowsListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setOnSizeChangedListener(final OnSizeChangedListener listener) {
|
||||
mOnSizeChangedListener = listener;
|
||||
}
|
||||
@Override
|
||||
public final void setOnSizeChangedListener(final OnSizeChangedListener listener) {
|
||||
mOnSizeChangedListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setTouchInterceptor(final TouchInterceptor listener) {
|
||||
mTouchInterceptor = listener;
|
||||
}
|
||||
@Override
|
||||
public final void setTouchInterceptor(final TouchInterceptor listener) {
|
||||
mTouchInterceptor = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void onSizeChanged(final int w, final int h, final int oldw, final int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
if (mOnSizeChangedListener != null) {
|
||||
mOnSizeChangedListener.onSizeChanged(this, w, h, oldw, oldh);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected boolean fitSystemWindows(@NonNull Rect insets) {
|
||||
if (mOnFitSystemWindowsListener != null) {
|
||||
mOnFitSystemWindowsListener.onFitSystemWindows(insets);
|
||||
}
|
||||
return super.fitSystemWindows(insets);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean onTouchEvent(@NonNull final MotionEvent event) {
|
||||
if (mTouchInterceptor != null) {
|
||||
final boolean ret = mTouchInterceptor.onTouchEvent(this, event);
|
||||
if (ret) return true;
|
||||
}
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void onSizeChanged(final int w, final int h, final int oldw, final int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
if (mOnSizeChangedListener != null) {
|
||||
mOnSizeChangedListener.onSizeChanged(this, w, h, oldw, oldh);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
package org.mariotaku.twidere.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.widget.RelativeLayout;
|
||||
|
@ -28,64 +30,78 @@ import org.mariotaku.twidere.view.iface.IExtendedView;
|
|||
|
||||
public class ExtendedRelativeLayout extends RelativeLayout implements IExtendedView {
|
||||
|
||||
private TouchInterceptor mTouchInterceptor;
|
||||
private OnSizeChangedListener mOnSizeChangedListener;
|
||||
private TouchInterceptor mTouchInterceptor;
|
||||
private OnSizeChangedListener mOnSizeChangedListener;
|
||||
private OnFitSystemWindowsListener mOnFitSystemWindowsListener;
|
||||
|
||||
public ExtendedRelativeLayout(final Context context) {
|
||||
super(context);
|
||||
}
|
||||
public ExtendedRelativeLayout(final Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public ExtendedRelativeLayout(final Context context, final AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
public ExtendedRelativeLayout(final Context context, final AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public ExtendedRelativeLayout(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
public ExtendedRelativeLayout(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean dispatchTouchEvent(final MotionEvent event) {
|
||||
if (mTouchInterceptor != null) {
|
||||
final boolean ret = mTouchInterceptor.dispatchTouchEvent(this, event);
|
||||
if (ret) return true;
|
||||
}
|
||||
return super.dispatchTouchEvent(event);
|
||||
}
|
||||
@Override
|
||||
public final boolean dispatchTouchEvent(final MotionEvent event) {
|
||||
if (mTouchInterceptor != null) {
|
||||
final boolean ret = mTouchInterceptor.dispatchTouchEvent(this, event);
|
||||
if (ret) return true;
|
||||
}
|
||||
return super.dispatchTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean onInterceptTouchEvent(final MotionEvent event) {
|
||||
if (mTouchInterceptor != null) {
|
||||
final boolean ret = mTouchInterceptor.onInterceptTouchEvent(this, event);
|
||||
if (ret) return true;
|
||||
}
|
||||
return super.onInterceptTouchEvent(event);
|
||||
}
|
||||
@Override
|
||||
public final boolean onInterceptTouchEvent(final MotionEvent event) {
|
||||
if (mTouchInterceptor != null) {
|
||||
final boolean ret = mTouchInterceptor.onInterceptTouchEvent(this, event);
|
||||
if (ret) return true;
|
||||
}
|
||||
return super.onInterceptTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean onTouchEvent(final MotionEvent event) {
|
||||
if (mTouchInterceptor != null) {
|
||||
final boolean ret = mTouchInterceptor.onTouchEvent(this, event);
|
||||
if (ret) return true;
|
||||
}
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
@Override
|
||||
public void setOnFitSystemWindowsListener(OnFitSystemWindowsListener listener) {
|
||||
mOnFitSystemWindowsListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setOnSizeChangedListener(final OnSizeChangedListener listener) {
|
||||
mOnSizeChangedListener = listener;
|
||||
}
|
||||
@Override
|
||||
public final void setOnSizeChangedListener(final OnSizeChangedListener listener) {
|
||||
mOnSizeChangedListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setTouchInterceptor(final TouchInterceptor listener) {
|
||||
mTouchInterceptor = listener;
|
||||
}
|
||||
@Override
|
||||
public final void setTouchInterceptor(final TouchInterceptor listener) {
|
||||
mTouchInterceptor = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void onSizeChanged(final int w, final int h, final int oldw, final int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
if (mOnSizeChangedListener != null) {
|
||||
mOnSizeChangedListener.onSizeChanged(this, w, h, oldw, oldh);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected boolean fitSystemWindows(@NonNull Rect insets) {
|
||||
if (mOnFitSystemWindowsListener != null) {
|
||||
mOnFitSystemWindowsListener.onFitSystemWindows(insets);
|
||||
}
|
||||
return super.fitSystemWindows(insets);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean onTouchEvent(final MotionEvent event) {
|
||||
if (mTouchInterceptor != null) {
|
||||
final boolean ret = mTouchInterceptor.onTouchEvent(this, event);
|
||||
if (ret) return true;
|
||||
}
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void onSizeChanged(final int w, final int h, final int oldw, final int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
if (mOnSizeChangedListener != null) {
|
||||
mOnSizeChangedListener.onSizeChanged(this, w, h, oldw, oldh);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -41,15 +41,15 @@ public class ExtendedViewPager extends ViewPager {
|
|||
return super.onInterceptTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean fitSystemWindows(Rect insets) {
|
||||
return super.fitSystemWindows(insets);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(final MotionEvent event) {
|
||||
if (!isEnabled()) return false;
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean fitSystemWindows(Rect insets) {
|
||||
return super.fitSystemWindows(insets);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -39,14 +39,10 @@ public class ForegroundColorView extends View implements IForegroundView {
|
|||
|
||||
private final Rect mAlphaRect, mColorRect;
|
||||
private final Paint mPaint;
|
||||
|
||||
private boolean mAlphaPattern;
|
||||
|
||||
private int mNumRectanglesHorizontal;
|
||||
|
||||
private int mNumRectanglesVertical;
|
||||
|
||||
private final int mAlphaPatternSize;
|
||||
private boolean mAlphaPattern;
|
||||
private int mNumRectanglesHorizontal;
|
||||
private int mNumRectanglesVertical;
|
||||
|
||||
public ForegroundColorView(final Context context) {
|
||||
this(context, null);
|
||||
|
@ -72,33 +68,14 @@ public class ForegroundColorView extends View implements IForegroundView {
|
|||
return mPaint.getColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable getForeground() {
|
||||
return mForegroundViewHelper.getForeground();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jumpDrawablesToCurrentState() {
|
||||
super.jumpDrawablesToCurrentState();
|
||||
mForegroundViewHelper.jumpDrawablesToCurrentState();
|
||||
}
|
||||
|
||||
public void setAlphaPatternEnable(final boolean alphaPattern) {
|
||||
if (mAlphaPattern == alphaPattern) return;
|
||||
mAlphaPattern = alphaPattern;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setColor(final int color) {
|
||||
mPaint.setColor(color);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
@Override
|
||||
public void drawableHotspotChanged(float x, float y) {
|
||||
super.drawableHotspotChanged(x, y);
|
||||
mForegroundViewHelper.dispatchDrawableHotspotChanged(x, y);
|
||||
public Drawable getForeground() {
|
||||
return mForegroundViewHelper.getForeground();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -126,10 +103,19 @@ public class ForegroundColorView extends View implements IForegroundView {
|
|||
mForegroundViewHelper.setForegroundGravity(foregroundGravity);
|
||||
}
|
||||
|
||||
public void setAlphaPatternEnable(final boolean alphaPattern) {
|
||||
if (mAlphaPattern == alphaPattern) return;
|
||||
mAlphaPattern = alphaPattern;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawableStateChanged() {
|
||||
super.drawableStateChanged();
|
||||
mForegroundViewHelper.drawableStateChanged();
|
||||
protected void onSizeChanged(final int w, final int h, final int oldw, final int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
mForegroundViewHelper.dispatchOnSizeChanged(w, h, oldw, oldh);
|
||||
mColorRect.set(getPaddingLeft(), getPaddingTop(), w - getPaddingRight(), h - getPaddingBottom());
|
||||
mNumRectanglesHorizontal = (int) Math.ceil(w / mAlphaPatternSize);
|
||||
mNumRectanglesVertical = (int) Math.ceil(h / mAlphaPatternSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -146,17 +132,27 @@ public class ForegroundColorView extends View implements IForegroundView {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(final int w, final int h, final int oldw, final int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
mForegroundViewHelper.dispatchOnSizeChanged(w, h, oldw, oldh);
|
||||
mColorRect.set(getPaddingLeft(), getPaddingTop(), w - getPaddingRight(), h - getPaddingBottom());
|
||||
mNumRectanglesHorizontal = (int) Math.ceil(w / mAlphaPatternSize);
|
||||
mNumRectanglesVertical = (int) Math.ceil(h / mAlphaPatternSize);
|
||||
protected boolean verifyDrawable(final Drawable who) {
|
||||
return super.verifyDrawable(who) || mForegroundViewHelper.verifyDrawable(who);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean verifyDrawable(final Drawable who) {
|
||||
return super.verifyDrawable(who) || mForegroundViewHelper.verifyDrawable(who);
|
||||
protected void drawableStateChanged() {
|
||||
super.drawableStateChanged();
|
||||
mForegroundViewHelper.drawableStateChanged();
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
@Override
|
||||
public void drawableHotspotChanged(float x, float y) {
|
||||
super.drawableHotspotChanged(x, y);
|
||||
mForegroundViewHelper.dispatchDrawableHotspotChanged(x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jumpDrawablesToCurrentState() {
|
||||
super.jumpDrawablesToCurrentState();
|
||||
mForegroundViewHelper.jumpDrawablesToCurrentState();
|
||||
}
|
||||
|
||||
private void drawAlphaPattern(final Canvas canvas) {
|
||||
|
|
|
@ -51,19 +51,6 @@ public class ForegroundImageView extends ImageView implements IForegroundView {
|
|||
return mForegroundViewHelper.getForeground();
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
@Override
|
||||
public void drawableHotspotChanged(float x, float y) {
|
||||
super.drawableHotspotChanged(x, y);
|
||||
mForegroundViewHelper.dispatchDrawableHotspotChanged(x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jumpDrawablesToCurrentState() {
|
||||
super.jumpDrawablesToCurrentState();
|
||||
mForegroundViewHelper.jumpDrawablesToCurrentState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Supply a Drawable that is to be rendered on top of all of the child views
|
||||
* in the frame layout. Any padding in the Drawable will be taken into
|
||||
|
@ -90,15 +77,9 @@ public class ForegroundImageView extends ImageView implements IForegroundView {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void drawableStateChanged() {
|
||||
super.drawableStateChanged();
|
||||
mForegroundViewHelper.drawableStateChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(final Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
mForegroundViewHelper.dispatchOnDraw(canvas);
|
||||
protected void onSizeChanged(final int w, final int h, final int oldw, final int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
mForegroundViewHelper.dispatchOnSizeChanged(w, h, oldw, oldh);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -107,15 +88,34 @@ public class ForegroundImageView extends ImageView implements IForegroundView {
|
|||
super.onLayout(changed, left, top, right, bottom);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(final int w, final int h, final int oldw, final int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
mForegroundViewHelper.dispatchOnSizeChanged(w, h, oldw, oldh);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean verifyDrawable(final Drawable who) {
|
||||
return super.verifyDrawable(who) || mForegroundViewHelper.verifyDrawable(who);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jumpDrawablesToCurrentState() {
|
||||
super.jumpDrawablesToCurrentState();
|
||||
mForegroundViewHelper.jumpDrawablesToCurrentState();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawableStateChanged() {
|
||||
super.drawableStateChanged();
|
||||
mForegroundViewHelper.drawableStateChanged();
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
@Override
|
||||
public void drawableHotspotChanged(float x, float y) {
|
||||
super.drawableHotspotChanged(x, y);
|
||||
mForegroundViewHelper.dispatchDrawableHotspotChanged(x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(final Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
mForegroundViewHelper.dispatchOnDraw(canvas);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -150,7 +150,9 @@ public class HeaderDrawerLayout extends ViewGroup {
|
|||
return mContainer.getHeader();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeaderTop() {
|
||||
return mContainer.getTop();
|
||||
} @Override
|
||||
public void computeScroll() {
|
||||
boolean invalidate = mDragHelper.continueSettling(true);
|
||||
if (!mTouchDown && mScroller.computeScrollOffset()) {
|
||||
|
@ -165,10 +167,6 @@ public class HeaderDrawerLayout extends ViewGroup {
|
|||
}
|
||||
}
|
||||
|
||||
public int getHeaderTop() {
|
||||
return mContainer.getTop();
|
||||
}
|
||||
|
||||
public int getHeaderTopMaximum() {
|
||||
return mContainer.getHeaderTopMaximum();
|
||||
}
|
||||
|
@ -183,19 +181,17 @@ public class HeaderDrawerLayout extends ViewGroup {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
if (getChildCount() != 1) {
|
||||
throw new IllegalArgumentException("Add subview by XML is not allowed.");
|
||||
}
|
||||
}
|
||||
|
||||
public void setDrawerCallback(DrawerCallback callback) {
|
||||
mDrawerCallback = callback;
|
||||
}
|
||||
|
||||
private boolean canScrollCallback(float dy) {
|
||||
return mDrawerCallback.canScroll(dy);
|
||||
} @Override
|
||||
protected void onFinishInflate() {
|
||||
if (getChildCount() != 1) {
|
||||
throw new IllegalArgumentException("Add subview by XML is not allowed.");
|
||||
}
|
||||
}
|
||||
|
||||
private void cancelTouchCallback() {
|
||||
|
@ -253,17 +249,6 @@ public class HeaderDrawerLayout extends ViewGroup {
|
|||
mDrawerCallback.topChanged(top);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
final View child = getChildAt(0);
|
||||
|
||||
final int childWidthMeasureSpec = makeChildMeasureSpec(widthMeasureSpec, getPaddingLeft() + getPaddingRight());
|
||||
final int childHeightMeasureSpec = makeChildMeasureSpec(heightMeasureSpec, getPaddingTop() + getPaddingBottom());
|
||||
|
||||
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
|
||||
private void offsetHeaderBy(int dy) {
|
||||
final int prevTop = mContainer.getTop();
|
||||
final int clampedDy = MathUtils.clamp(prevTop + dy, getHeaderTopMinimum(), getHeaderTopMaximum()) - prevTop;
|
||||
|
@ -278,6 +263,15 @@ public class HeaderDrawerLayout extends ViewGroup {
|
|||
|
||||
private void setScrollingHeaderByGesture(boolean scrolling) {
|
||||
mScrollingHeaderByGesture = scrolling;
|
||||
} @Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
final View child = getChildAt(0);
|
||||
|
||||
final int childWidthMeasureSpec = makeChildMeasureSpec(widthMeasureSpec, getPaddingLeft() + getPaddingRight());
|
||||
final int childHeightMeasureSpec = makeChildMeasureSpec(heightMeasureSpec, getPaddingTop() + getPaddingBottom());
|
||||
|
||||
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
|
||||
private boolean shouldLayoutHeaderBottomCallback() {
|
||||
|
@ -549,4 +543,10 @@ public class HeaderDrawerLayout extends ViewGroup {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -26,18 +26,18 @@ import org.mariotaku.twidere.util.ThemeUtils;
|
|||
|
||||
public class HighlightImageView extends ForegroundImageView {
|
||||
|
||||
public HighlightImageView(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
public HighlightImageView(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public HighlightImageView(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
public HighlightImageView(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public HighlightImageView(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
if (isInEditMode()) return;
|
||||
setForeground(ThemeUtils.getImageHighlightDrawable(context));
|
||||
}
|
||||
public HighlightImageView(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
if (isInEditMode()) return;
|
||||
setForeground(ThemeUtils.getImageHighlightDrawable(context));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -73,12 +73,6 @@ public class HomeActionButton extends FrameLayout implements IHomeActionButton {
|
|||
ViewAccessor.setBackground(this, new ColorDrawable(color));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIconColor(int color, Mode mode) {
|
||||
mIconView.setColorFilter(color, mode);
|
||||
mProgressBar.setIndeterminateTintList(ColorStateList.valueOf(color));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIcon(final Bitmap bm) {
|
||||
mIconView.setImageBitmap(bm);
|
||||
|
@ -94,6 +88,12 @@ public class HomeActionButton extends FrameLayout implements IHomeActionButton {
|
|||
mIconView.setImageResource(resId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIconColor(int color, Mode mode) {
|
||||
mIconView.setColorFilter(color, mode);
|
||||
mProgressBar.setIndeterminateTintList(ColorStateList.valueOf(color));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setShowProgress(final boolean showProgress) {
|
||||
mProgressBar.setVisibility(showProgress ? View.VISIBLE : View.GONE);
|
||||
|
|
|
@ -83,6 +83,36 @@ public class HomeActionButtonCompat extends FrameLayout implements IHomeActionBu
|
|||
|
||||
}
|
||||
|
||||
public void setIcon(final Bitmap bm) {
|
||||
mIconView.setImageBitmap(bm);
|
||||
}
|
||||
|
||||
public void setIcon(final Drawable drawable) {
|
||||
mIconView.setImageDrawable(drawable);
|
||||
}
|
||||
|
||||
public void setIcon(final int resId) {
|
||||
mIconView.setImageResource(resId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIconColor(int color, Mode mode) {
|
||||
mIconView.setColorFilter(color, mode);
|
||||
}
|
||||
|
||||
public void setShowProgress(final boolean showProgress) {
|
||||
mProgressBar.setVisibility(showProgress ? View.VISIBLE : View.GONE);
|
||||
mIconView.setVisibility(showProgress ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
|
||||
public void setTitle(final CharSequence title) {
|
||||
setContentDescription(title);
|
||||
}
|
||||
|
||||
public void setTitle(final int title) {
|
||||
setTitle(getResources().getText(title));
|
||||
}
|
||||
|
||||
private static class FloatingActionDrawable extends Drawable {
|
||||
|
||||
|
||||
|
@ -95,13 +125,6 @@ public class HomeActionButtonCompat extends FrameLayout implements IHomeActionBu
|
|||
private Paint mColorPaint;
|
||||
private Rect mBounds;
|
||||
|
||||
@Override
|
||||
protected void onBoundsChange(Rect bounds) {
|
||||
super.onBoundsChange(bounds);
|
||||
mBounds.set(bounds);
|
||||
updateBitmap();
|
||||
}
|
||||
|
||||
public FloatingActionDrawable(View view, float radius) {
|
||||
mView = view;
|
||||
mRadius = radius;
|
||||
|
@ -109,11 +132,6 @@ public class HomeActionButtonCompat extends FrameLayout implements IHomeActionBu
|
|||
mBounds = new Rect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicHeight() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
if (mBitmap != null) {
|
||||
|
@ -127,24 +145,6 @@ public class HomeActionButtonCompat extends FrameLayout implements IHomeActionBu
|
|||
}
|
||||
}
|
||||
|
||||
private void updateBitmap() {
|
||||
final Rect bounds = mBounds;
|
||||
if (bounds.isEmpty()) return;
|
||||
mBitmap = Bitmap.createBitmap(bounds.width(), bounds.height(), Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(mBitmap);
|
||||
final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
paint.setColor(Color.WHITE);
|
||||
final float radius = mRadius;
|
||||
paint.setShadowLayer(radius, 0, radius * 1.5f / 2, SHADOW_START_COLOR);
|
||||
final RectF rect = new RectF(mView.getPaddingLeft(), mView.getPaddingTop(),
|
||||
bounds.width() - mView.getPaddingRight(), bounds.height() - mView.getPaddingBottom());
|
||||
canvas.drawOval(rect, paint);
|
||||
paint.setShadowLayer(0, 0, 0, 0);
|
||||
paint.setXfermode(new PorterDuffXfermode(Mode.CLEAR));
|
||||
canvas.drawOval(rect, paint);
|
||||
invalidateSelf();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
// No-op
|
||||
|
@ -161,45 +161,45 @@ public class HomeActionButtonCompat extends FrameLayout implements IHomeActionBu
|
|||
return PixelFormat.TRANSLUCENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBoundsChange(Rect bounds) {
|
||||
super.onBoundsChange(bounds);
|
||||
mBounds.set(bounds);
|
||||
updateBitmap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicWidth() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicHeight() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void setColor(int color) {
|
||||
mColorPaint.setColor(color);
|
||||
invalidateSelf();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIconColor(int color, Mode mode) {
|
||||
mIconView.setColorFilter(color, mode);
|
||||
}
|
||||
|
||||
public void setIcon(final Bitmap bm) {
|
||||
mIconView.setImageBitmap(bm);
|
||||
}
|
||||
|
||||
public void setIcon(final Drawable drawable) {
|
||||
mIconView.setImageDrawable(drawable);
|
||||
}
|
||||
|
||||
public void setIcon(final int resId) {
|
||||
mIconView.setImageResource(resId);
|
||||
}
|
||||
|
||||
public void setShowProgress(final boolean showProgress) {
|
||||
mProgressBar.setVisibility(showProgress ? View.VISIBLE : View.GONE);
|
||||
mIconView.setVisibility(showProgress ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
|
||||
public void setTitle(final CharSequence title) {
|
||||
setContentDescription(title);
|
||||
}
|
||||
|
||||
public void setTitle(final int title) {
|
||||
setTitle(getResources().getText(title));
|
||||
private void updateBitmap() {
|
||||
final Rect bounds = mBounds;
|
||||
if (bounds.isEmpty()) return;
|
||||
mBitmap = Bitmap.createBitmap(bounds.width(), bounds.height(), Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(mBitmap);
|
||||
final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
paint.setColor(Color.WHITE);
|
||||
final float radius = mRadius;
|
||||
paint.setShadowLayer(radius, 0, radius * 1.5f / 2, SHADOW_START_COLOR);
|
||||
final RectF rect = new RectF(mView.getPaddingLeft(), mView.getPaddingTop(),
|
||||
bounds.width() - mView.getPaddingRight(), bounds.height() - mView.getPaddingBottom());
|
||||
canvas.drawOval(rect, paint);
|
||||
paint.setShadowLayer(0, 0, 0, 0);
|
||||
paint.setXfermode(new PorterDuffXfermode(Mode.CLEAR));
|
||||
canvas.drawOval(rect, paint);
|
||||
invalidateSelf();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -47,18 +47,18 @@ public class HomeSlidingMenu extends SlidingMenu implements Constants {
|
|||
return super.dispatchTouchEvent(ev);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CustomViewBehind newCustomViewBehind(final Context context) {
|
||||
if (isInEditMode()) return super.newCustomViewBehind(context);
|
||||
return new MyCustomViewBehind(context, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean fitSystemWindows(Rect insets) {
|
||||
mActivity.setSystemWindowInsets(insets);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CustomViewBehind newCustomViewBehind(final Context context) {
|
||||
if (isInEditMode()) return super.newCustomViewBehind(context);
|
||||
return new MyCustomViewBehind(context, this);
|
||||
}
|
||||
|
||||
private ViewPager getViewPager() {
|
||||
if (mActivity == null) return null;
|
||||
return mActivity.getViewPager();
|
||||
|
|
|
@ -25,24 +25,24 @@ import android.widget.FrameLayout;
|
|||
|
||||
public class ImagePreviewContainer extends FrameLayout {
|
||||
|
||||
public ImagePreviewContainer(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
public ImagePreviewContainer(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public ImagePreviewContainer(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
public ImagePreviewContainer(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public ImagePreviewContainer(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
public ImagePreviewContainer(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||
final int width = MeasureSpec.getSize(widthMeasureSpec), height = width / 2;
|
||||
final int hSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
|
||||
super.onMeasure(widthMeasureSpec, hSpec);
|
||||
setMeasuredDimension(width, height);
|
||||
}
|
||||
@Override
|
||||
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||
final int width = MeasureSpec.getSize(widthMeasureSpec), height = width / 2;
|
||||
final int hSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
|
||||
super.onMeasure(widthMeasureSpec, hSpec);
|
||||
setMeasuredDimension(width, height);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -40,396 +40,393 @@ import org.mariotaku.twidere.view.iface.PagerIndicator;
|
|||
* the unselected page lines.
|
||||
*/
|
||||
public class LinePageIndicator extends View implements PagerIndicator {
|
||||
private static final int INVALID_POINTER = -1;
|
||||
private static final int INVALID_POINTER = -1;
|
||||
private int mActivePointerId = INVALID_POINTER;
|
||||
private final Paint mPaintUnselected = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private final Paint mPaintSelected = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private ViewPager mViewPager;
|
||||
private ViewPager.OnPageChangeListener mListener;
|
||||
private int mCurrentPage;
|
||||
private boolean mCentered;
|
||||
private float mLineWidth;
|
||||
private float mGapWidth;
|
||||
private int mTouchSlop;
|
||||
private float mLastMotionX = -1;
|
||||
private boolean mIsDragging;
|
||||
|
||||
private final Paint mPaintUnselected = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private final Paint mPaintSelected = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private ViewPager mViewPager;
|
||||
private ViewPager.OnPageChangeListener mListener;
|
||||
private int mCurrentPage;
|
||||
private boolean mCentered;
|
||||
private float mLineWidth;
|
||||
private float mGapWidth;
|
||||
public LinePageIndicator(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
private int mTouchSlop;
|
||||
private float mLastMotionX = -1;
|
||||
private int mActivePointerId = INVALID_POINTER;
|
||||
private boolean mIsDragging;
|
||||
public LinePageIndicator(final Context context, final AttributeSet attrs) {
|
||||
super(context, attrs, 0);
|
||||
if (isInEditMode()) return;
|
||||
|
||||
public LinePageIndicator(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
final Resources res = getResources();
|
||||
|
||||
public LinePageIndicator(final Context context, final AttributeSet attrs) {
|
||||
super(context, attrs, 0);
|
||||
if (isInEditMode()) return;
|
||||
// Load defaults from resources
|
||||
final int defaultSelectedColor = res.getColor(R.color.default_line_indicator_selected_color);
|
||||
final int defaultUnselectedColor = res.getColor(R.color.default_line_indicator_unselected_color);
|
||||
final float defaultLineWidth = res.getDimension(R.dimen.default_line_indicator_line_width);
|
||||
final float defaultGapWidth = res.getDimension(R.dimen.default_line_indicator_gap_width);
|
||||
final float defaultStrokeWidth = res.getDimension(R.dimen.default_line_indicator_stroke_width);
|
||||
final boolean defaultCentered = res.getBoolean(R.bool.default_line_indicator_centered);
|
||||
|
||||
final Resources res = getResources();
|
||||
// Retrieve styles attributes
|
||||
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LinePageIndicator, 0, 0);
|
||||
|
||||
// Load defaults from resources
|
||||
final int defaultSelectedColor = res.getColor(R.color.default_line_indicator_selected_color);
|
||||
final int defaultUnselectedColor = res.getColor(R.color.default_line_indicator_unselected_color);
|
||||
final float defaultLineWidth = res.getDimension(R.dimen.default_line_indicator_line_width);
|
||||
final float defaultGapWidth = res.getDimension(R.dimen.default_line_indicator_gap_width);
|
||||
final float defaultStrokeWidth = res.getDimension(R.dimen.default_line_indicator_stroke_width);
|
||||
final boolean defaultCentered = res.getBoolean(R.bool.default_line_indicator_centered);
|
||||
mCentered = a.getBoolean(R.styleable.LinePageIndicator_centered, defaultCentered);
|
||||
mLineWidth = a.getDimension(R.styleable.LinePageIndicator_lineWidth, defaultLineWidth);
|
||||
mGapWidth = a.getDimension(R.styleable.LinePageIndicator_gapWidth, defaultGapWidth);
|
||||
setStrokeWidth(a.getDimension(R.styleable.LinePageIndicator_strokeWidth, defaultStrokeWidth));
|
||||
mPaintUnselected.setColor(a.getColor(R.styleable.LinePageIndicator_unselectedColor, defaultUnselectedColor));
|
||||
mPaintSelected.setColor(a.getColor(R.styleable.LinePageIndicator_selectedColor, defaultSelectedColor));
|
||||
|
||||
// Retrieve styles attributes
|
||||
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LinePageIndicator, 0, 0);
|
||||
final Drawable background = a.getDrawable(R.styleable.LinePageIndicator_android_background);
|
||||
if (background != null) {
|
||||
ViewAccessor.setBackground(this, background);
|
||||
}
|
||||
|
||||
mCentered = a.getBoolean(R.styleable.LinePageIndicator_centered, defaultCentered);
|
||||
mLineWidth = a.getDimension(R.styleable.LinePageIndicator_lineWidth, defaultLineWidth);
|
||||
mGapWidth = a.getDimension(R.styleable.LinePageIndicator_gapWidth, defaultGapWidth);
|
||||
setStrokeWidth(a.getDimension(R.styleable.LinePageIndicator_strokeWidth, defaultStrokeWidth));
|
||||
mPaintUnselected.setColor(a.getColor(R.styleable.LinePageIndicator_unselectedColor, defaultUnselectedColor));
|
||||
mPaintSelected.setColor(a.getColor(R.styleable.LinePageIndicator_selectedColor, defaultSelectedColor));
|
||||
a.recycle();
|
||||
|
||||
final Drawable background = a.getDrawable(R.styleable.LinePageIndicator_android_background);
|
||||
if (background != null) {
|
||||
ViewAccessor.setBackground(this, background);
|
||||
}
|
||||
final ViewConfiguration configuration = ViewConfiguration.get(context);
|
||||
mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration);
|
||||
}
|
||||
|
||||
a.recycle();
|
||||
public float getGapWidth() {
|
||||
return mGapWidth;
|
||||
}
|
||||
|
||||
final ViewConfiguration configuration = ViewConfiguration.get(context);
|
||||
mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration);
|
||||
}
|
||||
public void setGapWidth(final float gapWidth) {
|
||||
mGapWidth = gapWidth;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public float getGapWidth() {
|
||||
return mGapWidth;
|
||||
}
|
||||
public float getLineWidth() {
|
||||
return mLineWidth;
|
||||
}
|
||||
|
||||
public float getLineWidth() {
|
||||
return mLineWidth;
|
||||
}
|
||||
public void setLineWidth(final float lineWidth) {
|
||||
mLineWidth = lineWidth;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public int getSelectedColor() {
|
||||
return mPaintSelected.getColor();
|
||||
}
|
||||
public int getSelectedColor() {
|
||||
return mPaintSelected.getColor();
|
||||
}
|
||||
|
||||
public float getStrokeWidth() {
|
||||
return mPaintSelected.getStrokeWidth();
|
||||
}
|
||||
public void setSelectedColor(final int selectedColor) {
|
||||
mPaintSelected.setColor(selectedColor);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public int getUnselectedColor() {
|
||||
return mPaintUnselected.getColor();
|
||||
}
|
||||
public float getStrokeWidth() {
|
||||
return mPaintSelected.getStrokeWidth();
|
||||
}
|
||||
|
||||
public boolean isCentered() {
|
||||
return mCentered;
|
||||
}
|
||||
public void setStrokeWidth(final float lineHeight) {
|
||||
mPaintSelected.setStrokeWidth(lineHeight);
|
||||
mPaintUnselected.setStrokeWidth(lineHeight);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyDataSetChanged() {
|
||||
invalidate();
|
||||
}
|
||||
public int getUnselectedColor() {
|
||||
return mPaintUnselected.getColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) {
|
||||
if (mListener != null) {
|
||||
mListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
|
||||
}
|
||||
}
|
||||
public void setUnselectedColor(final int unselectedColor) {
|
||||
mPaintUnselected.setColor(unselectedColor);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(final int state) {
|
||||
if (mListener != null) {
|
||||
mListener.onPageScrollStateChanged(state);
|
||||
}
|
||||
}
|
||||
public boolean isCentered() {
|
||||
return mCentered;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageSelected(final int position) {
|
||||
mCurrentPage = position;
|
||||
invalidate();
|
||||
public void setCentered(final boolean centered) {
|
||||
mCentered = centered;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
if (mListener != null) {
|
||||
mListener.onPageSelected(position);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void notifyDataSetChanged() {
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRestoreInstanceState(final Parcelable state) {
|
||||
final SavedState savedState = (SavedState) state;
|
||||
super.onRestoreInstanceState(savedState.getSuperState());
|
||||
mCurrentPage = savedState.currentPage;
|
||||
requestLayout();
|
||||
}
|
||||
@Override
|
||||
public void setCurrentItem(final int item) {
|
||||
if (mViewPager == null) throw new IllegalStateException("ViewPager has not been bound.");
|
||||
mViewPager.setCurrentItem(item);
|
||||
mCurrentPage = item;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Parcelable onSaveInstanceState() {
|
||||
final Parcelable superState = super.onSaveInstanceState();
|
||||
final SavedState savedState = new SavedState(superState);
|
||||
savedState.currentPage = mCurrentPage;
|
||||
return savedState;
|
||||
}
|
||||
@Override
|
||||
public void setOnPageChangeListener(final ViewPager.OnPageChangeListener listener) {
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(final android.view.MotionEvent ev) {
|
||||
if (super.onTouchEvent(ev)) return true;
|
||||
if (mViewPager == null || mViewPager.getAdapter().getCount() == 0) return false;
|
||||
@Override
|
||||
public void setViewPager(final ViewPager viewPager) {
|
||||
if (mViewPager == viewPager) return;
|
||||
if (mViewPager != null) {
|
||||
// Clear us from the old pager.
|
||||
mViewPager.setOnPageChangeListener(null);
|
||||
}
|
||||
if (viewPager.getAdapter() == null)
|
||||
throw new IllegalStateException("ViewPager does not have adapter instance.");
|
||||
mViewPager = viewPager;
|
||||
mViewPager.setOnPageChangeListener(this);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
final int action = ev.getAction() & MotionEventCompat.ACTION_MASK;
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
|
||||
mLastMotionX = ev.getX();
|
||||
break;
|
||||
@Override
|
||||
public void setViewPager(final ViewPager view, final int initialPosition) {
|
||||
setViewPager(view);
|
||||
setCurrentItem(initialPosition);
|
||||
}
|
||||
|
||||
case MotionEvent.ACTION_MOVE: {
|
||||
final int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
|
||||
final float x = MotionEventCompat.getX(ev, activePointerIndex);
|
||||
final float deltaX = x - mLastMotionX;
|
||||
@Override
|
||||
public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) {
|
||||
if (mListener != null) {
|
||||
mListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
|
||||
}
|
||||
}
|
||||
|
||||
if (!mIsDragging) {
|
||||
if (Math.abs(deltaX) > mTouchSlop) {
|
||||
mIsDragging = true;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onPageSelected(final int position) {
|
||||
mCurrentPage = position;
|
||||
invalidate();
|
||||
|
||||
if (mIsDragging) {
|
||||
mLastMotionX = x;
|
||||
if (mViewPager.isFakeDragging() || mViewPager.beginFakeDrag()) {
|
||||
mViewPager.fakeDragBy(deltaX);
|
||||
}
|
||||
}
|
||||
if (mListener != null) {
|
||||
mListener.onPageSelected(position);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
@Override
|
||||
public void onPageScrollStateChanged(final int state) {
|
||||
if (mListener != null) {
|
||||
mListener.onPageScrollStateChanged(state);
|
||||
}
|
||||
}
|
||||
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
case MotionEvent.ACTION_UP:
|
||||
if (!mIsDragging) {
|
||||
final int count = mViewPager.getAdapter().getCount();
|
||||
final int width = getWidth();
|
||||
final float halfWidth = width / 2f;
|
||||
final float sixthWidth = width / 6f;
|
||||
@Override
|
||||
public boolean onTouchEvent(final android.view.MotionEvent ev) {
|
||||
if (super.onTouchEvent(ev)) return true;
|
||||
if (mViewPager == null || mViewPager.getAdapter().getCount() == 0) return false;
|
||||
|
||||
if (mCurrentPage > 0 && ev.getX() < halfWidth - sixthWidth) {
|
||||
if (action != MotionEvent.ACTION_CANCEL) {
|
||||
mViewPager.setCurrentItem(mCurrentPage - 1);
|
||||
}
|
||||
return true;
|
||||
} else if (mCurrentPage < count - 1 && ev.getX() > halfWidth + sixthWidth) {
|
||||
if (action != MotionEvent.ACTION_CANCEL) {
|
||||
mViewPager.setCurrentItem(mCurrentPage + 1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
final int action = ev.getAction() & MotionEventCompat.ACTION_MASK;
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
|
||||
mLastMotionX = ev.getX();
|
||||
break;
|
||||
|
||||
mIsDragging = false;
|
||||
mActivePointerId = INVALID_POINTER;
|
||||
if (mViewPager.isFakeDragging()) {
|
||||
mViewPager.endFakeDrag();
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE: {
|
||||
final int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
|
||||
final float x = MotionEventCompat.getX(ev, activePointerIndex);
|
||||
final float deltaX = x - mLastMotionX;
|
||||
|
||||
case MotionEventCompat.ACTION_POINTER_DOWN: {
|
||||
final int index = MotionEventCompat.getActionIndex(ev);
|
||||
mLastMotionX = MotionEventCompat.getX(ev, index);
|
||||
mActivePointerId = MotionEventCompat.getPointerId(ev, index);
|
||||
break;
|
||||
}
|
||||
if (!mIsDragging) {
|
||||
if (Math.abs(deltaX) > mTouchSlop) {
|
||||
mIsDragging = true;
|
||||
}
|
||||
}
|
||||
|
||||
case MotionEventCompat.ACTION_POINTER_UP:
|
||||
final int pointerIndex = MotionEventCompat.getActionIndex(ev);
|
||||
final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex);
|
||||
if (pointerId == mActivePointerId) {
|
||||
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
|
||||
mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);
|
||||
}
|
||||
mLastMotionX = MotionEventCompat.getX(ev, MotionEventCompat.findPointerIndex(ev, mActivePointerId));
|
||||
break;
|
||||
}
|
||||
if (mIsDragging) {
|
||||
mLastMotionX = x;
|
||||
if (mViewPager.isFakeDragging() || mViewPager.beginFakeDrag()) {
|
||||
mViewPager.fakeDragBy(deltaX);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
public void setCentered(final boolean centered) {
|
||||
mCentered = centered;
|
||||
invalidate();
|
||||
}
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
case MotionEvent.ACTION_UP:
|
||||
if (!mIsDragging) {
|
||||
final int count = mViewPager.getAdapter().getCount();
|
||||
final int width = getWidth();
|
||||
final float halfWidth = width / 2f;
|
||||
final float sixthWidth = width / 6f;
|
||||
|
||||
@Override
|
||||
public void setCurrentItem(final int item) {
|
||||
if (mViewPager == null) throw new IllegalStateException("ViewPager has not been bound.");
|
||||
mViewPager.setCurrentItem(item);
|
||||
mCurrentPage = item;
|
||||
invalidate();
|
||||
}
|
||||
if (mCurrentPage > 0 && ev.getX() < halfWidth - sixthWidth) {
|
||||
if (action != MotionEvent.ACTION_CANCEL) {
|
||||
mViewPager.setCurrentItem(mCurrentPage - 1);
|
||||
}
|
||||
return true;
|
||||
} else if (mCurrentPage < count - 1 && ev.getX() > halfWidth + sixthWidth) {
|
||||
if (action != MotionEvent.ACTION_CANCEL) {
|
||||
mViewPager.setCurrentItem(mCurrentPage + 1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void setGapWidth(final float gapWidth) {
|
||||
mGapWidth = gapWidth;
|
||||
invalidate();
|
||||
}
|
||||
mIsDragging = false;
|
||||
mActivePointerId = INVALID_POINTER;
|
||||
if (mViewPager.isFakeDragging()) {
|
||||
mViewPager.endFakeDrag();
|
||||
}
|
||||
break;
|
||||
|
||||
public void setLineWidth(final float lineWidth) {
|
||||
mLineWidth = lineWidth;
|
||||
invalidate();
|
||||
}
|
||||
case MotionEventCompat.ACTION_POINTER_DOWN: {
|
||||
final int index = MotionEventCompat.getActionIndex(ev);
|
||||
mLastMotionX = MotionEventCompat.getX(ev, index);
|
||||
mActivePointerId = MotionEventCompat.getPointerId(ev, index);
|
||||
break;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnPageChangeListener(final ViewPager.OnPageChangeListener listener) {
|
||||
mListener = listener;
|
||||
}
|
||||
case MotionEventCompat.ACTION_POINTER_UP:
|
||||
final int pointerIndex = MotionEventCompat.getActionIndex(ev);
|
||||
final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex);
|
||||
if (pointerId == mActivePointerId) {
|
||||
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
|
||||
mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);
|
||||
}
|
||||
mLastMotionX = MotionEventCompat.getX(ev, MotionEventCompat.findPointerIndex(ev, mActivePointerId));
|
||||
break;
|
||||
}
|
||||
|
||||
public void setSelectedColor(final int selectedColor) {
|
||||
mPaintSelected.setColor(selectedColor);
|
||||
invalidate();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setStrokeWidth(final float lineHeight) {
|
||||
mPaintSelected.setStrokeWidth(lineHeight);
|
||||
mPaintUnselected.setStrokeWidth(lineHeight);
|
||||
invalidate();
|
||||
}
|
||||
@Override
|
||||
protected void onDraw(final Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
|
||||
public void setUnselectedColor(final int unselectedColor) {
|
||||
mPaintUnselected.setColor(unselectedColor);
|
||||
invalidate();
|
||||
}
|
||||
if (mViewPager == null) return;
|
||||
final int count = mViewPager.getAdapter().getCount();
|
||||
if (count == 0) return;
|
||||
|
||||
@Override
|
||||
public void setViewPager(final ViewPager viewPager) {
|
||||
if (mViewPager == viewPager) return;
|
||||
if (mViewPager != null) {
|
||||
// Clear us from the old pager.
|
||||
mViewPager.setOnPageChangeListener(null);
|
||||
}
|
||||
if (viewPager.getAdapter() == null)
|
||||
throw new IllegalStateException("ViewPager does not have adapter instance.");
|
||||
mViewPager = viewPager;
|
||||
mViewPager.setOnPageChangeListener(this);
|
||||
invalidate();
|
||||
}
|
||||
if (mCurrentPage >= count) {
|
||||
setCurrentItem(count - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setViewPager(final ViewPager view, final int initialPosition) {
|
||||
setViewPager(view);
|
||||
setCurrentItem(initialPosition);
|
||||
}
|
||||
final float lineWidthAndGap = mLineWidth + mGapWidth;
|
||||
final float indicatorWidth = count * lineWidthAndGap - mGapWidth;
|
||||
final float paddingTop = getPaddingTop();
|
||||
final float paddingLeft = getPaddingLeft();
|
||||
final float paddingRight = getPaddingRight();
|
||||
|
||||
@Override
|
||||
protected void onDraw(final Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
final float verticalOffset = paddingTop + (getHeight() - paddingTop - getPaddingBottom()) / 2.0f;
|
||||
float horizontalOffset = paddingLeft;
|
||||
if (mCentered) {
|
||||
horizontalOffset += (getWidth() - paddingLeft - paddingRight) / 2.0f - indicatorWidth / 2.0f;
|
||||
}
|
||||
|
||||
if (mViewPager == null) return;
|
||||
final int count = mViewPager.getAdapter().getCount();
|
||||
if (count == 0) return;
|
||||
// Draw stroked circles
|
||||
for (int i = 0; i < count; i++) {
|
||||
final float dx1 = horizontalOffset + i * lineWidthAndGap;
|
||||
final float dx2 = dx1 + mLineWidth;
|
||||
canvas.drawLine(dx1, verticalOffset, dx2, verticalOffset, i == mCurrentPage ? mPaintSelected
|
||||
: mPaintUnselected);
|
||||
}
|
||||
}
|
||||
|
||||
if (mCurrentPage >= count) {
|
||||
setCurrentItem(count - 1);
|
||||
return;
|
||||
}
|
||||
@Override
|
||||
public Parcelable onSaveInstanceState() {
|
||||
final Parcelable superState = super.onSaveInstanceState();
|
||||
final SavedState savedState = new SavedState(superState);
|
||||
savedState.currentPage = mCurrentPage;
|
||||
return savedState;
|
||||
}
|
||||
|
||||
final float lineWidthAndGap = mLineWidth + mGapWidth;
|
||||
final float indicatorWidth = count * lineWidthAndGap - mGapWidth;
|
||||
final float paddingTop = getPaddingTop();
|
||||
final float paddingLeft = getPaddingLeft();
|
||||
final float paddingRight = getPaddingRight();
|
||||
@Override
|
||||
public void onRestoreInstanceState(final Parcelable state) {
|
||||
final SavedState savedState = (SavedState) state;
|
||||
super.onRestoreInstanceState(savedState.getSuperState());
|
||||
mCurrentPage = savedState.currentPage;
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
final float verticalOffset = paddingTop + (getHeight() - paddingTop - getPaddingBottom()) / 2.0f;
|
||||
float horizontalOffset = paddingLeft;
|
||||
if (mCentered) {
|
||||
horizontalOffset += (getWidth() - paddingLeft - paddingRight) / 2.0f - indicatorWidth / 2.0f;
|
||||
}
|
||||
@Override
|
||||
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||
setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
|
||||
}
|
||||
|
||||
// Draw stroked circles
|
||||
for (int i = 0; i < count; i++) {
|
||||
final float dx1 = horizontalOffset + i * lineWidthAndGap;
|
||||
final float dx2 = dx1 + mLineWidth;
|
||||
canvas.drawLine(dx1, verticalOffset, dx2, verticalOffset, i == mCurrentPage ? mPaintSelected
|
||||
: mPaintUnselected);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Determines the height of this view
|
||||
*
|
||||
* @param measureSpec A measureSpec packed into an int
|
||||
* @return The height of the view, honoring constraints from measureSpec
|
||||
*/
|
||||
private int measureHeight(final int measureSpec) {
|
||||
float result;
|
||||
final int specMode = MeasureSpec.getMode(measureSpec);
|
||||
final int specSize = MeasureSpec.getSize(measureSpec);
|
||||
|
||||
@Override
|
||||
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||
setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
|
||||
}
|
||||
if (specMode == MeasureSpec.EXACTLY) {
|
||||
// We were told how big to be
|
||||
result = specSize;
|
||||
} else {
|
||||
// Measure the height
|
||||
result = mPaintSelected.getStrokeWidth() + getPaddingTop() + getPaddingBottom();
|
||||
// Respect AT_MOST value if that was what is called for by
|
||||
// measureSpec
|
||||
if (specMode == MeasureSpec.AT_MOST) {
|
||||
result = Math.min(result, specSize);
|
||||
}
|
||||
}
|
||||
return (int) Math.ceil(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the height of this view
|
||||
*
|
||||
* @param measureSpec A measureSpec packed into an int
|
||||
* @return The height of the view, honoring constraints from measureSpec
|
||||
*/
|
||||
private int measureHeight(final int measureSpec) {
|
||||
float result;
|
||||
final int specMode = MeasureSpec.getMode(measureSpec);
|
||||
final int specSize = MeasureSpec.getSize(measureSpec);
|
||||
/**
|
||||
* Determines the width of this view
|
||||
*
|
||||
* @param measureSpec A measureSpec packed into an int
|
||||
* @return The width of the view, honoring constraints from measureSpec
|
||||
*/
|
||||
private int measureWidth(final int measureSpec) {
|
||||
float result;
|
||||
final int specMode = MeasureSpec.getMode(measureSpec);
|
||||
final int specSize = MeasureSpec.getSize(measureSpec);
|
||||
|
||||
if (specMode == MeasureSpec.EXACTLY) {
|
||||
// We were told how big to be
|
||||
result = specSize;
|
||||
} else {
|
||||
// Measure the height
|
||||
result = mPaintSelected.getStrokeWidth() + getPaddingTop() + getPaddingBottom();
|
||||
// Respect AT_MOST value if that was what is called for by
|
||||
// measureSpec
|
||||
if (specMode == MeasureSpec.AT_MOST) {
|
||||
result = Math.min(result, specSize);
|
||||
}
|
||||
}
|
||||
return (int) Math.ceil(result);
|
||||
}
|
||||
if (specMode == MeasureSpec.EXACTLY || mViewPager == null) {
|
||||
// We were told how big to be
|
||||
result = specSize;
|
||||
} else {
|
||||
// Calculate the width according the views count
|
||||
final int count = mViewPager.getAdapter().getCount();
|
||||
result = getPaddingLeft() + getPaddingRight() + count * mLineWidth + (count - 1) * mGapWidth;
|
||||
// Respect AT_MOST value if that was what is called for by
|
||||
// measureSpec
|
||||
if (specMode == MeasureSpec.AT_MOST) {
|
||||
result = Math.min(result, specSize);
|
||||
}
|
||||
}
|
||||
return (int) Math.ceil(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the width of this view
|
||||
*
|
||||
* @param measureSpec A measureSpec packed into an int
|
||||
* @return The width of the view, honoring constraints from measureSpec
|
||||
*/
|
||||
private int measureWidth(final int measureSpec) {
|
||||
float result;
|
||||
final int specMode = MeasureSpec.getMode(measureSpec);
|
||||
final int specSize = MeasureSpec.getSize(measureSpec);
|
||||
static class SavedState extends BaseSavedState {
|
||||
public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
|
||||
@Override
|
||||
public SavedState createFromParcel(final Parcel in) {
|
||||
return new SavedState(in);
|
||||
}
|
||||
|
||||
if (specMode == MeasureSpec.EXACTLY || mViewPager == null) {
|
||||
// We were told how big to be
|
||||
result = specSize;
|
||||
} else {
|
||||
// Calculate the width according the views count
|
||||
final int count = mViewPager.getAdapter().getCount();
|
||||
result = getPaddingLeft() + getPaddingRight() + count * mLineWidth + (count - 1) * mGapWidth;
|
||||
// Respect AT_MOST value if that was what is called for by
|
||||
// measureSpec
|
||||
if (specMode == MeasureSpec.AT_MOST) {
|
||||
result = Math.min(result, specSize);
|
||||
}
|
||||
}
|
||||
return (int) Math.ceil(result);
|
||||
}
|
||||
@Override
|
||||
public SavedState[] newArray(final int size) {
|
||||
return new SavedState[size];
|
||||
}
|
||||
};
|
||||
int currentPage;
|
||||
|
||||
static class SavedState extends BaseSavedState {
|
||||
int currentPage;
|
||||
public SavedState(final Parcelable superState) {
|
||||
super(superState);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
|
||||
@Override
|
||||
public SavedState createFromParcel(final Parcel in) {
|
||||
return new SavedState(in);
|
||||
}
|
||||
private SavedState(final Parcel in) {
|
||||
super(in);
|
||||
currentPage = in.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SavedState[] newArray(final int size) {
|
||||
return new SavedState[size];
|
||||
}
|
||||
};
|
||||
|
||||
public SavedState(final Parcelable superState) {
|
||||
super(superState);
|
||||
}
|
||||
|
||||
private SavedState(final Parcel in) {
|
||||
super(in);
|
||||
currentPage = in.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(final Parcel dest, final int flags) {
|
||||
super.writeToParcel(dest, flags);
|
||||
dest.writeInt(currentPage);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void writeToParcel(final Parcel dest, final int flags) {
|
||||
super.writeToParcel(dest, flags);
|
||||
dest.writeInt(currentPage);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -24,24 +24,24 @@ import android.util.AttributeSet;
|
|||
|
||||
public class MapImageView extends ForegroundImageView {
|
||||
|
||||
public MapImageView(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
public MapImageView(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public MapImageView(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
public MapImageView(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public MapImageView(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
public MapImageView(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||
final int width = MeasureSpec.getSize(widthMeasureSpec), height = width / 2;
|
||||
final int hSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
|
||||
super.onMeasure(widthMeasureSpec, hSpec);
|
||||
setMeasuredDimension(width, height);
|
||||
}
|
||||
@Override
|
||||
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||
final int width = MeasureSpec.getSize(widthMeasureSpec), height = width / 2;
|
||||
final int hSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
|
||||
super.onMeasure(widthMeasureSpec, hSpec);
|
||||
setMeasuredDimension(width, height);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
package org.mariotaku.twidere.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
|
@ -31,6 +32,7 @@ public class ProfileBannerImageView extends ForegroundImageView implements IExte
|
|||
|
||||
private OnSizeChangedListener mOnSizeChangedListener;
|
||||
private TouchInterceptor mTouchInterceptor;
|
||||
private OnFitSystemWindowsListener mOnFitSystemWindowsListener;
|
||||
|
||||
public ProfileBannerImageView(final Context context) {
|
||||
this(context, null);
|
||||
|
@ -46,6 +48,29 @@ public class ProfileBannerImageView extends ForegroundImageView implements IExte
|
|||
setScaleType(ScaleType.CENTER_CROP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnFitSystemWindowsListener(OnFitSystemWindowsListener listener) {
|
||||
mOnFitSystemWindowsListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setOnSizeChangedListener(final OnSizeChangedListener listener) {
|
||||
mOnSizeChangedListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setTouchInterceptor(final TouchInterceptor listener) {
|
||||
mTouchInterceptor = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean fitSystemWindows(@NonNull Rect insets) {
|
||||
if (mOnFitSystemWindowsListener != null) {
|
||||
mOnFitSystemWindowsListener.onFitSystemWindows(insets);
|
||||
}
|
||||
return super.fitSystemWindows(insets);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean dispatchTouchEvent(@NonNull final MotionEvent event) {
|
||||
if (mTouchInterceptor != null) {
|
||||
|
@ -64,16 +89,6 @@ public class ProfileBannerImageView extends ForegroundImageView implements IExte
|
|||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setOnSizeChangedListener(final OnSizeChangedListener listener) {
|
||||
mOnSizeChangedListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setTouchInterceptor(final TouchInterceptor listener) {
|
||||
mTouchInterceptor = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||
final int width = MeasureSpec.getSize(widthMeasureSpec), height = width / 2;
|
||||
|
|
|
@ -33,6 +33,12 @@ public class ProfileBannerSpace extends View {
|
|||
mSystemWindowsInsets = new Rect();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean fitSystemWindows(Rect insets) {
|
||||
mSystemWindowsInsets.set(insets);
|
||||
return super.fitSystemWindows(insets);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw nothing.
|
||||
*
|
||||
|
@ -42,12 +48,6 @@ public class ProfileBannerSpace extends View {
|
|||
public void draw(final Canvas canvas) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean fitSystemWindows(Rect insets) {
|
||||
mSystemWindowsInsets.set(insets);
|
||||
return super.fitSystemWindows(insets);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||
final int width = MeasureSpec.getSize(widthMeasureSpec), height = width / 2 - mSystemWindowsInsets.top;
|
||||
|
|
|
@ -256,6 +256,10 @@ public class ShapedImageView extends ImageView {
|
|||
invalidate();
|
||||
}
|
||||
|
||||
public void setCornerRadius(float radius) {
|
||||
mCornerRadius = radius;
|
||||
}
|
||||
|
||||
public void setCornerRadiusRatio(float ratio) {
|
||||
mCornerRadiusRatio = ratio;
|
||||
}
|
||||
|
@ -417,10 +421,6 @@ public class ShapedImageView extends ImageView {
|
|||
return 0;
|
||||
}
|
||||
|
||||
public void setCornerRadius(float radius) {
|
||||
mCornerRadius = radius;
|
||||
}
|
||||
|
||||
private void initOutlineProvider() {
|
||||
ViewAccessor.setClipToOutline(this, true);
|
||||
ViewAccessor.setOutlineProvider(this, new CircularOutlineProvider());
|
||||
|
|
|
@ -39,12 +39,10 @@ public class ShortTimeView extends ThemedTextView implements Constants, OnShared
|
|||
private static final long TICKER_DURATION = 5000L;
|
||||
|
||||
private final Runnable mTicker;
|
||||
|
||||
private final SharedPreferences mPreferences;
|
||||
private boolean mShowAbsoluteTime;
|
||||
private long mTime;
|
||||
|
||||
private final SharedPreferences mPreferences;
|
||||
|
||||
public ShortTimeView(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
|
|
@ -25,37 +25,37 @@ import android.view.ViewGroup;
|
|||
|
||||
public class SquareCircularImageView extends ShapedImageView {
|
||||
|
||||
public SquareCircularImageView(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
public SquareCircularImageView(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public SquareCircularImageView(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
public SquareCircularImageView(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public SquareCircularImageView(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
public SquareCircularImageView(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||
final int width = MeasureSpec.getSize(widthMeasureSpec), height = MeasureSpec.getSize(heightMeasureSpec);
|
||||
final ViewGroup.LayoutParams lp = getLayoutParams();
|
||||
if (lp.height == ViewGroup.LayoutParams.MATCH_PARENT && lp.width == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
||||
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
|
||||
setMeasuredDimension(height, height);
|
||||
} else if (lp.width == ViewGroup.LayoutParams.MATCH_PARENT && lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
setMeasuredDimension(width, width);
|
||||
} else {
|
||||
if (width > height) {
|
||||
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
|
||||
setMeasuredDimension(height, height);
|
||||
} else {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
setMeasuredDimension(width, width);
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||
final int width = MeasureSpec.getSize(widthMeasureSpec), height = MeasureSpec.getSize(heightMeasureSpec);
|
||||
final ViewGroup.LayoutParams lp = getLayoutParams();
|
||||
if (lp.height == ViewGroup.LayoutParams.MATCH_PARENT && lp.width == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
||||
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
|
||||
setMeasuredDimension(height, height);
|
||||
} else if (lp.width == ViewGroup.LayoutParams.MATCH_PARENT && lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
setMeasuredDimension(width, width);
|
||||
} else {
|
||||
if (width > height) {
|
||||
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
|
||||
setMeasuredDimension(height, height);
|
||||
} else {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
setMeasuredDimension(width, width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,37 +26,37 @@ import android.widget.FrameLayout;
|
|||
|
||||
public class SquareFrameLayout extends FrameLayout {
|
||||
|
||||
public SquareFrameLayout(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
public SquareFrameLayout(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public SquareFrameLayout(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
public SquareFrameLayout(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public SquareFrameLayout(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
public SquareFrameLayout(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||
final int width = MeasureSpec.getSize(widthMeasureSpec), height = MeasureSpec.getSize(heightMeasureSpec);
|
||||
final ViewGroup.LayoutParams lp = getLayoutParams();
|
||||
if (lp.height == ViewGroup.LayoutParams.MATCH_PARENT && lp.width == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
||||
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
|
||||
setMeasuredDimension(height, height);
|
||||
} else if (lp.width == ViewGroup.LayoutParams.MATCH_PARENT && lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
setMeasuredDimension(width, width);
|
||||
} else {
|
||||
if (width > height) {
|
||||
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
|
||||
setMeasuredDimension(height, height);
|
||||
} else {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
setMeasuredDimension(width, width);
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||
final int width = MeasureSpec.getSize(widthMeasureSpec), height = MeasureSpec.getSize(heightMeasureSpec);
|
||||
final ViewGroup.LayoutParams lp = getLayoutParams();
|
||||
if (lp.height == ViewGroup.LayoutParams.MATCH_PARENT && lp.width == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
||||
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
|
||||
setMeasuredDimension(height, height);
|
||||
} else if (lp.width == ViewGroup.LayoutParams.MATCH_PARENT && lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
setMeasuredDimension(width, width);
|
||||
} else {
|
||||
if (width > height) {
|
||||
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
|
||||
setMeasuredDimension(height, height);
|
||||
} else {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
setMeasuredDimension(width, width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,37 +25,37 @@ import android.view.ViewGroup;
|
|||
|
||||
public class SquareHighlightImageView extends HighlightImageView {
|
||||
|
||||
public SquareHighlightImageView(final Context context) {
|
||||
super(context);
|
||||
}
|
||||
public SquareHighlightImageView(final Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public SquareHighlightImageView(final Context context, final AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
public SquareHighlightImageView(final Context context, final AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public SquareHighlightImageView(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
public SquareHighlightImageView(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||
final int width = MeasureSpec.getSize(widthMeasureSpec), height = MeasureSpec.getSize(heightMeasureSpec);
|
||||
final ViewGroup.LayoutParams lp = getLayoutParams();
|
||||
if (lp.height == ViewGroup.LayoutParams.MATCH_PARENT && lp.width == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
||||
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
|
||||
setMeasuredDimension(height, height);
|
||||
} else if (lp.width == ViewGroup.LayoutParams.MATCH_PARENT && lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
setMeasuredDimension(width, width);
|
||||
} else {
|
||||
if (width > height) {
|
||||
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
|
||||
setMeasuredDimension(height, height);
|
||||
} else {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
setMeasuredDimension(width, width);
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||
final int width = MeasureSpec.getSize(widthMeasureSpec), height = MeasureSpec.getSize(heightMeasureSpec);
|
||||
final ViewGroup.LayoutParams lp = getLayoutParams();
|
||||
if (lp.height == ViewGroup.LayoutParams.MATCH_PARENT && lp.width == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
||||
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
|
||||
setMeasuredDimension(height, height);
|
||||
} else if (lp.width == ViewGroup.LayoutParams.MATCH_PARENT && lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
setMeasuredDimension(width, width);
|
||||
} else {
|
||||
if (width > height) {
|
||||
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
|
||||
setMeasuredDimension(height, height);
|
||||
} else {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
setMeasuredDimension(width, width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,37 +26,37 @@ import android.widget.ImageView;
|
|||
|
||||
public class SquareImageView extends ImageView {
|
||||
|
||||
public SquareImageView(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
public SquareImageView(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public SquareImageView(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
public SquareImageView(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public SquareImageView(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
public SquareImageView(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||
final int width = MeasureSpec.getSize(widthMeasureSpec), height = MeasureSpec.getSize(heightMeasureSpec);
|
||||
final ViewGroup.LayoutParams lp = getLayoutParams();
|
||||
if (lp.height == ViewGroup.LayoutParams.MATCH_PARENT && lp.width == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
||||
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
|
||||
setMeasuredDimension(height, height);
|
||||
} else if (lp.width == ViewGroup.LayoutParams.MATCH_PARENT && lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
setMeasuredDimension(width, width);
|
||||
} else {
|
||||
if (width > height) {
|
||||
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
|
||||
setMeasuredDimension(height, height);
|
||||
} else {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
setMeasuredDimension(width, width);
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||
final int width = MeasureSpec.getSize(widthMeasureSpec), height = MeasureSpec.getSize(heightMeasureSpec);
|
||||
final ViewGroup.LayoutParams lp = getLayoutParams();
|
||||
if (lp.height == ViewGroup.LayoutParams.MATCH_PARENT && lp.width == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
||||
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
|
||||
setMeasuredDimension(height, height);
|
||||
} else if (lp.width == ViewGroup.LayoutParams.MATCH_PARENT && lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
setMeasuredDimension(width, width);
|
||||
} else {
|
||||
if (width > height) {
|
||||
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
|
||||
setMeasuredDimension(height, height);
|
||||
} else {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
setMeasuredDimension(width, width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,37 +26,37 @@ import android.widget.RelativeLayout;
|
|||
|
||||
public class SquareRelativeLayout extends RelativeLayout {
|
||||
|
||||
public SquareRelativeLayout(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
public SquareRelativeLayout(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public SquareRelativeLayout(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
public SquareRelativeLayout(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public SquareRelativeLayout(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
public SquareRelativeLayout(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||
final int width = MeasureSpec.getSize(widthMeasureSpec), height = MeasureSpec.getSize(heightMeasureSpec);
|
||||
final ViewGroup.LayoutParams lp = getLayoutParams();
|
||||
if (lp.height == ViewGroup.LayoutParams.MATCH_PARENT && lp.width == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
||||
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
|
||||
setMeasuredDimension(height, height);
|
||||
} else if (lp.width == ViewGroup.LayoutParams.MATCH_PARENT && lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
setMeasuredDimension(width, width);
|
||||
} else {
|
||||
if (width > height) {
|
||||
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
|
||||
setMeasuredDimension(height, height);
|
||||
} else {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
setMeasuredDimension(width, width);
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||
final int width = MeasureSpec.getSize(widthMeasureSpec), height = MeasureSpec.getSize(heightMeasureSpec);
|
||||
final ViewGroup.LayoutParams lp = getLayoutParams();
|
||||
if (lp.height == ViewGroup.LayoutParams.MATCH_PARENT && lp.width == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
||||
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
|
||||
setMeasuredDimension(height, height);
|
||||
} else if (lp.width == ViewGroup.LayoutParams.MATCH_PARENT && lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
setMeasuredDimension(width, width);
|
||||
} else {
|
||||
if (width > height) {
|
||||
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
|
||||
setMeasuredDimension(height, height);
|
||||
} else {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
setMeasuredDimension(width, width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,37 +26,37 @@ import android.view.ViewGroup;
|
|||
|
||||
public class SquareView extends View {
|
||||
|
||||
public SquareView(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
public SquareView(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public SquareView(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
public SquareView(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public SquareView(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
public SquareView(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||
final int width = MeasureSpec.getSize(widthMeasureSpec), height = MeasureSpec.getSize(heightMeasureSpec);
|
||||
final ViewGroup.LayoutParams lp = getLayoutParams();
|
||||
if (lp.height == ViewGroup.LayoutParams.MATCH_PARENT && lp.width == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
||||
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
|
||||
setMeasuredDimension(height, height);
|
||||
} else if (lp.width == ViewGroup.LayoutParams.MATCH_PARENT && lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
setMeasuredDimension(width, width);
|
||||
} else {
|
||||
if (width > height) {
|
||||
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
|
||||
setMeasuredDimension(height, height);
|
||||
} else {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
setMeasuredDimension(width, width);
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||
final int width = MeasureSpec.getSize(widthMeasureSpec), height = MeasureSpec.getSize(heightMeasureSpec);
|
||||
final ViewGroup.LayoutParams lp = getLayoutParams();
|
||||
if (lp.height == ViewGroup.LayoutParams.MATCH_PARENT && lp.width == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
||||
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
|
||||
setMeasuredDimension(height, height);
|
||||
} else if (lp.width == ViewGroup.LayoutParams.MATCH_PARENT && lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
setMeasuredDimension(width, width);
|
||||
} else {
|
||||
if (width > height) {
|
||||
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
|
||||
setMeasuredDimension(height, height);
|
||||
} else {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
setMeasuredDimension(width, width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,33 +26,33 @@ import android.view.ViewGroup;
|
|||
|
||||
public class SquareViewPager extends ViewPager {
|
||||
|
||||
public SquareViewPager(final Context context) {
|
||||
super(context);
|
||||
}
|
||||
public SquareViewPager(final Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public SquareViewPager(final Context context, final AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
public SquareViewPager(final Context context, final AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||
final int width = MeasureSpec.getSize(widthMeasureSpec), height = MeasureSpec.getSize(heightMeasureSpec);
|
||||
final ViewGroup.LayoutParams lp = getLayoutParams();
|
||||
if (lp.height == ViewGroup.LayoutParams.MATCH_PARENT && lp.width == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
||||
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
|
||||
setMeasuredDimension(height, height);
|
||||
} else if (lp.width == ViewGroup.LayoutParams.MATCH_PARENT && lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
setMeasuredDimension(width, width);
|
||||
} else {
|
||||
if (width > height) {
|
||||
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
|
||||
setMeasuredDimension(height, height);
|
||||
} else {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
setMeasuredDimension(width, width);
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||
final int width = MeasureSpec.getSize(widthMeasureSpec), height = MeasureSpec.getSize(heightMeasureSpec);
|
||||
final ViewGroup.LayoutParams lp = getLayoutParams();
|
||||
if (lp.height == ViewGroup.LayoutParams.MATCH_PARENT && lp.width == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
||||
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
|
||||
setMeasuredDimension(height, height);
|
||||
} else if (lp.width == ViewGroup.LayoutParams.MATCH_PARENT && lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
setMeasuredDimension(width, width);
|
||||
} else {
|
||||
if (width > height) {
|
||||
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
|
||||
setMeasuredDimension(height, height);
|
||||
} else {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||
setMeasuredDimension(width, width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
package org.mariotaku.twidere.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.text.InputType;
|
||||
import android.text.SpannableString;
|
||||
import android.text.Spanned;
|
||||
|
@ -53,6 +52,16 @@ public class StatusComposeEditText extends ThemedMultiAutoCompleteTextView imple
|
|||
| InputType.TYPE_TEXT_FLAG_MULTI_LINE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int computeVerticalScrollRange() {
|
||||
return super.computeVerticalScrollRange();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int computeVerticalScrollExtent() {
|
||||
return super.computeVerticalScrollExtent();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
|
@ -78,34 +87,8 @@ public class StatusComposeEditText extends ThemedMultiAutoCompleteTextView imple
|
|||
append(" ");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int computeVerticalScrollRange() {
|
||||
return super.computeVerticalScrollRange();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int computeVerticalScrollExtent() {
|
||||
return super.computeVerticalScrollExtent();
|
||||
}
|
||||
|
||||
private static class ScreenNameTokenizer implements Tokenizer {
|
||||
|
||||
@Override
|
||||
public int findTokenEnd(final CharSequence text, final int cursor) {
|
||||
int i = cursor;
|
||||
final int len = text.length();
|
||||
|
||||
while (i < len) {
|
||||
if (text.charAt(i) == ' ')
|
||||
return i;
|
||||
else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int findTokenStart(final CharSequence text, final int cursor) {
|
||||
int start = cursor;
|
||||
|
@ -127,6 +110,22 @@ public class StatusComposeEditText extends ThemedMultiAutoCompleteTextView imple
|
|||
return start;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int findTokenEnd(final CharSequence text, final int cursor) {
|
||||
int i = cursor;
|
||||
final int len = text.length();
|
||||
|
||||
while (i < len) {
|
||||
if (text.charAt(i) == ' ')
|
||||
return i;
|
||||
else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence terminateToken(final CharSequence text) {
|
||||
int i = text.length();
|
||||
|
|
|
@ -19,8 +19,6 @@
|
|||
|
||||
package org.mariotaku.twidere.view;
|
||||
|
||||
import static org.mariotaku.twidere.util.Utils.getLocalizedNumber;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Color;
|
||||
|
@ -32,46 +30,48 @@ import org.mariotaku.twidere.util.TwidereValidator;
|
|||
|
||||
import java.util.Locale;
|
||||
|
||||
import static org.mariotaku.twidere.util.Utils.getLocalizedNumber;
|
||||
|
||||
public class StatusTextCountView extends TextView {
|
||||
|
||||
private final int mTextColor;
|
||||
private final Locale mLocale;
|
||||
private final TwidereValidator mValidator;
|
||||
private final int mTextColor;
|
||||
private final Locale mLocale;
|
||||
private final TwidereValidator mValidator;
|
||||
|
||||
public StatusTextCountView(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
public StatusTextCountView(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public StatusTextCountView(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, android.R.attr.textViewStyle);
|
||||
}
|
||||
public StatusTextCountView(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, android.R.attr.textViewStyle);
|
||||
}
|
||||
|
||||
public StatusTextCountView(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
mValidator = new TwidereValidator(context);
|
||||
if (isInEditMode()) {
|
||||
mTextColor = 0;
|
||||
mLocale = Locale.getDefault();
|
||||
} else {
|
||||
final int textAppearance = ThemeUtils.getTitleTextAppearance(context);
|
||||
final TypedArray a = context.obtainStyledAttributes(textAppearance, new int[] { android.R.attr.textColor });
|
||||
mTextColor = a.getColor(0, 0);
|
||||
a.recycle();
|
||||
mLocale = getResources().getConfiguration().locale;
|
||||
setTextColor(mTextColor);
|
||||
}
|
||||
}
|
||||
public StatusTextCountView(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
mValidator = new TwidereValidator(context);
|
||||
if (isInEditMode()) {
|
||||
mTextColor = 0;
|
||||
mLocale = Locale.getDefault();
|
||||
} else {
|
||||
final int textAppearance = ThemeUtils.getTitleTextAppearance(context);
|
||||
final TypedArray a = context.obtainStyledAttributes(textAppearance, new int[]{android.R.attr.textColor});
|
||||
mTextColor = a.getColor(0, 0);
|
||||
a.recycle();
|
||||
mLocale = getResources().getConfiguration().locale;
|
||||
setTextColor(mTextColor);
|
||||
}
|
||||
}
|
||||
|
||||
public void setTextCount(final int count) {
|
||||
final int maxLength = mValidator.getMaxTweetLength();
|
||||
setText(getLocalizedNumber(mLocale, maxLength - count));
|
||||
final boolean exceeded_limit = count < maxLength;
|
||||
final boolean near_limit = count >= maxLength - 10;
|
||||
final float hue = exceeded_limit ? near_limit ? 5 * (maxLength - count) : 50 : 0;
|
||||
final float[] textColorHsv = new float[3];
|
||||
Color.colorToHSV(mTextColor, textColorHsv);
|
||||
final float[] errorColorHsv = { hue, 1.0f, 0.75f + textColorHsv[2] / 4 };
|
||||
setTextColor(count >= maxLength - 10 ? Color.HSVToColor(errorColorHsv) : mTextColor);
|
||||
}
|
||||
public void setTextCount(final int count) {
|
||||
final int maxLength = mValidator.getMaxTweetLength();
|
||||
setText(getLocalizedNumber(mLocale, maxLength - count));
|
||||
final boolean exceeded_limit = count < maxLength;
|
||||
final boolean near_limit = count >= maxLength - 10;
|
||||
final float hue = exceeded_limit ? near_limit ? 5 * (maxLength - count) : 50 : 0;
|
||||
final float[] textColorHsv = new float[3];
|
||||
Color.colorToHSV(mTextColor, textColorHsv);
|
||||
final float[] errorColorHsv = {hue, 1.0f, 0.75f + textColorHsv[2] / 4};
|
||||
setTextColor(count >= maxLength - 10 ? Color.HSVToColor(errorColorHsv) : mTextColor);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.mariotaku.twidere.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
|
@ -13,6 +14,7 @@ public class StatusTextView extends ThemedTextView implements IExtendedView {
|
|||
private TouchInterceptor mTouchInterceptor;
|
||||
private OnSizeChangedListener mOnSizeChangedListener;
|
||||
private OnSelectionChangeListener mOnSelectionChangeListener;
|
||||
private OnFitSystemWindowsListener mOnFitSystemWindowsListener;
|
||||
|
||||
public StatusTextView(final Context context) {
|
||||
super(context);
|
||||
|
@ -27,25 +29,8 @@ public class StatusTextView extends ThemedTextView implements IExtendedView {
|
|||
}
|
||||
|
||||
@Override
|
||||
public final boolean dispatchTouchEvent(@NonNull final MotionEvent event) {
|
||||
if (mTouchInterceptor != null) {
|
||||
final boolean ret = mTouchInterceptor.dispatchTouchEvent(this, event);
|
||||
if (ret) return true;
|
||||
}
|
||||
return super.dispatchTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean onTouchEvent(@NonNull final MotionEvent event) {
|
||||
if (mTouchInterceptor != null) {
|
||||
final boolean ret = mTouchInterceptor.onTouchEvent(this, event);
|
||||
if (ret) return true;
|
||||
}
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
public void setOnSelectionChangeListener(final OnSelectionChangeListener l) {
|
||||
mOnSelectionChangeListener = l;
|
||||
public void setOnFitSystemWindowsListener(OnFitSystemWindowsListener listener) {
|
||||
mOnFitSystemWindowsListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -58,12 +43,25 @@ public class StatusTextView extends ThemedTextView implements IExtendedView {
|
|||
mTouchInterceptor = listener;
|
||||
}
|
||||
|
||||
public void setOnSelectionChangeListener(final OnSelectionChangeListener l) {
|
||||
mOnSelectionChangeListener = l;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSelectionChanged(final int selStart, final int selEnd) {
|
||||
super.onSelectionChanged(selStart, selEnd);
|
||||
if (mOnSelectionChangeListener != null) {
|
||||
mOnSelectionChangeListener.onSelectionChanged(selStart, selEnd);
|
||||
protected boolean fitSystemWindows(@NonNull Rect insets) {
|
||||
if (mOnFitSystemWindowsListener != null) {
|
||||
mOnFitSystemWindowsListener.onFitSystemWindows(insets);
|
||||
}
|
||||
return super.fitSystemWindows(insets);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean dispatchTouchEvent(@NonNull final MotionEvent event) {
|
||||
if (mTouchInterceptor != null) {
|
||||
final boolean ret = mTouchInterceptor.dispatchTouchEvent(this, event);
|
||||
if (ret) return true;
|
||||
}
|
||||
return super.dispatchTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -74,6 +72,23 @@ public class StatusTextView extends ThemedTextView implements IExtendedView {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSelectionChanged(final int selStart, final int selEnd) {
|
||||
super.onSelectionChanged(selStart, selEnd);
|
||||
if (mOnSelectionChangeListener != null) {
|
||||
mOnSelectionChangeListener.onSelectionChanged(selStart, selEnd);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean onTouchEvent(@NonNull final MotionEvent event) {
|
||||
if (mTouchInterceptor != null) {
|
||||
final boolean ret = mTouchInterceptor.onTouchEvent(this, event);
|
||||
if (ret) return true;
|
||||
}
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
public interface OnSelectionChangeListener {
|
||||
void onSelectionChanged(int selStart, int selEnd);
|
||||
}
|
||||
|
|
|
@ -80,19 +80,11 @@ public class TabPagerIndicator extends RecyclerView implements PagerIndicator {
|
|||
a.recycle();
|
||||
}
|
||||
|
||||
private void setTabShowDivider(boolean showDivider) {
|
||||
if (showDivider) {
|
||||
addItemDecoration(mItemDecoration);
|
||||
} else {
|
||||
removeItemDecoration(mItemDecoration);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public TabPagerIndicator(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
|
||||
public TabPagerIndicator(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
@ -239,6 +231,14 @@ public class TabPagerIndicator extends RecyclerView implements PagerIndicator {
|
|||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private void setTabShowDivider(boolean showDivider) {
|
||||
if (showDivider) {
|
||||
addItemDecoration(mItemDecoration);
|
||||
} else {
|
||||
removeItemDecoration(mItemDecoration);
|
||||
}
|
||||
}
|
||||
|
||||
private void setVerticalPadding(int padding) {
|
||||
mVerticalPadding = padding;
|
||||
notifyDataSetChanged();
|
||||
|
@ -249,80 +249,46 @@ public class TabPagerIndicator extends RecyclerView implements PagerIndicator {
|
|||
public @interface DisplayOption {
|
||||
}
|
||||
|
||||
private static class TabPagerIndicatorAdapter extends Adapter<TabItemHolder> {
|
||||
public static final class ItemLayout extends RelativeLayout {
|
||||
|
||||
private final TabPagerIndicator mIndicator;
|
||||
private final SparseIntArray mUnreadCounts;
|
||||
private Context mItemContext;
|
||||
private LayoutInflater mInflater;
|
||||
private final Paint mStripPaint;
|
||||
|
||||
private TabProvider mTabProvider;
|
||||
private int mStripColor, mIconColor;
|
||||
private boolean mDisplayBadge;
|
||||
private boolean mIsCurrent;
|
||||
private int mStripColor;
|
||||
private int mStripHeight;
|
||||
|
||||
public TabPagerIndicatorAdapter(TabPagerIndicator indicator) {
|
||||
mIndicator = indicator;
|
||||
mUnreadCounts = new SparseIntArray();
|
||||
public ItemLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mStripPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
setWillNotDraw(false);
|
||||
}
|
||||
|
||||
public Context getItemContext() {
|
||||
return mItemContext;
|
||||
public void setIsCurrent(boolean isCurrent) {
|
||||
if (mIsCurrent == isCurrent) return;
|
||||
mIsCurrent = isCurrent;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setItemContext(Context itemContext) {
|
||||
mItemContext = itemContext;
|
||||
mInflater = LayoutInflater.from(itemContext);
|
||||
public void setStripColor(int stripColor) {
|
||||
if (mStripColor == stripColor) return;
|
||||
mStripColor = stripColor;
|
||||
mStripPaint.setColor(stripColor);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setStripHeight(int stripHeight) {
|
||||
if (mStripHeight == stripHeight) return;
|
||||
mStripHeight = stripHeight;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TabItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
if (mIndicator == null) throw new IllegalStateException("item context not set");
|
||||
final View view = mInflater.inflate(R.layout.layout_tab_item, parent, false);
|
||||
return new TabItemHolder(mIndicator, view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(TabItemHolder holder, int position) {
|
||||
final Drawable icon = mTabProvider.getPageIcon(position);
|
||||
final CharSequence title = mTabProvider.getPageTitle(position);
|
||||
holder.setTabData(icon, title, mIndicator.getCurrentItem() == position);
|
||||
holder.setPadding(mIndicator.getTabHorizontalPadding(), mIndicator.getTabVerticalPadding());
|
||||
holder.setStripHeight(mIndicator.getStripHeight());
|
||||
holder.setStripColor(mStripColor);
|
||||
holder.setIconColor(mIconColor);
|
||||
holder.setBadge(mUnreadCounts.get(position, 0), mDisplayBadge);
|
||||
holder.setDisplayOption(mIndicator.isIconDisplayed(), mIndicator.isLabelDisplayed());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
if (mTabProvider == null) return 0;
|
||||
return mTabProvider.getCount();
|
||||
}
|
||||
|
||||
public void setBadge(int position, int count) {
|
||||
mUnreadCounts.put(position, count);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void setDisplayBadge(boolean display) {
|
||||
mDisplayBadge = display;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void setIconColor(int color) {
|
||||
mIconColor = color;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void setStripColor(int color) {
|
||||
mStripColor = color;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void setTabProvider(TabProvider tabProvider) {
|
||||
mTabProvider = tabProvider;
|
||||
notifyDataSetChanged();
|
||||
protected void onDraw(Canvas canvas) {
|
||||
if (mIsCurrent) {
|
||||
final int width = canvas.getWidth(), height = canvas.getHeight();
|
||||
canvas.drawRect(0, height - mStripHeight, width, height, mStripPaint);
|
||||
}
|
||||
super.onDraw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -419,46 +385,80 @@ public class TabPagerIndicator extends RecyclerView implements PagerIndicator {
|
|||
}
|
||||
}
|
||||
|
||||
public static final class ItemLayout extends RelativeLayout {
|
||||
private static class TabPagerIndicatorAdapter extends Adapter<TabItemHolder> {
|
||||
|
||||
private final Paint mStripPaint;
|
||||
private final TabPagerIndicator mIndicator;
|
||||
private final SparseIntArray mUnreadCounts;
|
||||
private Context mItemContext;
|
||||
private LayoutInflater mInflater;
|
||||
|
||||
private boolean mIsCurrent;
|
||||
private int mStripColor;
|
||||
private int mStripHeight;
|
||||
private TabProvider mTabProvider;
|
||||
private int mStripColor, mIconColor;
|
||||
private boolean mDisplayBadge;
|
||||
|
||||
public ItemLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mStripPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
setWillNotDraw(false);
|
||||
public TabPagerIndicatorAdapter(TabPagerIndicator indicator) {
|
||||
mIndicator = indicator;
|
||||
mUnreadCounts = new SparseIntArray();
|
||||
}
|
||||
|
||||
public void setIsCurrent(boolean isCurrent) {
|
||||
if (mIsCurrent == isCurrent) return;
|
||||
mIsCurrent = isCurrent;
|
||||
invalidate();
|
||||
public Context getItemContext() {
|
||||
return mItemContext;
|
||||
}
|
||||
|
||||
public void setStripColor(int stripColor) {
|
||||
if (mStripColor == stripColor) return;
|
||||
mStripColor = stripColor;
|
||||
mStripPaint.setColor(stripColor);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setStripHeight(int stripHeight) {
|
||||
if (mStripHeight == stripHeight) return;
|
||||
mStripHeight = stripHeight;
|
||||
invalidate();
|
||||
public void setItemContext(Context itemContext) {
|
||||
mItemContext = itemContext;
|
||||
mInflater = LayoutInflater.from(itemContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
if (mIsCurrent) {
|
||||
final int width = canvas.getWidth(), height = canvas.getHeight();
|
||||
canvas.drawRect(0, height - mStripHeight, width, height, mStripPaint);
|
||||
}
|
||||
super.onDraw(canvas);
|
||||
public TabItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
if (mIndicator == null) throw new IllegalStateException("item context not set");
|
||||
final View view = mInflater.inflate(R.layout.layout_tab_item, parent, false);
|
||||
return new TabItemHolder(mIndicator, view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(TabItemHolder holder, int position) {
|
||||
final Drawable icon = mTabProvider.getPageIcon(position);
|
||||
final CharSequence title = mTabProvider.getPageTitle(position);
|
||||
holder.setTabData(icon, title, mIndicator.getCurrentItem() == position);
|
||||
holder.setPadding(mIndicator.getTabHorizontalPadding(), mIndicator.getTabVerticalPadding());
|
||||
holder.setStripHeight(mIndicator.getStripHeight());
|
||||
holder.setStripColor(mStripColor);
|
||||
holder.setIconColor(mIconColor);
|
||||
holder.setBadge(mUnreadCounts.get(position, 0), mDisplayBadge);
|
||||
holder.setDisplayOption(mIndicator.isIconDisplayed(), mIndicator.isLabelDisplayed());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
if (mTabProvider == null) return 0;
|
||||
return mTabProvider.getCount();
|
||||
}
|
||||
|
||||
public void setBadge(int position, int count) {
|
||||
mUnreadCounts.put(position, count);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void setDisplayBadge(boolean display) {
|
||||
mDisplayBadge = display;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void setIconColor(int color) {
|
||||
mIconColor = color;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void setStripColor(int color) {
|
||||
mStripColor = color;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void setTabProvider(TabProvider tabProvider) {
|
||||
mTabProvider = tabProvider;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,20 +72,30 @@ public class TintedStatusFrameLayout extends FrameLayout {
|
|||
updateAlpha();
|
||||
}
|
||||
|
||||
public void setDrawColor(boolean color) {
|
||||
mDrawColor = color;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setDrawShadow(boolean shadow) {
|
||||
mDrawShadow = shadow;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setFactor(float f) {
|
||||
mFactor = f;
|
||||
updateAlpha();
|
||||
}
|
||||
|
||||
public void setShadowColor(int color) {
|
||||
mShadowPaint.setColor(color);
|
||||
mShadowAlpha = Color.alpha(color);
|
||||
updateAlpha();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean fitSystemWindows(@NonNull Rect insets) {
|
||||
setStatusBarHeight(Utils.getInsetsTopWithoutActionBarHeight(getContext(), insets.top));
|
||||
final Context context = getContext();
|
||||
if (context instanceof FitSystemWindowsCallback) {
|
||||
((FitSystemWindowsCallback) context).fitSystemWindows(insets);
|
||||
}
|
||||
return super.fitSystemWindows(insets);
|
||||
public void setStatusBarHeight(int height) {
|
||||
mStatusBarHeight = height;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -99,24 +109,14 @@ public class TintedStatusFrameLayout extends FrameLayout {
|
|||
canvas.drawRect(0, 0, canvas.getWidth(), mStatusBarHeight, mDrawColor ? mColorPaint : mBlackPaint);
|
||||
}
|
||||
|
||||
public void setStatusBarHeight(int height) {
|
||||
mStatusBarHeight = height;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setFactor(float f) {
|
||||
mFactor = f;
|
||||
updateAlpha();
|
||||
}
|
||||
|
||||
public void setDrawShadow(boolean shadow) {
|
||||
mDrawShadow = shadow;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setDrawColor(boolean color) {
|
||||
mDrawColor = color;
|
||||
invalidate();
|
||||
@Override
|
||||
protected boolean fitSystemWindows(@NonNull Rect insets) {
|
||||
setStatusBarHeight(Utils.getInsetsTopWithoutActionBarHeight(getContext(), insets.top));
|
||||
final Context context = getContext();
|
||||
if (context instanceof FitSystemWindowsCallback) {
|
||||
((FitSystemWindowsCallback) context).fitSystemWindows(insets);
|
||||
}
|
||||
return super.fitSystemWindows(insets);
|
||||
}
|
||||
|
||||
private void updateAlpha() {
|
||||
|
|
|
@ -20,12 +20,9 @@
|
|||
package org.mariotaku.twidere.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v7.internal.view.menu.MenuPopupHelper;
|
||||
import android.support.v7.widget.ActionMenuView;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/1/22.
|
||||
*/
|
||||
|
|
|
@ -46,17 +46,8 @@ public class PressElevateViewHelper implements Animator.AnimatorListener {
|
|||
return mView.isPressed();
|
||||
}
|
||||
|
||||
public void updateButtonState() {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return;
|
||||
final boolean state = getState();
|
||||
final AnimatorRunnable runnable = new AnimatorRunnable(this, state);
|
||||
if (mCurrentAnimator != null) {
|
||||
mAnimatorRunnable = runnable;
|
||||
mCurrentAnimator = null;
|
||||
return;
|
||||
}
|
||||
runnable.run();
|
||||
mAnimatorRunnable = null;
|
||||
public View getView() {
|
||||
return mView;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -91,8 +82,17 @@ public class PressElevateViewHelper implements Animator.AnimatorListener {
|
|||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return;
|
||||
}
|
||||
|
||||
public View getView() {
|
||||
return mView;
|
||||
public void updateButtonState() {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return;
|
||||
final boolean state = getState();
|
||||
final AnimatorRunnable runnable = new AnimatorRunnable(this, state);
|
||||
if (mCurrentAnimator != null) {
|
||||
mAnimatorRunnable = runnable;
|
||||
mCurrentAnimator = null;
|
||||
return;
|
||||
}
|
||||
runnable.run();
|
||||
mAnimatorRunnable = null;
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
|
|
|
@ -50,11 +50,11 @@ public class AccountViewHolder {
|
|||
content.drawEnd(color);
|
||||
}
|
||||
|
||||
public void setSortEnabled(boolean enabled) {
|
||||
drag_handle.setVisibility(enabled ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
public void setIsDefault(final boolean is_default) {
|
||||
default_indicator.setVisibility(is_default ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
public void setSortEnabled(boolean enabled) {
|
||||
drag_handle.setVisibility(enabled ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -150,62 +150,6 @@ public class ActivityTitleSummaryViewHolder extends ViewHolder {
|
|||
}
|
||||
}
|
||||
|
||||
private Spanned getTitleStringAboutMe(int stringRes, int stringResMulti, ParcelableUser[] sources) {
|
||||
if (sources == null || sources.length == 0) return null;
|
||||
final Context context = adapter.getContext();
|
||||
final Resources resources = context.getResources();
|
||||
final Configuration configuration = resources.getConfiguration();
|
||||
final SpannableString firstDisplayName = new SpannableString(UserColorNameUtils.getDisplayName(context,
|
||||
sources[0]));
|
||||
firstDisplayName.setSpan(new StyleSpan(Typeface.BOLD), 0, firstDisplayName.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
if (sources.length == 1) {
|
||||
final String format = context.getString(stringRes);
|
||||
return SpanFormatter.format(configuration.locale, format, firstDisplayName);
|
||||
} else if (sources.length == 2) {
|
||||
final String format = context.getString(stringResMulti);
|
||||
final SpannableString secondDisplayName = new SpannableString(UserColorNameUtils.getDisplayName(context, sources[1]));
|
||||
secondDisplayName.setSpan(new StyleSpan(Typeface.BOLD), 0, secondDisplayName.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
return SpanFormatter.format(configuration.locale, format, firstDisplayName,
|
||||
secondDisplayName);
|
||||
} else {
|
||||
final int othersCount = sources.length - 1;
|
||||
final SpannableString nOthers = new SpannableString(resources.getQuantityString(R.plurals.N_others, othersCount, othersCount));
|
||||
nOthers.setSpan(new StyleSpan(Typeface.BOLD), 0, nOthers.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
final String format = context.getString(stringResMulti);
|
||||
return SpanFormatter.format(configuration.locale, format, firstDisplayName, nOthers);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Spanned getTitleStringByFriends(int stringRes, int stringResMulti, ParcelableUser[] sources, ParcelableUser[] targets) {
|
||||
if (sources == null || sources.length == 0) return null;
|
||||
final Context context = adapter.getContext();
|
||||
final Resources resources = context.getResources();
|
||||
final Configuration configuration = resources.getConfiguration();
|
||||
final SpannableString firstSourceName = new SpannableString(UserColorNameUtils.getDisplayName(context,
|
||||
sources[0]));
|
||||
firstSourceName.setSpan(new StyleSpan(Typeface.BOLD), 0, firstSourceName.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
final SpannableString firstTargetName = new SpannableString(UserColorNameUtils.getDisplayName(context,
|
||||
targets[0]));
|
||||
firstTargetName.setSpan(new StyleSpan(Typeface.BOLD), 0, firstTargetName.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
if (sources.length == 1) {
|
||||
final String format = context.getString(stringRes);
|
||||
return SpanFormatter.format(configuration.locale, format, firstSourceName, firstTargetName);
|
||||
} else if (sources.length == 2) {
|
||||
final String format = context.getString(stringResMulti);
|
||||
final SpannableString secondSourceName = new SpannableString(UserColorNameUtils.getDisplayName(context, sources[1]));
|
||||
secondSourceName.setSpan(new StyleSpan(Typeface.BOLD), 0, secondSourceName.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
return SpanFormatter.format(configuration.locale, format, firstSourceName,
|
||||
secondSourceName, firstTargetName);
|
||||
} else {
|
||||
final int othersCount = sources.length - 1;
|
||||
final SpannableString nOthers = new SpannableString(resources.getQuantityString(R.plurals.N_others, othersCount, othersCount));
|
||||
nOthers.setSpan(new StyleSpan(Typeface.BOLD), 0, nOthers.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
final String format = context.getString(stringResMulti);
|
||||
return SpanFormatter.format(configuration.locale, format, firstSourceName, nOthers, firstTargetName);
|
||||
}
|
||||
}
|
||||
|
||||
public void setTextSize(float textSize) {
|
||||
titleView.setTextSize(textSize);
|
||||
summaryView.setTextSize(textSize * 0.85f);
|
||||
|
@ -245,4 +189,59 @@ public class ActivityTitleSummaryViewHolder extends ViewHolder {
|
|||
}
|
||||
}
|
||||
|
||||
private Spanned getTitleStringAboutMe(int stringRes, int stringResMulti, ParcelableUser[] sources) {
|
||||
if (sources == null || sources.length == 0) return null;
|
||||
final Context context = adapter.getContext();
|
||||
final Resources resources = context.getResources();
|
||||
final Configuration configuration = resources.getConfiguration();
|
||||
final SpannableString firstDisplayName = new SpannableString(UserColorNameUtils.getDisplayName(context,
|
||||
sources[0]));
|
||||
firstDisplayName.setSpan(new StyleSpan(Typeface.BOLD), 0, firstDisplayName.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
if (sources.length == 1) {
|
||||
final String format = context.getString(stringRes);
|
||||
return SpanFormatter.format(configuration.locale, format, firstDisplayName);
|
||||
} else if (sources.length == 2) {
|
||||
final String format = context.getString(stringResMulti);
|
||||
final SpannableString secondDisplayName = new SpannableString(UserColorNameUtils.getDisplayName(context, sources[1]));
|
||||
secondDisplayName.setSpan(new StyleSpan(Typeface.BOLD), 0, secondDisplayName.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
return SpanFormatter.format(configuration.locale, format, firstDisplayName,
|
||||
secondDisplayName);
|
||||
} else {
|
||||
final int othersCount = sources.length - 1;
|
||||
final SpannableString nOthers = new SpannableString(resources.getQuantityString(R.plurals.N_others, othersCount, othersCount));
|
||||
nOthers.setSpan(new StyleSpan(Typeface.BOLD), 0, nOthers.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
final String format = context.getString(stringResMulti);
|
||||
return SpanFormatter.format(configuration.locale, format, firstDisplayName, nOthers);
|
||||
}
|
||||
}
|
||||
|
||||
private Spanned getTitleStringByFriends(int stringRes, int stringResMulti, ParcelableUser[] sources, ParcelableUser[] targets) {
|
||||
if (sources == null || sources.length == 0) return null;
|
||||
final Context context = adapter.getContext();
|
||||
final Resources resources = context.getResources();
|
||||
final Configuration configuration = resources.getConfiguration();
|
||||
final SpannableString firstSourceName = new SpannableString(UserColorNameUtils.getDisplayName(context,
|
||||
sources[0]));
|
||||
firstSourceName.setSpan(new StyleSpan(Typeface.BOLD), 0, firstSourceName.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
final SpannableString firstTargetName = new SpannableString(UserColorNameUtils.getDisplayName(context,
|
||||
targets[0]));
|
||||
firstTargetName.setSpan(new StyleSpan(Typeface.BOLD), 0, firstTargetName.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
if (sources.length == 1) {
|
||||
final String format = context.getString(stringRes);
|
||||
return SpanFormatter.format(configuration.locale, format, firstSourceName, firstTargetName);
|
||||
} else if (sources.length == 2) {
|
||||
final String format = context.getString(stringResMulti);
|
||||
final SpannableString secondSourceName = new SpannableString(UserColorNameUtils.getDisplayName(context, sources[1]));
|
||||
secondSourceName.setSpan(new StyleSpan(Typeface.BOLD), 0, secondSourceName.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
return SpanFormatter.format(configuration.locale, format, firstSourceName,
|
||||
secondSourceName, firstTargetName);
|
||||
} else {
|
||||
final int othersCount = sources.length - 1;
|
||||
final SpannableString nOthers = new SpannableString(resources.getQuantityString(R.plurals.N_others, othersCount, othersCount));
|
||||
nOthers.setSpan(new StyleSpan(Typeface.BOLD), 0, nOthers.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
final String format = context.getString(stringResMulti);
|
||||
return SpanFormatter.format(configuration.locale, format, firstSourceName, nOthers, firstTargetName);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,10 +24,10 @@ import android.widget.CheckBox;
|
|||
|
||||
public final class CheckableTwoLineWithIconViewHolder extends TwoLineWithIconViewHolder {
|
||||
|
||||
public final CheckBox checkbox;
|
||||
public final CheckBox checkbox;
|
||||
|
||||
public CheckableTwoLineWithIconViewHolder(final View view) {
|
||||
super(view);
|
||||
checkbox = (CheckBox) findViewById(android.R.id.checkbox);
|
||||
}
|
||||
public CheckableTwoLineWithIconViewHolder(final View view) {
|
||||
super(view);
|
||||
checkbox = (CheckBox) findViewById(android.R.id.checkbox);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,24 +28,24 @@ import org.mariotaku.twidere.view.iface.IColorLabelView;
|
|||
|
||||
public class DraftViewHolder extends ViewListHolder {
|
||||
|
||||
public final IColorLabelView content;
|
||||
public final TextView text;
|
||||
public final TextView time;
|
||||
public ImageView image_preview;
|
||||
public View image_preview_container;
|
||||
public final IColorLabelView content;
|
||||
public final TextView text;
|
||||
public final TextView time;
|
||||
public ImageView image_preview;
|
||||
public View image_preview_container;
|
||||
|
||||
public DraftViewHolder(final View view) {
|
||||
super(view);
|
||||
content = (IColorLabelView) findViewById(R.id.content);
|
||||
text = (TextView) findViewById(R.id.text);
|
||||
time = (TextView) findViewById(R.id.time);
|
||||
image_preview = (ImageView) findViewById(R.id.image_preview);
|
||||
image_preview_container = findViewById(R.id.image_preview_container);
|
||||
}
|
||||
public DraftViewHolder(final View view) {
|
||||
super(view);
|
||||
content = (IColorLabelView) findViewById(R.id.content);
|
||||
text = (TextView) findViewById(R.id.text);
|
||||
time = (TextView) findViewById(R.id.time);
|
||||
image_preview = (ImageView) findViewById(R.id.image_preview);
|
||||
image_preview_container = findViewById(R.id.image_preview_container);
|
||||
}
|
||||
|
||||
public void setTextSize(final float textSize) {
|
||||
text.setTextSize(textSize);
|
||||
time.setTextSize(textSize * 0.75f);
|
||||
}
|
||||
public void setTextSize(final float textSize) {
|
||||
text.setTextSize(textSize);
|
||||
time.setTextSize(textSize * 0.75f);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
package org.mariotaku.twidere.view.holder;
|
||||
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.RecyclerView.*;
|
||||
import android.view.View;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/11/19.
|
||||
*/
|
||||
* Created by mariotaku on 14/11/19.
|
||||
*/
|
||||
public class LoadIndicatorViewHolder extends RecyclerView.ViewHolder {
|
||||
public LoadIndicatorViewHolder(View view) {
|
||||
super(view);
|
||||
|
|
|
@ -30,7 +30,6 @@ import android.widget.TextView;
|
|||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.MessageEntriesAdapter;
|
||||
import org.mariotaku.twidere.fragment.support.DirectMessagesFragment;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages.ConversationEntries;
|
||||
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
||||
import org.mariotaku.twidere.view.ShortTimeView;
|
||||
|
@ -40,11 +39,10 @@ import static org.mariotaku.twidere.util.UserColorNameUtils.getUserNickname;
|
|||
|
||||
public class MessageEntryViewHolder extends ViewHolder implements OnClickListener {
|
||||
|
||||
private final MessageEntriesAdapter adapter;
|
||||
|
||||
public final ImageView profileImageView;
|
||||
public final TextView nameView, screenNameView, textView;
|
||||
public final ShortTimeView timeView;
|
||||
private final MessageEntriesAdapter adapter;
|
||||
private float text_size;
|
||||
private boolean account_color_enabled;
|
||||
|
||||
|
|
|
@ -84,43 +84,13 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
|
|||
// profileImageView.setSelectorColor(ThemeUtils.getUserHighlightColor(itemView.getContext()));
|
||||
}
|
||||
|
||||
public void setOnClickListeners() {
|
||||
setStatusClickListener(adapter);
|
||||
}
|
||||
|
||||
public static interface StatusClickListener extends ContentCardClickListener {
|
||||
|
||||
void onUserProfileClick(StatusViewHolder holder, int position);
|
||||
|
||||
void onStatusClick(StatusViewHolder holder, int position);
|
||||
}
|
||||
|
||||
public void setStatusClickListener(StatusClickListener listener) {
|
||||
statusClickListener = listener;
|
||||
itemView.findViewById(R.id.item_content).setOnClickListener(this);
|
||||
itemView.findViewById(R.id.item_menu).setOnClickListener(this);
|
||||
|
||||
itemView.setOnClickListener(this);
|
||||
profileImageView.setOnClickListener(this);
|
||||
mediaPreviewContainer.setOnClickListener(this);
|
||||
replyCountView.setOnClickListener(this);
|
||||
retweetCountView.setOnClickListener(this);
|
||||
favoriteCountView.setOnClickListener(this);
|
||||
}
|
||||
|
||||
public void setupViewOptions() {
|
||||
setTextSize(adapter.getTextSize());
|
||||
}
|
||||
|
||||
public void setTextSize(final float textSize) {
|
||||
nameView.setTextSize(textSize);
|
||||
textView.setTextSize(textSize);
|
||||
screenNameView.setTextSize(textSize * 0.85f);
|
||||
timeView.setTextSize(textSize * 0.85f);
|
||||
replyRetweetView.setTextSize(textSize * 0.75f);
|
||||
replyCountView.setTextSize(textSize);
|
||||
replyCountView.setTextSize(textSize);
|
||||
favoriteCountView.setTextSize(textSize);
|
||||
public void displaySampleStatus() {
|
||||
nameView.setText("User");
|
||||
screenNameView.setText("@user");
|
||||
timeView.setTime(System.currentTimeMillis());
|
||||
textView.setText(R.string.sample_status_text);
|
||||
mediaPreviewContainer.displayMedia(R.drawable.profile_image_nyan_sakamoto,
|
||||
R.drawable.profile_image_nyan_sakamoto_santa);
|
||||
}
|
||||
|
||||
public void displayStatus(final ParcelableStatus status, final boolean displayInReplyTo) {
|
||||
|
@ -245,25 +215,6 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
|
|||
displayExtraTypeIcon(status.card_name, status.media != null ? status.media.length : 0);
|
||||
}
|
||||
|
||||
private void displayExtraTypeIcon(String cardName, int mediaLength) {
|
||||
if (TwitterCardUtils.CARD_NAME_AUDIO.equals(cardName)) {
|
||||
extraTypeView.setImageResource(R.drawable.ic_action_music);
|
||||
extraTypeView.setVisibility(View.VISIBLE);
|
||||
} else if (TwitterCardUtils.CARD_NAME_ANIMATED_GIF.equals(cardName)) {
|
||||
extraTypeView.setImageResource(R.drawable.ic_action_movie);
|
||||
extraTypeView.setVisibility(View.VISIBLE);
|
||||
} else if (TwitterCardUtils.CARD_NAME_PLAYER.equals(cardName)) {
|
||||
extraTypeView.setImageResource(R.drawable.ic_action_play_circle);
|
||||
extraTypeView.setVisibility(View.VISIBLE);
|
||||
} else if (mediaLength > 0) {
|
||||
extraTypeView.setImageResource(R.drawable.ic_action_gallery);
|
||||
extraTypeView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
extraTypeView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void displayStatus(@NonNull Cursor cursor, @NonNull CursorIndices indices,
|
||||
final boolean displayInReplyTo) {
|
||||
final ImageLoaderWrapper loader = adapter.getImageLoader();
|
||||
|
@ -407,15 +358,6 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
|
|||
return profileTypeView;
|
||||
}
|
||||
|
||||
public void displaySampleStatus() {
|
||||
nameView.setText("User");
|
||||
screenNameView.setText("@user");
|
||||
timeView.setTime(System.currentTimeMillis());
|
||||
textView.setText(R.string.sample_status_text);
|
||||
mediaPreviewContainer.displayMedia(R.drawable.profile_image_nyan_sakamoto,
|
||||
R.drawable.profile_image_nyan_sakamoto_santa);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (statusClickListener == null) return;
|
||||
|
@ -441,4 +383,61 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements OnClick
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setOnClickListeners() {
|
||||
setStatusClickListener(adapter);
|
||||
}
|
||||
|
||||
public void setStatusClickListener(StatusClickListener listener) {
|
||||
statusClickListener = listener;
|
||||
itemView.findViewById(R.id.item_content).setOnClickListener(this);
|
||||
itemView.findViewById(R.id.item_menu).setOnClickListener(this);
|
||||
|
||||
itemView.setOnClickListener(this);
|
||||
profileImageView.setOnClickListener(this);
|
||||
mediaPreviewContainer.setOnClickListener(this);
|
||||
replyCountView.setOnClickListener(this);
|
||||
retweetCountView.setOnClickListener(this);
|
||||
favoriteCountView.setOnClickListener(this);
|
||||
}
|
||||
|
||||
public void setTextSize(final float textSize) {
|
||||
nameView.setTextSize(textSize);
|
||||
textView.setTextSize(textSize);
|
||||
screenNameView.setTextSize(textSize * 0.85f);
|
||||
timeView.setTextSize(textSize * 0.85f);
|
||||
replyRetweetView.setTextSize(textSize * 0.75f);
|
||||
replyCountView.setTextSize(textSize);
|
||||
replyCountView.setTextSize(textSize);
|
||||
favoriteCountView.setTextSize(textSize);
|
||||
}
|
||||
|
||||
public void setupViewOptions() {
|
||||
setTextSize(adapter.getTextSize());
|
||||
}
|
||||
|
||||
private void displayExtraTypeIcon(String cardName, int mediaLength) {
|
||||
if (TwitterCardUtils.CARD_NAME_AUDIO.equals(cardName)) {
|
||||
extraTypeView.setImageResource(R.drawable.ic_action_music);
|
||||
extraTypeView.setVisibility(View.VISIBLE);
|
||||
} else if (TwitterCardUtils.CARD_NAME_ANIMATED_GIF.equals(cardName)) {
|
||||
extraTypeView.setImageResource(R.drawable.ic_action_movie);
|
||||
extraTypeView.setVisibility(View.VISIBLE);
|
||||
} else if (TwitterCardUtils.CARD_NAME_PLAYER.equals(cardName)) {
|
||||
extraTypeView.setImageResource(R.drawable.ic_action_play_circle);
|
||||
extraTypeView.setVisibility(View.VISIBLE);
|
||||
} else if (mediaLength > 0) {
|
||||
extraTypeView.setImageResource(R.drawable.ic_action_gallery);
|
||||
extraTypeView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
extraTypeView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
public static interface StatusClickListener extends ContentCardClickListener {
|
||||
|
||||
void onStatusClick(StatusViewHolder holder, int position);
|
||||
|
||||
void onUserProfileClick(StatusViewHolder holder, int position);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,13 +25,13 @@ import android.widget.TextView;
|
|||
|
||||
public class TwoLineWithIconViewHolder extends ViewListHolder {
|
||||
|
||||
public final ImageView icon;
|
||||
public final TextView text1, text2;
|
||||
public final ImageView icon;
|
||||
public final TextView text1, text2;
|
||||
|
||||
public TwoLineWithIconViewHolder(final View view) {
|
||||
super(view);
|
||||
icon = (ImageView) findViewById(android.R.id.icon);
|
||||
text1 = (TextView) findViewById(android.R.id.text1);
|
||||
text2 = (TextView) findViewById(android.R.id.text2);
|
||||
}
|
||||
public TwoLineWithIconViewHolder(final View view) {
|
||||
super(view);
|
||||
icon = (ImageView) findViewById(android.R.id.icon);
|
||||
text1 = (TextView) findViewById(android.R.id.text1);
|
||||
text2 = (TextView) findViewById(android.R.id.text2);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,8 +31,8 @@ public class UserListViewListHolder extends ViewListHolder {
|
|||
public final IColorLabelView content;
|
||||
public final ImageView profile_image;
|
||||
public final TextView name, description, created_by, members_count, subscribers_count;
|
||||
private float text_size;
|
||||
public int position;
|
||||
private float text_size;
|
||||
|
||||
public UserListViewListHolder(final View view) {
|
||||
super(view);
|
||||
|
|
|
@ -30,58 +30,58 @@ import org.mariotaku.twidere.view.iface.IColorLabelView;
|
|||
public class UserViewListHolder extends ViewListHolder {
|
||||
|
||||
public final IColorLabelView content;
|
||||
public final ImageView profile_image, profile_type;
|
||||
public final TextView name, screen_name, description, location, url, statuses_count, followers_count,
|
||||
friends_count;
|
||||
private boolean account_color_enabled;
|
||||
private float text_size;
|
||||
public int position;
|
||||
public final ImageView profile_image, profile_type;
|
||||
public final TextView name, screen_name, description, location, url, statuses_count, followers_count,
|
||||
friends_count;
|
||||
public int position;
|
||||
private boolean account_color_enabled;
|
||||
private float text_size;
|
||||
|
||||
public UserViewListHolder(final View view) {
|
||||
super(view);
|
||||
public UserViewListHolder(final View view) {
|
||||
super(view);
|
||||
content = (IColorLabelView) view.findViewById(R.id.content);
|
||||
profile_image = (ImageView) findViewById(R.id.profile_image);
|
||||
profile_image = (ImageView) findViewById(R.id.profile_image);
|
||||
profile_type = (ImageView) findViewById(R.id.profile_type);
|
||||
name = (TextView) findViewById(R.id.name);
|
||||
screen_name = (TextView) findViewById(R.id.screen_name);
|
||||
description = (TextView) findViewById(R.id.description);
|
||||
location = (TextView) findViewById(R.id.location);
|
||||
url = (TextView) findViewById(R.id.url);
|
||||
statuses_count = (TextView) findViewById(R.id.statuses_count);
|
||||
followers_count = (TextView) findViewById(R.id.followers_count);
|
||||
friends_count = (TextView) findViewById(R.id.friends_count);
|
||||
}
|
||||
name = (TextView) findViewById(R.id.name);
|
||||
screen_name = (TextView) findViewById(R.id.screen_name);
|
||||
description = (TextView) findViewById(R.id.description);
|
||||
location = (TextView) findViewById(R.id.location);
|
||||
url = (TextView) findViewById(R.id.url);
|
||||
statuses_count = (TextView) findViewById(R.id.statuses_count);
|
||||
followers_count = (TextView) findViewById(R.id.followers_count);
|
||||
friends_count = (TextView) findViewById(R.id.friends_count);
|
||||
}
|
||||
|
||||
public void setAccountColor(final int color) {
|
||||
content.drawEnd(account_color_enabled ? color : Color.TRANSPARENT);
|
||||
}
|
||||
public void setAccountColor(final int color) {
|
||||
content.drawEnd(account_color_enabled ? color : Color.TRANSPARENT);
|
||||
}
|
||||
|
||||
public void setAccountColorEnabled(final boolean enabled) {
|
||||
account_color_enabled = enabled;
|
||||
if (!account_color_enabled) {
|
||||
content.drawEnd(Color.TRANSPARENT);
|
||||
}
|
||||
}
|
||||
public void setAccountColorEnabled(final boolean enabled) {
|
||||
account_color_enabled = enabled;
|
||||
if (!account_color_enabled) {
|
||||
content.drawEnd(Color.TRANSPARENT);
|
||||
}
|
||||
}
|
||||
|
||||
public void setHighlightColor(final int color) {
|
||||
content.drawBackground(color);
|
||||
}
|
||||
public void setHighlightColor(final int color) {
|
||||
content.drawBackground(color);
|
||||
}
|
||||
|
||||
public void setTextSize(final float text_size) {
|
||||
if (this.text_size == text_size) return;
|
||||
this.text_size = text_size;
|
||||
description.setTextSize(text_size);
|
||||
name.setTextSize(text_size);
|
||||
screen_name.setTextSize(text_size * 0.75f);
|
||||
location.setTextSize(text_size);
|
||||
url.setTextSize(text_size);
|
||||
statuses_count.setTextSize(text_size);
|
||||
followers_count.setTextSize(text_size);
|
||||
friends_count.setTextSize(text_size);
|
||||
}
|
||||
public void setTextSize(final float text_size) {
|
||||
if (this.text_size == text_size) return;
|
||||
this.text_size = text_size;
|
||||
description.setTextSize(text_size);
|
||||
name.setTextSize(text_size);
|
||||
screen_name.setTextSize(text_size * 0.75f);
|
||||
location.setTextSize(text_size);
|
||||
url.setTextSize(text_size);
|
||||
statuses_count.setTextSize(text_size);
|
||||
followers_count.setTextSize(text_size);
|
||||
friends_count.setTextSize(text_size);
|
||||
}
|
||||
|
||||
public void setUserColor(final int color) {
|
||||
content.drawStart(color);
|
||||
}
|
||||
public void setUserColor(final int color) {
|
||||
content.drawStart(color);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,23 +26,23 @@ import org.mariotaku.twidere.Constants;
|
|||
|
||||
public class ViewListHolder implements Constants {
|
||||
|
||||
public View view;
|
||||
public View view;
|
||||
|
||||
public ViewListHolder(final View view) {
|
||||
if (view == null) throw new NullPointerException();
|
||||
this.view = view;
|
||||
}
|
||||
public ViewListHolder(final View view) {
|
||||
if (view == null) throw new NullPointerException();
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
public View findViewById(final int id) {
|
||||
return view.findViewById(id);
|
||||
}
|
||||
public View findViewById(final int id) {
|
||||
return view.findViewById(id);
|
||||
}
|
||||
|
||||
public Context getContext() {
|
||||
return view.getContext();
|
||||
}
|
||||
public Context getContext() {
|
||||
return view.getContext();
|
||||
}
|
||||
|
||||
protected String getString(final int resId, final Object... formatArgs) {
|
||||
return getContext().getString(resId, formatArgs);
|
||||
}
|
||||
protected String getString(final int resId, final Object... formatArgs) {
|
||||
return getContext().getString(resId, formatArgs);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,8 +19,6 @@
|
|||
|
||||
package org.mariotaku.twidere.view.iface;
|
||||
|
||||
import static org.mariotaku.twidere.util.Utils.isRTL;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
|
@ -31,134 +29,136 @@ import android.view.View;
|
|||
|
||||
import org.mariotaku.twidere.R;
|
||||
|
||||
import static org.mariotaku.twidere.util.Utils.isRTL;
|
||||
|
||||
public interface IColorLabelView {
|
||||
|
||||
public static final float LABEL_WIDTH = 3.5f;
|
||||
public static final float LABEL_WIDTH = 3.5f;
|
||||
|
||||
public void drawBackground(final int color);
|
||||
public void drawBackground(final int color);
|
||||
|
||||
public void drawBottom(final int... colors);
|
||||
public void drawBottom(final int... colors);
|
||||
|
||||
public void drawEnd(final int... colors);
|
||||
public void drawEnd(final int... colors);
|
||||
|
||||
public void drawLabel(final int[] start, final int[] end, int[] top, int[] bottom, final int background);
|
||||
public void drawLabel(final int[] start, final int[] end, int[] top, int[] bottom, final int background);
|
||||
|
||||
public void drawStart(final int... colors);
|
||||
public void drawStart(final int... colors);
|
||||
|
||||
public void drawTop(final int... colors);
|
||||
public void drawTop(final int... colors);
|
||||
|
||||
public boolean isPaddingsIgnored();
|
||||
public boolean isPaddingsIgnored();
|
||||
|
||||
public void setIgnorePaddings(final boolean ignorePaddings);
|
||||
public void setIgnorePaddings(final boolean ignorePaddings);
|
||||
|
||||
public void setVisibility(int visibility);
|
||||
public void setVisibility(int visibility);
|
||||
|
||||
public static final class Helper {
|
||||
public static final class Helper {
|
||||
|
||||
private final View mView;
|
||||
private final View mView;
|
||||
|
||||
private final Paint mPaint = new Paint();
|
||||
private final float mDensity;
|
||||
private final boolean mIsRTL;
|
||||
private final Paint mPaint = new Paint();
|
||||
private final float mDensity;
|
||||
private final boolean mIsRTL;
|
||||
|
||||
private int mBackgroundColor;
|
||||
private int[] mStartColors, mEndColors, mTopColors, mBottomColors;
|
||||
private int mBackgroundColor;
|
||||
private int[] mStartColors, mEndColors, mTopColors, mBottomColors;
|
||||
|
||||
private boolean mIgnorePadding;
|
||||
private boolean mIgnorePadding;
|
||||
|
||||
public Helper(final View view, final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
mView = view;
|
||||
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Twidere);
|
||||
mIgnorePadding = a.getBoolean(R.styleable.Twidere_ignorePadding, false);
|
||||
a.recycle();
|
||||
final Resources res = context.getResources();
|
||||
mDensity = res.getDisplayMetrics().density;
|
||||
mIsRTL = isRTL(context);
|
||||
}
|
||||
public Helper(final View view, final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
mView = view;
|
||||
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Twidere);
|
||||
mIgnorePadding = a.getBoolean(R.styleable.Twidere_ignorePadding, false);
|
||||
a.recycle();
|
||||
final Resources res = context.getResources();
|
||||
mDensity = res.getDisplayMetrics().density;
|
||||
mIsRTL = isRTL(context);
|
||||
}
|
||||
|
||||
public void dispatchDrawBackground(final Canvas canvas) {
|
||||
final int left = mIgnorePadding ? 0 : mView.getPaddingLeft();
|
||||
final int top = mIgnorePadding ? 0 : mView.getPaddingTop();
|
||||
final int right = mIgnorePadding ? mView.getWidth() : mView.getWidth() - mView.getPaddingRight();
|
||||
final int bottom = mIgnorePadding ? mView.getHeight() : mView.getHeight() - mView.getPaddingBottom();
|
||||
mPaint.setColor(mBackgroundColor);
|
||||
canvas.drawRect(left, top, right, bottom, mPaint);
|
||||
}
|
||||
public void dispatchDrawBackground(final Canvas canvas) {
|
||||
final int left = mIgnorePadding ? 0 : mView.getPaddingLeft();
|
||||
final int top = mIgnorePadding ? 0 : mView.getPaddingTop();
|
||||
final int right = mIgnorePadding ? mView.getWidth() : mView.getWidth() - mView.getPaddingRight();
|
||||
final int bottom = mIgnorePadding ? mView.getHeight() : mView.getHeight() - mView.getPaddingBottom();
|
||||
mPaint.setColor(mBackgroundColor);
|
||||
canvas.drawRect(left, top, right, bottom, mPaint);
|
||||
}
|
||||
|
||||
public void dispatchDrawLabels(final Canvas canvas) {
|
||||
final int left = mIgnorePadding ? 0 : mView.getPaddingLeft();
|
||||
final int top = mIgnorePadding ? 0 : mView.getPaddingTop();
|
||||
final int right = mIgnorePadding ? mView.getWidth() : mView.getWidth() - mView.getPaddingRight();
|
||||
final int bottom = mIgnorePadding ? mView.getHeight() : mView.getHeight() - mView.getPaddingBottom();
|
||||
final int labelWidth = Math.round(mDensity * LABEL_WIDTH);
|
||||
final int[] leftColors = mIsRTL ? mEndColors : mStartColors;
|
||||
final int[] rightColors = mIsRTL ? mStartColors : mEndColors;
|
||||
drawColorsHorizontally(canvas, mTopColors, left, top, right - left, labelWidth);
|
||||
drawColorsHorizontally(canvas, mBottomColors, left, bottom - labelWidth, right - left, labelWidth);
|
||||
drawColorsVertically(canvas, leftColors, left, top, labelWidth, bottom - top);
|
||||
drawColorsVertically(canvas, rightColors, right - labelWidth, top, labelWidth, bottom - top);
|
||||
}
|
||||
public void dispatchDrawLabels(final Canvas canvas) {
|
||||
final int left = mIgnorePadding ? 0 : mView.getPaddingLeft();
|
||||
final int top = mIgnorePadding ? 0 : mView.getPaddingTop();
|
||||
final int right = mIgnorePadding ? mView.getWidth() : mView.getWidth() - mView.getPaddingRight();
|
||||
final int bottom = mIgnorePadding ? mView.getHeight() : mView.getHeight() - mView.getPaddingBottom();
|
||||
final int labelWidth = Math.round(mDensity * LABEL_WIDTH);
|
||||
final int[] leftColors = mIsRTL ? mEndColors : mStartColors;
|
||||
final int[] rightColors = mIsRTL ? mStartColors : mEndColors;
|
||||
drawColorsHorizontally(canvas, mTopColors, left, top, right - left, labelWidth);
|
||||
drawColorsHorizontally(canvas, mBottomColors, left, bottom - labelWidth, right - left, labelWidth);
|
||||
drawColorsVertically(canvas, leftColors, left, top, labelWidth, bottom - top);
|
||||
drawColorsVertically(canvas, rightColors, right - labelWidth, top, labelWidth, bottom - top);
|
||||
}
|
||||
|
||||
public void drawBackground(final int color) {
|
||||
drawLabel(mStartColors, mEndColors, mTopColors, mBottomColors, color);
|
||||
}
|
||||
public void drawBackground(final int color) {
|
||||
drawLabel(mStartColors, mEndColors, mTopColors, mBottomColors, color);
|
||||
}
|
||||
|
||||
public void drawBottom(final int[] colors) {
|
||||
drawLabel(mStartColors, mEndColors, mTopColors, colors, mBackgroundColor);
|
||||
}
|
||||
public void drawBottom(final int[] colors) {
|
||||
drawLabel(mStartColors, mEndColors, mTopColors, colors, mBackgroundColor);
|
||||
}
|
||||
|
||||
public void drawEnd(final int[] colors) {
|
||||
drawLabel(mStartColors, colors, mTopColors, mBottomColors, mBackgroundColor);
|
||||
}
|
||||
public void drawEnd(final int[] colors) {
|
||||
drawLabel(mStartColors, colors, mTopColors, mBottomColors, mBackgroundColor);
|
||||
}
|
||||
|
||||
public void drawLabel(final int[] start, final int[] end, final int[] top, final int[] bottom,
|
||||
final int background) {
|
||||
mStartColors = start;
|
||||
mEndColors = end;
|
||||
mTopColors = top;
|
||||
mBottomColors = bottom;
|
||||
mBackgroundColor = background;
|
||||
mView.invalidate();
|
||||
}
|
||||
public void drawLabel(final int[] start, final int[] end, final int[] top, final int[] bottom,
|
||||
final int background) {
|
||||
mStartColors = start;
|
||||
mEndColors = end;
|
||||
mTopColors = top;
|
||||
mBottomColors = bottom;
|
||||
mBackgroundColor = background;
|
||||
mView.invalidate();
|
||||
}
|
||||
|
||||
public void drawStart(final int[] colors) {
|
||||
drawLabel(colors, mEndColors, mTopColors, mBottomColors, mBackgroundColor);
|
||||
}
|
||||
public void drawStart(final int[] colors) {
|
||||
drawLabel(colors, mEndColors, mTopColors, mBottomColors, mBackgroundColor);
|
||||
}
|
||||
|
||||
public void drawTop(final int[] colors) {
|
||||
drawLabel(mStartColors, mEndColors, colors, mBottomColors, mBackgroundColor);
|
||||
}
|
||||
public void drawTop(final int[] colors) {
|
||||
drawLabel(mStartColors, mEndColors, colors, mBottomColors, mBackgroundColor);
|
||||
}
|
||||
|
||||
public boolean isPaddingsIgnored() {
|
||||
return mIgnorePadding;
|
||||
}
|
||||
public boolean isPaddingsIgnored() {
|
||||
return mIgnorePadding;
|
||||
}
|
||||
|
||||
public void setIgnorePaddings(final boolean ignorePaddings) {
|
||||
mIgnorePadding = ignorePaddings;
|
||||
mView.invalidate();
|
||||
}
|
||||
public void setIgnorePaddings(final boolean ignorePaddings) {
|
||||
mIgnorePadding = ignorePaddings;
|
||||
mView.invalidate();
|
||||
}
|
||||
|
||||
private void drawColorsHorizontally(final Canvas canvas, final int[] colors, final int left, final int top,
|
||||
final int width, final int height) {
|
||||
if (colors == null || colors.length == 0) return;
|
||||
for (int i = 0, len = colors.length; i < len; i++) {
|
||||
mPaint.setColor(colors[i]);
|
||||
final float colorLeft = left + i * (width / len);
|
||||
final float colorRight = left + (i + 1) * (width / len);
|
||||
canvas.drawRect(colorLeft, top, colorRight, top + height, mPaint);
|
||||
}
|
||||
}
|
||||
private void drawColorsHorizontally(final Canvas canvas, final int[] colors, final int left, final int top,
|
||||
final int width, final int height) {
|
||||
if (colors == null || colors.length == 0) return;
|
||||
for (int i = 0, len = colors.length; i < len; i++) {
|
||||
mPaint.setColor(colors[i]);
|
||||
final float colorLeft = left + i * (width / len);
|
||||
final float colorRight = left + (i + 1) * (width / len);
|
||||
canvas.drawRect(colorLeft, top, colorRight, top + height, mPaint);
|
||||
}
|
||||
}
|
||||
|
||||
private void drawColorsVertically(final Canvas canvas, final int[] colors, final int left, final int top,
|
||||
final int width, final int height) {
|
||||
if (colors == null || colors.length == 0) return;
|
||||
for (int i = 0, len = colors.length; i < len; i++) {
|
||||
mPaint.setColor(colors[i]);
|
||||
final float colorTop = top + i * (height / len);
|
||||
final float colorBottom = top + (i + 1) * (height / len);
|
||||
canvas.drawRect(left, colorTop, left + width, colorBottom, mPaint);
|
||||
}
|
||||
}
|
||||
private void drawColorsVertically(final Canvas canvas, final int[] colors, final int left, final int top,
|
||||
final int width, final int height) {
|
||||
if (colors == null || colors.length == 0) return;
|
||||
for (int i = 0, len = colors.length; i < len; i++) {
|
||||
mPaint.setColor(colors[i]);
|
||||
final float colorTop = top + i * (height / len);
|
||||
final float colorBottom = top + (i + 1) * (height / len);
|
||||
canvas.drawRect(left, colorTop, left + width, colorBottom, mPaint);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,26 +19,33 @@
|
|||
|
||||
package org.mariotaku.twidere.view.iface;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
public interface IExtendedView {
|
||||
|
||||
public void setOnSizeChangedListener(final OnSizeChangedListener listener);
|
||||
public void setOnFitSystemWindowsListener(final OnFitSystemWindowsListener listener);
|
||||
|
||||
public void setTouchInterceptor(final TouchInterceptor listener);
|
||||
public void setOnSizeChangedListener(final OnSizeChangedListener listener);
|
||||
|
||||
public static interface OnSizeChangedListener {
|
||||
void onSizeChanged(View view, int w, int h, int oldw, int oldh);
|
||||
}
|
||||
public void setTouchInterceptor(final TouchInterceptor listener);
|
||||
|
||||
public static interface TouchInterceptor {
|
||||
public static interface OnFitSystemWindowsListener {
|
||||
void onFitSystemWindows(Rect insets);
|
||||
}
|
||||
|
||||
boolean dispatchTouchEvent(View view, MotionEvent event);
|
||||
public static interface OnSizeChangedListener {
|
||||
void onSizeChanged(View view, int w, int h, int oldw, int oldh);
|
||||
}
|
||||
|
||||
boolean onInterceptTouchEvent(View view, MotionEvent event);
|
||||
public static interface TouchInterceptor {
|
||||
|
||||
boolean onTouchEvent(View view, MotionEvent event);
|
||||
boolean dispatchTouchEvent(View view, MotionEvent event);
|
||||
|
||||
}
|
||||
boolean onInterceptTouchEvent(View view, MotionEvent event);
|
||||
|
||||
boolean onTouchEvent(View view, MotionEvent event);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,6 +90,11 @@ public interface IForegroundView {
|
|||
a.recycle();
|
||||
}
|
||||
|
||||
public void dispatchDrawableHotspotChanged(float x, float y) {
|
||||
if (mForeground == null) return;
|
||||
DrawableCompat.setHotspot(mForeground, x, y);
|
||||
}
|
||||
|
||||
public void dispatchOnDraw(final Canvas canvas) {
|
||||
if (mForeground != null) {
|
||||
final Drawable foreground = mForeground;
|
||||
|
@ -167,12 +172,6 @@ public interface IForegroundView {
|
|||
return mForeground;
|
||||
}
|
||||
|
||||
public void jumpDrawablesToCurrentState() {
|
||||
if (mForeground != null) {
|
||||
mForeground.jumpToCurrentState();
|
||||
}
|
||||
}
|
||||
|
||||
public void setForeground(final Drawable drawable) {
|
||||
if (mForeground != drawable) {
|
||||
if (mForeground != null) {
|
||||
|
@ -198,6 +197,12 @@ public interface IForegroundView {
|
|||
}
|
||||
}
|
||||
|
||||
public void jumpDrawablesToCurrentState() {
|
||||
if (mForeground != null) {
|
||||
mForeground.jumpToCurrentState();
|
||||
}
|
||||
}
|
||||
|
||||
public void setForegroundGravity(int foregroundGravity) {
|
||||
if (mForegroundGravity != foregroundGravity) {
|
||||
if ((foregroundGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) == 0) {
|
||||
|
@ -224,10 +229,5 @@ public interface IForegroundView {
|
|||
public boolean verifyDrawable(final Drawable who) {
|
||||
return who == mForeground;
|
||||
}
|
||||
|
||||
public void dispatchDrawableHotspotChanged(float x, float y) {
|
||||
if (mForeground == null) return;
|
||||
DrawableCompat.setHotspot(mForeground, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,14 +10,14 @@ import android.graphics.drawable.Drawable;
|
|||
public interface IHomeActionButton {
|
||||
void setButtonColor(int color);
|
||||
|
||||
void setIconColor(int color, PorterDuff.Mode mode);
|
||||
|
||||
void setIcon(Bitmap bm);
|
||||
|
||||
void setIcon(Drawable drawable);
|
||||
|
||||
void setIcon(int resId);
|
||||
|
||||
void setIconColor(int color, PorterDuff.Mode mode);
|
||||
|
||||
void setShowProgress(boolean showProgress);
|
||||
|
||||
void setTitle(CharSequence title);
|
||||
|
|
|
@ -25,46 +25,55 @@ import android.support.v4.view.ViewPager;
|
|||
* number and the current visible view.
|
||||
*/
|
||||
public interface PagerIndicator extends ViewPager.OnPageChangeListener {
|
||||
/**
|
||||
* Notify the indicator that the fragment list has changed.
|
||||
*/
|
||||
void notifyDataSetChanged();
|
||||
/**
|
||||
* Notify the indicator that the fragment list has changed.
|
||||
*/
|
||||
void notifyDataSetChanged();
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Set the current page of both the ViewPager and indicator.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* This <strong>must</strong> be used if you need to set the page before the
|
||||
* views are drawn on screen (e.g., default start page).
|
||||
* </p>
|
||||
*
|
||||
* @param item
|
||||
*/
|
||||
void setCurrentItem(int item);
|
||||
/**
|
||||
* <p>
|
||||
* Set the current page of both the ViewPager and indicator.
|
||||
* </p>
|
||||
* <p/>
|
||||
* <p>
|
||||
* This <strong>must</strong> be used if you need to set the page before the
|
||||
* views are drawn on screen (e.g., default start page).
|
||||
* </p>
|
||||
*
|
||||
* @param item
|
||||
*/
|
||||
void setCurrentItem(int item);
|
||||
|
||||
/**
|
||||
* Set a page change listener which will receive forwarded events.
|
||||
*
|
||||
* @param listener
|
||||
*/
|
||||
void setOnPageChangeListener(ViewPager.OnPageChangeListener listener);
|
||||
/**
|
||||
* Set a page change listener which will receive forwarded events.
|
||||
*
|
||||
* @param listener
|
||||
*/
|
||||
void setOnPageChangeListener(ViewPager.OnPageChangeListener listener);
|
||||
|
||||
/**
|
||||
* Bind the indicator to a ViewPager.
|
||||
*
|
||||
* @param view
|
||||
*/
|
||||
void setViewPager(ViewPager view);
|
||||
/**
|
||||
* Bind the indicator to a ViewPager.
|
||||
*
|
||||
* @param view
|
||||
*/
|
||||
void setViewPager(ViewPager view);
|
||||
|
||||
/**
|
||||
* Bind the indicator to a ViewPager.
|
||||
*
|
||||
* @param view
|
||||
* @param initialPosition
|
||||
*/
|
||||
void setViewPager(ViewPager view, int initialPosition);
|
||||
/**
|
||||
* Bind the indicator to a ViewPager.
|
||||
*
|
||||
* @param view
|
||||
* @param initialPosition
|
||||
*/
|
||||
void setViewPager(ViewPager view, int initialPosition);
|
||||
|
||||
interface TabListener {
|
||||
|
||||
public void onPageReselected(int position);
|
||||
|
||||
public void onPageSelected(int position);
|
||||
|
||||
public boolean onTabLongClick(int position);
|
||||
}
|
||||
|
||||
/**
|
||||
* A TitleProvider provides the title to display according to a view.
|
||||
|
@ -91,13 +100,4 @@ public interface PagerIndicator extends ViewPager.OnPageChangeListener {
|
|||
|
||||
public float getPageWidth(int position);
|
||||
}
|
||||
|
||||
interface TabListener {
|
||||
|
||||
public void onPageReselected(int position);
|
||||
|
||||
public void onPageSelected(int position);
|
||||
|
||||
public boolean onTabLongClick(int position);
|
||||
}
|
||||
}
|
|
@ -27,17 +27,17 @@ import org.mariotaku.twidere.util.ThemeUtils;
|
|||
|
||||
public class ThemedCheckBox extends CheckBox {
|
||||
|
||||
public ThemedCheckBox(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
public ThemedCheckBox(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public ThemedCheckBox(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, android.R.attr.checkboxStyle);
|
||||
}
|
||||
public ThemedCheckBox(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, android.R.attr.checkboxStyle);
|
||||
}
|
||||
|
||||
public ThemedCheckBox(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
public ThemedCheckBox(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
ThemeUtils.initTextView(this);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -30,18 +30,18 @@ import org.mariotaku.twidere.view.iface.IThemedView;
|
|||
|
||||
public class ThemedEditText extends EditText implements IThemedView {
|
||||
|
||||
public ThemedEditText(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
public ThemedEditText(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public ThemedEditText(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, android.R.attr.editTextStyle);
|
||||
}
|
||||
public ThemedEditText(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, android.R.attr.editTextStyle);
|
||||
}
|
||||
|
||||
public ThemedEditText(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
public ThemedEditText(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
ThemeUtils.initTextView(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setThemeTintColor(ColorStateList color) {
|
||||
|
|
|
@ -23,7 +23,6 @@ import android.content.Context;
|
|||
import android.content.res.ColorStateList;
|
||||
import android.os.Build;
|
||||
import android.support.v4.graphics.drawable.DrawableCompat;
|
||||
import android.support.v7.widget.SwitchCompat;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.Switch;
|
||||
|
||||
|
|
|
@ -22,10 +22,15 @@
|
|||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:id="@+id/compose_activity"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="@dimen/compose_min_width"
|
||||
android:orientation="vertical">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/compose_actionbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?actionBarSize"/>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/compose_content"
|
||||
|
@ -80,6 +85,7 @@
|
|||
|
||||
<org.mariotaku.twidere.view.ActionIconView
|
||||
android:layout_width="@dimen/element_size_small"
|
||||
android:id="@+id/location_icon"
|
||||
android:layout_height="@dimen/element_size_small"
|
||||
android:layout_marginLeft="@dimen/element_spacing_normal"
|
||||
android:layout_marginRight="@dimen/element_spacing_normal"
|
||||
|
|
|
@ -19,8 +19,17 @@
|
|||
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<merge xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
</merge>
|
||||
<EditText
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:inputType="text"
|
||||
android:minLines="10"
|
||||
android:singleLine="false"/>
|
||||
|
||||
</RelativeLayout>
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
|
@ -53,7 +54,9 @@
|
|||
android:layout_width="@dimen/icon_size_profile_image_dashboard_current"
|
||||
android:layout_height="@dimen/icon_size_profile_image_dashboard_current"
|
||||
android:layout_marginBottom="@dimen/element_spacing_mlarge"
|
||||
android:layout_marginTop="@dimen/element_spacing_mlarge"/>
|
||||
android:layout_marginTop="@dimen/element_spacing_mlarge"
|
||||
app:sivBorder="true"
|
||||
app:sivBorderWidth="2dp"/>
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/other_accounts_list"
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
android:icon="@drawable/ic_action_reply"
|
||||
android:title="@string/original_status"
|
||||
android:visible="false"
|
||||
app:showAsAction="ifRoom"/>
|
||||
app:showAsAction="always"/>
|
||||
<item
|
||||
android:id="@id/add_location"
|
||||
android:checkable="true"
|
||||
|
|
|
@ -185,30 +185,29 @@
|
|||
|
||||
<style name="Theme.Twidere.Dark.Compose">
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowActionModeOverlay">false</item>
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<item name="android:windowActionBar">false</item>
|
||||
<item name="android:windowBackground">@drawable/dialog_full_holo_dark</item>
|
||||
<item name="android:windowIsFloating">true</item>
|
||||
<item name="android:windowContentOverlay">@null</item>
|
||||
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
|
||||
<item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
|
||||
<item name="android:windowActionModeOverlay">true</item>
|
||||
<item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
|
||||
<item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Twidere.Light.Compose">
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowActionModeOverlay">false</item>
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<item name="android:windowActionBar">false</item>
|
||||
<item name="android:windowBackground">@drawable/dialog_full_holo_light</item>
|
||||
<item name="android:windowIsFloating">true</item>
|
||||
<item name="android:windowContentOverlay">@null</item>
|
||||
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
|
||||
<item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
|
||||
<item name="android:windowActionModeOverlay">true</item>
|
||||
<item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
|
||||
<item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
|
||||
|
||||
</style>
|
||||
|
||||
<style name="Theme.Twidere.Light.QuickSearchBar" parent="Theme.Twidere.Light.Dialog">
|
||||
|
|
Loading…
Reference in New Issue