started to use material colors instead of holo colors

added colored (tinted) status bar for KitKat and above
removed crouton library completely
This commit is contained in:
Mariotaku Lee 2014-11-27 00:22:40 +08:00
parent 2f679124b0
commit 8feedc3469
35 changed files with 1016 additions and 2953 deletions

View File

@ -1,847 +0,0 @@
/*
* Copyright 2012 - 2013 Benjamin Weiss
* Copyright 2012 Neofonie Mobile GmbH
*
* 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 de.keyboardsurfer.android.widget.crouton;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Shader;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.util.TypedValue;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import org.mariotaku.twidere.util.accessor.ViewAccessor;
/*
* Based on an article by Cyril Mottier (http://android.cyrilmottier.com/?p=773) <br>
*/
/**
* Displays information in a non-invasive context related manner. Like
* {@link android.widget.Toast}, but better.
* <p/>
* <b>Important: </b> Call {@link Crouton#clearCroutonsForActivity(Activity)}
* within {@link android.app.Activity#onDestroy()} to avoid {@link Context}
* leaks.
*/
public final class Crouton {
private static final int IMAGE_ID = 0x100;
private static final int TEXT_ID = 0x101;
private final CharSequence text;
private final CroutonStyle style;
private CroutonConfiguration configuration = null;
private final View customView;
private OnClickListener onClickListener;
private Activity activity;
private ViewGroup viewGroup;
private FrameLayout croutonView;
private Animation inAnimation;
private Animation outAnimation;
private CroutonLifecycleCallback lifecycleCallback = null;
/**
* Creates the {@link Crouton}.
*
* @param activity The {@link Activity} that the {@link Crouton} should be
* attached to.
* @param text The text you want to display.
* @param style The style that this {@link Crouton} should be created with.
*/
private Crouton(final Activity activity, final CharSequence text, final CroutonStyle style) {
if (activity == null || text == null || style == null)
throw new IllegalArgumentException("Null parameters are not accepted");
this.activity = activity;
viewGroup = null;
this.text = text;
this.style = style;
customView = null;
}
/**
* Creates the {@link Crouton}.
*
* @param activity The {@link Activity} that represents the context in which
* the Crouton should exist.
* @param text The text you want to display.
* @param style The style that this {@link Crouton} should be created with.
* @param viewGroup The {@link ViewGroup} that this {@link Crouton} should
* be added to.
*/
private Crouton(final Activity activity, final CharSequence text, final CroutonStyle style,
final ViewGroup viewGroup) {
if (activity == null || text == null || style == null)
throw new IllegalArgumentException("Null parameters are not accepted");
this.activity = activity;
this.text = text;
this.style = style;
this.viewGroup = viewGroup;
customView = null;
}
/**
* Creates the {@link Crouton}.
*
* @param activity The {@link Activity} that the {@link Crouton} should be
* attached to.
* @param customView The custom {@link View} to display
*/
private Crouton(final Activity activity, final View customView) {
if (activity == null || customView == null)
throw new IllegalArgumentException("Null parameters are not accepted");
this.activity = activity;
viewGroup = null;
this.customView = customView;
style = new CroutonStyle.Builder().build();
text = null;
}
/**
* Creates the {@link Crouton}.
*
* @param activity The {@link Activity} that represents the context in which
* the Crouton should exist.
* @param customView The custom {@link View} to display
* @param viewGroup The {@link ViewGroup} that this {@link Crouton} should
* be added to.
*/
private Crouton(final Activity activity, final View customView, final ViewGroup viewGroup) {
this(activity, customView, viewGroup, CroutonConfiguration.DEFAULT);
}
/**
* Creates the {@link Crouton}.
*
* @param activity The {@link Activity} that represents the context in which
* the Crouton should exist.
* @param customView The custom {@link View} to display
* @param viewGroup The {@link ViewGroup} that this {@link Crouton} should
* be added to.
* @param configuration The {@link CroutonConfiguration} for this
* {@link Crouton}.
*/
private Crouton(final Activity activity, final View customView, final ViewGroup viewGroup,
final CroutonConfiguration configuration) {
if (activity == null || customView == null)
throw new IllegalArgumentException("Null parameters are not accepted");
this.activity = activity;
this.customView = customView;
this.viewGroup = viewGroup;
style = new CroutonStyle.Builder().build();
text = null;
this.configuration = configuration;
}
/** Cancels a {@link Crouton} immediately. */
public void cancel() {
final CroutonManager manager = CroutonManager.getInstance();
manager.removeCroutonImmediately(this);
}
public Animation getInAnimation() {
if (null == inAnimation && null != activity) {
if (getConfiguration().inAnimationResId > 0) {
inAnimation = AnimationUtils.loadAnimation(getActivity(), getConfiguration().inAnimationResId);
} else {
measureCroutonView();
inAnimation = DefaultAnimationsBuilder.buildDefaultSlideInDownAnimation(getView());
}
}
return inAnimation;
}
public Animation getOutAnimation() {
if (null == outAnimation && null != activity) {
if (getConfiguration().outAnimationResId > 0) {
outAnimation = AnimationUtils.loadAnimation(getActivity(), getConfiguration().outAnimationResId);
} else {
outAnimation = DefaultAnimationsBuilder.buildDefaultSlideOutUpAnimation(getView());
}
}
return outAnimation;
}
/**
* Set the {@link CroutonConfiguration} on this {@link Crouton}, prior to
* showing it.
*
* @param configuration a {@link CroutonConfiguration} built using the
* {@link CroutonConfiguration.Builder}.
* @return this {@link Crouton}.
*/
public Crouton setConfiguration(final CroutonConfiguration configuration) {
this.configuration = configuration;
return this;
}
/**
* @param lifecycleCallback Callback object for notable events in the life
* of a Crouton.
*/
public void setLifecycleCallback(final CroutonLifecycleCallback lifecycleCallback) {
this.lifecycleCallback = lifecycleCallback;
}
/**
* Allows setting of an {@link OnClickListener} directly to a
* {@link Crouton} without having to use a custom view.
*
* @param onClickListener The {@link OnClickListener} to set.
* @return this {@link Crouton}.
*/
public Crouton setOnClickListener(final OnClickListener onClickListener) {
this.onClickListener = onClickListener;
return this;
}
/**
* Displays the {@link Crouton}. If there's another {@link Crouton} visible
* at the time, this {@link Crouton} will be displayed afterwards.
*/
public void show() {
CroutonManager.getInstance().add(this);
}
@Override
public String toString() {
return "Crouton{" + "text=" + text + ", style=" + style + ", configuration=" + configuration + ", customView="
+ customView + ", onClickListener=" + onClickListener + ", activity=" + activity + ", viewGroup="
+ viewGroup + ", croutonView=" + croutonView + ", inAnimation=" + inAnimation + ", outAnimation="
+ outAnimation + ", lifecycleCallback=" + lifecycleCallback + '}';
}
private RelativeLayout initializeContentView(final Resources resources) {
final RelativeLayout contentView = new RelativeLayout(activity);
contentView.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT));
// set padding
int padding = style.paddingInPixels;
// if a padding dimension has been set, this will overwrite any padding
// in pixels
if (style.paddingDimensionResId > 0) {
padding = resources.getDimensionPixelSize(style.paddingDimensionResId);
}
contentView.setPadding(padding, padding, padding, padding);
// only setup image if one is requested
ImageView image = null;
if (null != style.imageDrawable || 0 != style.imageResId) {
image = initializeImageView();
contentView.addView(image, image.getLayoutParams());
}
final TextView text = initializeTextView(resources);
final RelativeLayout.LayoutParams textParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
if (null != image) {
textParams.addRule(RelativeLayout.RIGHT_OF, image.getId());
}
contentView.addView(text, textParams);
return contentView;
}
private void initializeCroutonView() {
final Resources resources = activity.getResources();
croutonView = initializeCroutonViewGroup(resources);
// create content view
final RelativeLayout contentView = initializeContentView(resources);
croutonView.addView(contentView);
}
private FrameLayout initializeCroutonViewGroup(final Resources resources) {
final FrameLayout croutonView = new FrameLayout(activity);
if (null != onClickListener) {
croutonView.setOnClickListener(onClickListener);
}
final int height;
if (style.heightDimensionResId > 0) {
height = resources.getDimensionPixelSize(style.heightDimensionResId);
} else {
height = style.heightInPixels;
}
final int width;
if (style.widthDimensionResId > 0) {
width = resources.getDimensionPixelSize(style.widthDimensionResId);
} else {
width = style.widthInPixels;
}
croutonView.setLayoutParams(new FrameLayout.LayoutParams(width != 0 ? width
: FrameLayout.LayoutParams.MATCH_PARENT, height));
// set background
if (style.backgroundColorValue != -1) {
croutonView.setBackgroundColor(style.backgroundColorValue);
} else {
croutonView.setBackgroundColor(resources.getColor(style.backgroundColorResourceId));
}
// set the background drawable if set. This will override the background
// color.
if (style.backgroundDrawableResourceId != 0) {
final Bitmap background = BitmapFactory.decodeResource(resources, style.backgroundDrawableResourceId);
final BitmapDrawable drawable = new BitmapDrawable(resources, background);
if (style.isTileEnabled) {
drawable.setTileModeXY(Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
}
ViewAccessor.setBackground(croutonView, drawable);
}
return croutonView;
}
private ImageView initializeImageView() {
ImageView image;
image = new ImageView(activity);
image.setId(IMAGE_ID);
image.setAdjustViewBounds(true);
image.setScaleType(style.imageScaleType);
// set the image drawable if not null
if (null != style.imageDrawable) {
image.setImageDrawable(style.imageDrawable);
}
// set the image resource if not 0. This will overwrite the drawable
// if both are set
if (style.imageResId != 0) {
image.setImageResource(style.imageResId);
}
final RelativeLayout.LayoutParams imageParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
imageParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
imageParams.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
image.setLayoutParams(imageParams);
return image;
}
private TextView initializeTextView(final Resources resources) {
final TextView text = new TextView(activity);
text.setId(TEXT_ID);
text.setText(this.text);
text.setContentDescription(this.text);
text.setTypeface(Typeface.DEFAULT_BOLD);
text.setGravity(style.gravity);
// set the text color if set
if (style.textColorResourceId != 0) {
text.setTextColor(resources.getColor(style.textColorResourceId));
}
// Set the text size. If the user has set a text size and text
// appearance, the text size in the text appearance
// will override this.
if (style.textSize != 0) {
text.setTextSize(TypedValue.COMPLEX_UNIT_SP, style.textSize);
}
// Setup the shadow if requested
if (style.textShadowColorResId != 0) {
initializeTextViewShadow(resources, text);
}
// Set the text appearance
if (style.textAppearanceResId != 0) {
text.setTextAppearance(activity, style.textAppearanceResId);
}
return text;
}
private void initializeTextViewShadow(final Resources resources, final TextView text) {
final int textShadowColor = resources.getColor(style.textShadowColorResId);
final float textShadowRadius = style.textShadowRadius;
final float textShadowDx = style.textShadowDx;
final float textShadowDy = style.textShadowDy;
text.setShadowLayer(textShadowRadius, textShadowDx, textShadowDy, textShadowColor);
}
private boolean isCroutonViewNotNull() {
return null != croutonView && null != croutonView.getParent();
}
private boolean isCustomViewNotNull() {
return null != customView && null != customView.getParent();
}
private void measureCroutonView() {
final View view = getView();
int widthSpec;
if (viewGroup != null) {
widthSpec = View.MeasureSpec.makeMeasureSpec(viewGroup.getMeasuredWidth(), View.MeasureSpec.AT_MOST);
} else {
widthSpec = View.MeasureSpec.makeMeasureSpec(activity.getWindow().getDecorView().getMeasuredWidth(),
View.MeasureSpec.AT_MOST);
}
view.measure(widthSpec, View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
}
/** Removes the activity reference this {@link Crouton} is holding */
void detachActivity() {
activity = null;
}
/** Removes the lifecycleCallback reference this {@link Crouton} is holding */
void detachLifecycleCallback() {
lifecycleCallback = null;
}
/** Removes the viewGroup reference this {@link Crouton} is holding */
void detachViewGroup() {
viewGroup = null;
}
/** @return the activity */
Activity getActivity() {
return activity;
}
/** @return this croutons configuration */
CroutonConfiguration getConfiguration() {
if (null == configuration) {
configuration = getStyle().configuration;
}
return configuration;
}
/** @return the lifecycleCallback */
CroutonLifecycleCallback getLifecycleCallback() {
return lifecycleCallback;
}
/** @return the style */
CroutonStyle getStyle() {
return style;
}
/** @return the text */
CharSequence getText() {
return text;
}
/** @return the view */
View getView() {
// return the custom view if one exists
if (null != customView) return customView;
// if already setup return the view
if (null == croutonView) {
initializeCroutonView();
}
return croutonView;
}
/** @return the viewGroup */
ViewGroup getViewGroup() {
return viewGroup;
}
/**
* @return <code>true</code> if the {@link Crouton} is being displayed, else
* <code>false</code>.
*/
boolean isShowing() {
return null != activity && (isCroutonViewNotNull() || isCustomViewNotNull());
}
/**
* Cancels all queued {@link Crouton}s. If there is a {@link Crouton}
* displayed currently, it will be the last one displayed.
*/
public static void cancelAllCroutons() {
CroutonManager.getInstance().clearCroutonQueue();
}
/**
* Clears (and removes from {@link Activity}'s content view, if necessary)
* all croutons for the provided activity
*
* @param activity - The {@link Activity} to clear the croutons for.
*/
public static void clearCroutonsForActivity(final Activity activity) {
CroutonManager.getInstance().clearCroutonsForActivity(activity);
}
/**
* Convenience method to get the license text for embedding within your
* application.
*
* @return The license text.
*/
public static String getLicenseText() {
return "This application uses the Crouton library.\n\n" + "Copyright 2012 - 2013 Benjamin Weiss \n"
+ "Copyright 2012 Neofonie Mobile GmbH\n" + "\n"
+ "Licensed under the Apache License, Version 2.0 (the \"License\");\n"
+ "you may not use this file except in compliance with the License.\n"
+ "You may obtain a copy of the License at\n" + "\n"
+ " http://www.apache.org/licenses/LICENSE-2.0\n" + "\n"
+ "Unless required by applicable law or agreed to in writing, software\n"
+ "distributed under the License is distributed on an \"AS IS\" BASIS,\n"
+ "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
+ "See the License for the specific language governing permissions and\n"
+ "limitations under the License.";
}
/**
* Allows hiding of a previously displayed {@link Crouton}.
*
* @param crouton The {@link Crouton} you want to hide.
*/
public static void hide(final Crouton crouton) {
CroutonManager.getInstance().removeCrouton(crouton);
}
// ////////////////////////////////////////////////////////////////////////////////////
// You have reached the internal API of Crouton.
// If you do not plan to develop for Crouton there is nothing of interest
// below here.
// ////////////////////////////////////////////////////////////////////////////////////
/**
* Creates a {@link Crouton} with provided text-resource and style for a
* given activity.
*
* @param activity The {@link Activity} that the {@link Crouton} should be
* attached to.
* @param customView The custom {@link View} to display
* @return The created {@link Crouton}.
*/
public static Crouton make(final Activity activity, final View customView) {
return new Crouton(activity, customView);
}
/**
* Creates a {@link Crouton} with provided text-resource and style for a
* given activity.
*
* @param activity The {@link Activity} that represents the context in which
* the Crouton should exist.
* @param customView The custom {@link View} to display
* @param viewGroupResId The resource id of the {@link ViewGroup} that this
* {@link Crouton} should be added to.
* @return The created {@link Crouton}.
*/
public static Crouton make(final Activity activity, final View customView, final int viewGroupResId) {
return new Crouton(activity, customView, (ViewGroup) activity.findViewById(viewGroupResId));
}
/**
* Creates a {@link Crouton} with provided text-resource and style for a
* given activity.
*
* @param activity The {@link Activity} that represents the context in which
* the Crouton should exist.
* @param customView The custom {@link View} to display
* @param viewGroupResId The resource id of the {@link ViewGroup} that this
* {@link Crouton} should be added to.
* @param configuration The configuration for this crouton.
* @return The created {@link Crouton}.
*/
public static Crouton make(final Activity activity, final View customView, final int viewGroupResId,
final CroutonConfiguration configuration) {
return new Crouton(activity, customView, (ViewGroup) activity.findViewById(viewGroupResId), configuration);
}
/**
* Creates a {@link Crouton} with provided text-resource and style for a
* given activity.
*
* @param activity The {@link Activity} that represents the context in which
* the Crouton should exist.
* @param customView The custom {@link View} to display
* @param viewGroup The {@link ViewGroup} that this {@link Crouton} should
* be added to.
* @return The created {@link Crouton}.
*/
public static Crouton make(final Activity activity, final View customView, final ViewGroup viewGroup) {
return new Crouton(activity, customView, viewGroup);
}
/**
* Creates a {@link Crouton} with provided text and style for a given
* activity.
*
* @param activity The {@link Activity} that the {@link Crouton} should be
* attached to.
* @param text The text you want to display.
* @param style The style that this {@link Crouton} should be created with.
* @return The created {@link Crouton}.
*/
public static Crouton makeText(final Activity activity, final CharSequence text, final CroutonStyle style) {
return new Crouton(activity, text, style);
}
/**
* Creates a {@link Crouton} with provided text and style for a given
* activity.
*
* @param activity The {@link Activity} that represents the context in which
* the Crouton should exist.
* @param text The text you want to display.
* @param style The style that this {@link Crouton} should be created with.
* @param viewGroupResId The resource id of the {@link ViewGroup} that this
* {@link Crouton} should be added to.
* @return The created {@link Crouton}.
*/
public static Crouton makeText(final Activity activity, final CharSequence text, final CroutonStyle style,
final int viewGroupResId) {
return new Crouton(activity, text, style, (ViewGroup) activity.findViewById(viewGroupResId));
}
/**
* Creates a {@link Crouton} with provided text and style for a given
* activity.
*
* @param activity The {@link Activity} that represents the context in which
* the Crouton should exist.
* @param text The text you want to display.
* @param style The style that this {@link Crouton} should be created with.
* @param viewGroup The {@link ViewGroup} that this {@link Crouton} should
* be added to.
* @return The created {@link Crouton}.
*/
public static Crouton makeText(final Activity activity, final CharSequence text, final CroutonStyle style,
final ViewGroup viewGroup) {
return new Crouton(activity, text, style, viewGroup);
}
/**
* Creates a {@link Crouton} with provided text-resource and style for a
* given activity.
*
* @param activity The {@link Activity} that the {@link Crouton} should be
* attached to.
* @param textResourceId The resource id of the text you want to display.
* @param style The style that this {@link Crouton} should be created with.
* @return The created {@link Crouton}.
*/
public static Crouton makeText(final Activity activity, final int textResourceId, final CroutonStyle style) {
return makeText(activity, activity.getString(textResourceId), style);
}
/**
* Creates a {@link Crouton} with provided text-resource and style for a
* given activity.
*
* @param activity The {@link Activity} that represents the context in which
* the Crouton should exist.
* @param textResourceId The resource id of the text you want to display.
* @param style The style that this {@link Crouton} should be created with.
* @param viewGroupResId The resource id of the {@link ViewGroup} that this
* {@link Crouton} should be added to.
* @return The created {@link Crouton}.
*/
public static Crouton makeText(final Activity activity, final int textResourceId, final CroutonStyle style,
final int viewGroupResId) {
return makeText(activity, activity.getString(textResourceId), style,
(ViewGroup) activity.findViewById(viewGroupResId));
}
/**
* Creates a {@link Crouton} with provided text-resource and style for a
* given activity.
*
* @param activity The {@link Activity} that represents the context in which
* the Crouton should exist.
* @param textResourceId The resource id of the text you want to display.
* @param style The style that this {@link Crouton} should be created with.
* @param viewGroup The {@link ViewGroup} that this {@link Crouton} should
* be added to.
* @return The created {@link Crouton}.
*/
public static Crouton makeText(final Activity activity, final int textResourceId, final CroutonStyle style,
final ViewGroup viewGroup) {
return makeText(activity, activity.getString(textResourceId), style, viewGroup);
}
/**
* Creates a {@link Crouton} with provided text and style for a given
* activity and displays it directly.
*
* @param activity The {@link android.app.Activity} that the {@link Crouton}
* should be attached to.
* @param customView The custom {@link View} to display
*/
public static void show(final Activity activity, final View customView) {
make(activity, customView).show();
}
/**
* Creates a {@link Crouton} with provided text and style for a given
* activity and displays it directly.
*
* @param activity The {@link Activity} that represents the context in which
* the Crouton should exist.
* @param customView The custom {@link View} to display
* @param viewGroupResId The resource id of the {@link ViewGroup} that this
* {@link Crouton} should be added to.
*/
public static void show(final Activity activity, final View customView, final int viewGroupResId) {
make(activity, customView, viewGroupResId).show();
}
/**
* Creates a {@link Crouton} with provided text and style for a given
* activity and displays it directly.
*
* @param activity The {@link Activity} that represents the context in which
* the Crouton should exist.
* @param customView The custom {@link View} to display
* @param viewGroup The {@link ViewGroup} that this {@link Crouton} should
* be added to.
*/
public static void show(final Activity activity, final View customView, final ViewGroup viewGroup) {
make(activity, customView, viewGroup).show();
}
/**
* Creates a {@link Crouton} with provided text and style for a given
* activity and displays it directly.
*
* @param activity The {@link android.app.Activity} that the {@link Crouton}
* should be attached to.
* @param text The text you want to display.
* @param style The style that this {@link Crouton} should be created with.
*/
public static void showText(final Activity activity, final CharSequence text, final CroutonStyle style) {
makeText(activity, text, style).show();
}
/**
* Creates a {@link Crouton} with provided text and style for a given
* activity and displays it directly.
*
* @param activity The {@link Activity} that represents the context in which
* the Crouton should exist.
* @param text The text you want to display.
* @param style The style that this {@link Crouton} should be created with.
* @param viewGroupResId The resource id of the {@link ViewGroup} that this
* {@link Crouton} should be added to.
*/
public static void showText(final Activity activity, final CharSequence text, final CroutonStyle style,
final int viewGroupResId) {
makeText(activity, text, style, (ViewGroup) activity.findViewById(viewGroupResId)).show();
}
/**
* Creates a {@link Crouton} with provided text and style for a given
* activity and displays it directly.
*
* @param activity The {@link Activity} that represents the context in which
* the Crouton should exist.
* @param text The text you want to display.
* @param style The style that this {@link Crouton} should be created with.
* @param viewGroupResId The resource id of the {@link ViewGroup} that this
* {@link Crouton} should be added to.
* @param configuration The configuration for this Crouton.
*/
public static void showText(final Activity activity, final CharSequence text, final CroutonStyle style,
final int viewGroupResId, final CroutonConfiguration configuration) {
makeText(activity, text, style, (ViewGroup) activity.findViewById(viewGroupResId)).setConfiguration(
configuration).show();
}
/**
* Creates a {@link Crouton} with provided text and style for a given
* activity and displays it directly.
*
* @param activity The {@link Activity} that represents the context in which
* the Crouton should exist.
* @param text The text you want to display.
* @param style The style that this {@link Crouton} should be created with.
* @param viewGroup The {@link ViewGroup} that this {@link Crouton} should
* be added to.
*/
public static void showText(final Activity activity, final CharSequence text, final CroutonStyle style,
final ViewGroup viewGroup) {
makeText(activity, text, style, viewGroup).show();
}
/**
* Creates a {@link Crouton} with provided text-resource and style for a
* given activity and displays it directly.
*
* @param activity The {@link Activity} that the {@link Crouton} should be
* attached to.
* @param textResourceId The resource id of the text you want to display.
* @param style The style that this {@link Crouton} should be created with.
*/
public static void showText(final Activity activity, final int textResourceId, final CroutonStyle style) {
showText(activity, activity.getString(textResourceId), style);
}
/**
* Creates a {@link Crouton} with provided text-resource and style for a
* given activity and displays it directly.
*
* @param activity The {@link Activity} that represents the context in which
* the Crouton should exist.
* @param textResourceId The resource id of the text you want to display.
* @param style The style that this {@link Crouton} should be created with.
* @param viewGroupResId The resource id of the {@link ViewGroup} that this
* {@link Crouton} should be added to.
*/
public static void showText(final Activity activity, final int textResourceId, final CroutonStyle style,
final int viewGroupResId) {
showText(activity, activity.getString(textResourceId), style, viewGroupResId);
}
/**
* Creates a {@link Crouton} with provided text-resource and style for a
* given activity and displays it directly.
*
* @param activity The {@link Activity} that represents the context in which
* the Crouton should exist.
* @param textResourceId The resource id of the text you want to display.
* @param style The style that this {@link Crouton} should be created with.
* @param viewGroup The {@link ViewGroup} that this {@link Crouton} should
* be added to.
*/
public static void showText(final Activity activity, final int textResourceId, final CroutonStyle style,
final ViewGroup viewGroup) {
showText(activity, activity.getString(textResourceId), style, viewGroup);
}
}

View File

@ -1,127 +0,0 @@
/*
* Copyright 2013 Benjamin Weiss
*
* 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 de.keyboardsurfer.android.widget.crouton;
/**
* Allows configuring a {@link Crouton}s behavior aside from the actual view,
* which is defined via {@link CroutonStyle}.
* <p/>
* This allows to re-use a {@link CroutonStyle} while modifying parameters that
* only have to be applied when the {@link Crouton} is being displayed.
*
* @author chris
* @since 1.8
*/
public class CroutonConfiguration {
/**
* Display a {@link Crouton} for an infinite amount of time or until
* {@link de.keyboardsurfer.android.widget.crouton.Crouton#cancel()} has
* been called.
*/
public static final int DURATION_INFINITE = -1;
/** The default short display duration of a {@link Crouton}. */
public static final int DURATION_SHORT = 3000;
/** The default long display duration of a {@link Crouton}. */
public static final int DURATION_LONG = 5000;
/** The default {@link CroutonConfiguration} of a {@link Crouton}. */
public static final CroutonConfiguration DEFAULT;
static {
DEFAULT = new Builder().setDuration(DURATION_SHORT).build();
}
/**
* The durationInMilliseconds the {@link Crouton} will be displayed in
* milliseconds.
*/
final int durationInMilliseconds;
/** The resource id for the in animation. */
final int inAnimationResId;
/** The resource id for the out animation. */
final int outAnimationResId;
private CroutonConfiguration(final Builder builder) {
durationInMilliseconds = builder.durationInMilliseconds;
inAnimationResId = builder.inAnimationResId;
outAnimationResId = builder.outAnimationResId;
}
@Override
public String toString() {
return "Configuration{" + "durationInMilliseconds=" + durationInMilliseconds + ", inAnimationResId="
+ inAnimationResId + ", outAnimationResId=" + outAnimationResId + '}';
}
/** Creates a {@link Builder} to build a {@link CroutonConfiguration} upon. */
public static class Builder {
private int durationInMilliseconds = DURATION_SHORT;
private int inAnimationResId = 0;
private int outAnimationResId = 0;
/**
* Builds the {@link CroutonConfiguration}.
*
* @return The built {@link CroutonConfiguration}.
*/
public CroutonConfiguration build() {
return new CroutonConfiguration(this);
}
/**
* Set the durationInMilliseconds option of the {@link Crouton}.
*
* @param duration The durationInMilliseconds the crouton will be
* displayed {@link Crouton} in milliseconds.
* @return the {@link Builder}.
*/
public Builder setDuration(final int duration) {
durationInMilliseconds = duration;
return this;
}
/**
* The resource id for the in animation.
*
* @param inAnimationResId The resource identifier for the animation
* that's being shown when the {@link Crouton} is going to be
* displayed.
* @return the {@link Builder}.
*/
public Builder setInAnimation(final int inAnimationResId) {
this.inAnimationResId = inAnimationResId;
return this;
}
/**
* The resource id for the out animation
*
* @param outAnimationResId The resource identifier for the animation
* that's being shown when the {@link Crouton} is going to be
* removed.
* @return the {@link Builder}.
*/
public Builder setOutAnimation(final int outAnimationResId) {
this.outAnimationResId = outAnimationResId;
return this;
}
}
}

View File

@ -1,28 +0,0 @@
/*
* Copyright 2012 - 2013 Benjamin Weiss
*
* 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 de.keyboardsurfer.android.widget.crouton;
/** Provides callback methods on major lifecycle events of a {@link Crouton}. */
public interface CroutonLifecycleCallback {
/** Will be called when your Crouton has been displayed. */
public void onDisplayed();
/** Will be called when your {@link Crouton} has been removed. */
public void onRemoved();
// public void onCeasarDressing();
}

View File

@ -1,366 +0,0 @@
/*
* Copyright 2012 - 2013 Benjamin Weiss
* Copyright 2012 Neofonie Mobile GmbH
*
* 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 de.keyboardsurfer.android.widget.crouton;
import static org.mariotaku.twidere.util.Utils.announceForAccessibilityCompat;
import android.annotation.TargetApi;
import android.app.Activity;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.FrameLayout;
import java.util.Iterator;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
/** Manages the lifecycle of {@link Crouton}s. */
final class CroutonManager extends Handler {
private static CroutonManager INSTANCE;
private final Queue<Crouton> croutonQueue;
private CroutonManager() {
croutonQueue = new LinkedBlockingQueue<Crouton>();
}
/*
* (non-Javadoc)
*
* @see android.os.Handler#handleMessage(android.os.Message)
*/
@Override
public void handleMessage(final Message message) {
final Crouton crouton = (Crouton) message.obj;
switch (message.what) {
case Messages.DISPLAY_CROUTON: {
displayCrouton();
break;
}
case Messages.ADD_CROUTON_TO_VIEW: {
addCroutonToView(crouton);
break;
}
case Messages.REMOVE_CROUTON: {
removeCrouton(crouton);
if (null != crouton.getLifecycleCallback()) {
crouton.getLifecycleCallback().onRemoved();
}
break;
}
default: {
super.handleMessage(message);
break;
}
}
}
@Override
public String toString() {
return "CroutonManager{croutonQueue=" + croutonQueue + '}';
}
/**
* Removes the {@link Crouton}'s view after it's display
* durationInMilliseconds.
*
* @param crouton The {@link Crouton} added to a {@link ViewGroup} and
* should be removed.
*/
protected void removeCrouton(final Crouton crouton) {
final View croutonView = crouton.getView();
final ViewGroup croutonParentView = (ViewGroup) croutonView.getParent();
if (croutonParentView == null) return;
croutonView.startAnimation(crouton.getOutAnimation());
// Remove the Crouton from the queue.
final Crouton removed = croutonQueue.poll();
// Remove the crouton from the view's parent.
croutonParentView.removeView(croutonView);
if (null != removed) {
removed.detachActivity();
removed.detachViewGroup();
if (null != removed.getLifecycleCallback()) {
removed.getLifecycleCallback().onRemoved();
}
removed.detachLifecycleCallback();
}
// Send a message to display the next crouton but delay it by the out
// animation duration to make sure it finishes
sendMessageDelayed(crouton, Messages.DISPLAY_CROUTON, crouton.getOutAnimation().getDuration());
}
/**
* Adds a {@link Crouton} to the {@link ViewParent} of it's {@link Activity}
* .
*
* @param crouton The {@link Crouton} that should be added.
*/
private void addCroutonToView(final Crouton crouton) {
// don't add if it is already showing
if (crouton.isShowing()) return;
final View croutonView = crouton.getView();
if (null == croutonView.getParent()) {
ViewGroup.LayoutParams params = croutonView.getLayoutParams();
if (null == params) {
params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
// display Crouton in ViewGroup is it has been supplied
if (null != crouton.getViewGroup()) {
// TODO implement add to last position feature (need to align
// with how this will be requested for activity)
if (crouton.getViewGroup() instanceof FrameLayout) {
crouton.getViewGroup().addView(croutonView, params);
} else {
crouton.getViewGroup().addView(croutonView, 0, params);
}
} else {
final Activity activity = crouton.getActivity();
if (null == activity || activity.isFinishing()) return;
activity.addContentView(croutonView, params);
}
}
croutonView.requestLayout(); // This is needed so the animation can use
// the measured with/height
croutonView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
ViewTreeObserverAccessor.removeOnGlobalLayoutListener(croutonView.getViewTreeObserver(), this);
croutonView.startAnimation(crouton.getInAnimation());
announceForAccessibilityCompat(crouton.getActivity(), crouton.getView(), crouton.getText(), getClass());
if (CroutonConfiguration.DURATION_INFINITE != crouton.getConfiguration().durationInMilliseconds) {
sendMessageDelayed(crouton, Messages.REMOVE_CROUTON,
crouton.getConfiguration().durationInMilliseconds + crouton.getInAnimation().getDuration());
}
}
});
}
private long calculateCroutonDuration(final Crouton crouton) {
long croutonDuration = crouton.getConfiguration().durationInMilliseconds;
croutonDuration += crouton.getInAnimation().getDuration();
croutonDuration += crouton.getOutAnimation().getDuration();
return croutonDuration;
}
/** Displays the next {@link Crouton} within the queue. */
private void displayCrouton() {
if (croutonQueue.isEmpty()) return;
// First peek whether the Crouton has an activity.
final Crouton currentCrouton = croutonQueue.peek();
// If the activity is null we poll the Crouton off the queue.
if (null == currentCrouton.getActivity()) {
croutonQueue.poll();
}
if (!currentCrouton.isShowing()) {
// Display the Crouton
sendMessage(currentCrouton, Messages.ADD_CROUTON_TO_VIEW);
if (null != currentCrouton.getLifecycleCallback()) {
currentCrouton.getLifecycleCallback().onDisplayed();
}
} else {
sendMessageDelayed(currentCrouton, Messages.DISPLAY_CROUTON, calculateCroutonDuration(currentCrouton));
}
}
private void removeAllMessages() {
removeMessages(Messages.ADD_CROUTON_TO_VIEW);
removeMessages(Messages.DISPLAY_CROUTON);
removeMessages(Messages.REMOVE_CROUTON);
}
private void removeAllMessagesForCrouton(final Crouton crouton) {
removeMessages(Messages.ADD_CROUTON_TO_VIEW, crouton);
removeMessages(Messages.DISPLAY_CROUTON, crouton);
removeMessages(Messages.REMOVE_CROUTON, crouton);
}
/**
* Sends a {@link Crouton} within a {@link Message}.
*
* @param crouton The {@link Crouton} that should be sent.
* @param messageId The {@link Message} id.
*/
private void sendMessage(final Crouton crouton, final int messageId) {
final Message message = obtainMessage(messageId);
message.obj = crouton;
sendMessage(message);
}
/**
* Sends a {@link Crouton} within a delayed {@link Message}.
*
* @param crouton The {@link Crouton} that should be sent.
* @param messageId The {@link Message} id.
* @param delay The delay in milliseconds.
*/
private void sendMessageDelayed(final Crouton crouton, final int messageId, final long delay) {
final Message message = obtainMessage(messageId);
message.obj = crouton;
sendMessageDelayed(message, delay);
}
/**
* Inserts a {@link Crouton} to be displayed.
*
* @param crouton The {@link Crouton} to be displayed.
*/
void add(final Crouton crouton) {
croutonQueue.add(crouton);
displayCrouton();
}
/** Removes all {@link Crouton}s from the queue. */
void clearCroutonQueue() {
removeAllMessages();
if (croutonQueue == null) return;
// remove any views that may already have been added to the activity's
// content view
for (final Crouton crouton : croutonQueue) {
if (crouton.isShowing()) {
((ViewGroup) crouton.getView().getParent()).removeView(crouton.getView());
}
}
croutonQueue.clear();
}
/**
* Removes all {@link Crouton}s for the provided activity. This will remove
* crouton from {@link Activity}s content view immediately.
*/
void clearCroutonsForActivity(final Activity activity) {
if (croutonQueue == null) return;
final Iterator<Crouton> croutonIterator = croutonQueue.iterator();
while (croutonIterator.hasNext()) {
final Crouton crouton = croutonIterator.next();
if (null != crouton.getActivity() && crouton.getActivity().equals(activity)) {
// remove the crouton from the content view
if (crouton.isShowing()) {
((ViewGroup) crouton.getView().getParent()).removeView(crouton.getView());
}
removeAllMessagesForCrouton(crouton);
// remove the crouton from the queue
croutonIterator.remove();
}
}
}
/**
* Removes a {@link Crouton} immediately, even when it's currently being
* displayed.
*
* @param crouton The {@link Crouton} that should be removed.
*/
void removeCroutonImmediately(final Crouton crouton) {
// if Crouton has already been displayed then it may not be in the queue
// (because it was popped).
// This ensures the displayed Crouton is removed from its parent
// immediately, whether another instance
// of it exists in the queue or not.
// Note: crouton.isShowing() is false here even if it really is showing,
// as croutonView object in
// Crouton seems to be out of sync with reality!
if (null != crouton.getActivity() && null != crouton.getView() && null != crouton.getView().getParent()) {
((ViewGroup) crouton.getView().getParent()).removeView(crouton.getView());
// remove any messages pending for the crouton
removeAllMessagesForCrouton(crouton);
}
// remove any matching croutons from queue
if (croutonQueue == null) return;
final Iterator<Crouton> croutonIterator = croutonQueue.iterator();
while (croutonIterator.hasNext()) {
final Crouton c = croutonIterator.next();
if (c.equals(crouton) && null != c.getActivity()) {
// remove the crouton from the content view
if (crouton.isShowing()) {
((ViewGroup) c.getView().getParent()).removeView(c.getView());
}
// remove any messages pending for the crouton
removeAllMessagesForCrouton(c);
// remove the crouton from the queue
croutonIterator.remove();
// we have found our crouton so just break
break;
}
}
}
/** @return The currently used instance of the {@link Manager}. */
static synchronized CroutonManager getInstance() {
if (null == INSTANCE) {
INSTANCE = new CroutonManager();
}
return INSTANCE;
}
private static final class Messages {
public static final int DISPLAY_CROUTON = 0xc2007;
public static final int ADD_CROUTON_TO_VIEW = 0xc20074dd;
public static final int REMOVE_CROUTON = 0xc2007de1;
private Messages() { /* no-op */
}
}
private static class ViewTreeObserverAccessor {
@SuppressWarnings("deprecation")
private static void removeOnGlobalLayoutListener(final ViewTreeObserver observer,
final OnGlobalLayoutListener listener) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
observer.removeGlobalOnLayoutListener(listener);
} else {
ViewTreeObserverAccessorJB.removeOnGlobalLayoutListener(observer, listener);
}
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private static class ViewTreeObserverAccessorJB {
private static void removeOnGlobalLayoutListener(final ViewTreeObserver observer,
final OnGlobalLayoutListener listener) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) return;
observer.removeOnGlobalLayoutListener(listener);
}
}
}
}

View File

@ -1,479 +0,0 @@
/*
* Copyright 2012 - 2013 Benjamin Weiss
* Copyright 2012 Neofonie Mobile GmbH
*
* 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 de.keyboardsurfer.android.widget.crouton;
import android.graphics.drawable.Drawable;
import android.view.Gravity;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
/** The style for a {@link Crouton}. */
public class CroutonStyle {
public static final int holoRedLight = 0xffff4444;
public static final int holoGreenLight = 0xff99cc00;
public static final int holoBlueLight = 0xff33b5e5;
public static final int holoOrangeLight = 0xffffbb33;
/** Default style for alerting the user. */
public static final CroutonStyle ALERT;
/** Default style for warn the user. */
public static final CroutonStyle WARN;
/** Default style for confirming an action. */
public static final CroutonStyle CONFIRM;
/** Default style for general information. */
public static final CroutonStyle INFO;
static {
ALERT = new Builder().setBackgroundColorValue(holoRedLight).build();
WARN = new Builder().setBackgroundColorValue(holoOrangeLight).build();
CONFIRM = new Builder().setBackgroundColorValue(holoGreenLight).build();
INFO = new Builder().setBackgroundColorValue(holoBlueLight).build();
}
/**
* The {@link CroutonConfiguration} for this {@link CroutonStyle}. It can be
* overridden via {@link Crouton#setConfiguration(CroutonConfiguration)}.
*/
final CroutonConfiguration configuration;
/**
* The resource id of the backgroundResourceId.
* <p/>
* 0 for no backgroundResourceId.
*/
final int backgroundColorResourceId;
/**
* The resource id of the backgroundDrawableResourceId.
* <p/>
* 0 for no backgroundDrawableResourceId.
*/
final int backgroundDrawableResourceId;
/**
* The backgroundColorResourceValue's e.g. 0xffff4444;
* <p/>
* -1 for no value.
*/
final int backgroundColorValue;
/** Whether we should isTileEnabled the backgroundResourceId or not. */
final boolean isTileEnabled;
/**
* The text colorResourceId's resource id.
* <p/>
* 0 sets the text colorResourceId to the system theme default.
*/
final int textColorResourceId;
/** The height of the {@link Crouton} in pixels. */
final int heightInPixels;
/** Resource ID for the height of the {@link Crouton}. */
final int heightDimensionResId;
/** The width of the {@link Crouton} in pixels. */
final int widthInPixels;
/** Resource ID for the width of the {@link Crouton}. */
final int widthDimensionResId;
/** The text's gravity as provided by {@link Gravity}. */
final int gravity;
/** An additional image to display in the {@link Crouton}. */
final Drawable imageDrawable;
/** An additional image to display in the {@link Crouton}. */
final int imageResId;
/**
* The {@link ImageView.ScaleType} for the image to display in the
* {@link Crouton}.
*/
final ImageView.ScaleType imageScaleType;
/**
* The text size in sp
* <p/>
* 0 sets the text size to the system theme default
*/
final int textSize;
/** The text shadow color's resource id */
final int textShadowColorResId;
/** The text shadow radius */
final float textShadowRadius;
/** The text shadow vertical offset */
final float textShadowDy;
/** The text shadow horizontal offset */
final float textShadowDx;
/** The text appearance resource id for the text. */
final int textAppearanceResId;
/** The padding for the crouton view content in pixels */
final int paddingInPixels;
/** The resource id for the padding for the view content */
final int paddingDimensionResId;
private CroutonStyle(final Builder builder) {
configuration = builder.configuration;
backgroundColorResourceId = builder.backgroundColorResourceId;
backgroundDrawableResourceId = builder.backgroundDrawableResourceId;
isTileEnabled = builder.isTileEnabled;
textColorResourceId = builder.textColorResourceId;
heightInPixels = builder.heightInPixels;
heightDimensionResId = builder.heightDimensionResId;
widthInPixels = builder.widthInPixels;
widthDimensionResId = builder.widthDimensionResId;
gravity = builder.gravity;
imageDrawable = builder.imageDrawable;
textSize = builder.textSize;
textShadowColorResId = builder.textShadowColorResId;
textShadowRadius = builder.textShadowRadius;
textShadowDx = builder.textShadowDx;
textShadowDy = builder.textShadowDy;
textAppearanceResId = builder.textAppearanceResId;
imageResId = builder.imageResId;
imageScaleType = builder.imageScaleType;
paddingInPixels = builder.paddingInPixels;
paddingDimensionResId = builder.paddingDimensionResId;
backgroundColorValue = builder.backgroundColorValue;
}
@Override
public String toString() {
return "Style{" + "configuration=" + configuration + ", backgroundColorResourceId=" + backgroundColorResourceId
+ ", backgroundDrawableResourceId=" + backgroundDrawableResourceId + ", backgroundColorValue="
+ backgroundColorValue + ", isTileEnabled=" + isTileEnabled + ", textColorResourceId="
+ textColorResourceId + ", heightInPixels=" + heightInPixels + ", heightDimensionResId="
+ heightDimensionResId + ", widthInPixels=" + widthInPixels + ", widthDimensionResId="
+ widthDimensionResId + ", gravity=" + gravity + ", imageDrawable=" + imageDrawable + ", imageResId="
+ imageResId + ", imageScaleType=" + imageScaleType + ", textSize=" + textSize
+ ", textShadowColorResId=" + textShadowColorResId + ", textShadowRadius=" + textShadowRadius
+ ", textShadowDy=" + textShadowDy + ", textShadowDx=" + textShadowDx + ", textAppearanceResId="
+ textAppearanceResId + ", paddingInPixels=" + paddingInPixels + ", paddingDimensionResId="
+ paddingDimensionResId + '}';
}
/** Builder for the {@link CroutonStyle} object. */
public static class Builder {
private CroutonConfiguration configuration;
private int backgroundColorValue;
private int backgroundColorResourceId;
private int backgroundDrawableResourceId;
private boolean isTileEnabled;
private int textColorResourceId;
private int heightInPixels;
private int heightDimensionResId;
private int widthInPixels;
private int widthDimensionResId;
private int gravity;
private Drawable imageDrawable;
private int textSize;
private int textShadowColorResId;
private float textShadowRadius;
private float textShadowDx;
private float textShadowDy;
private int textAppearanceResId;
private int imageResId;
private ImageView.ScaleType imageScaleType;
private int paddingInPixels;
private int paddingDimensionResId;
/** Creates a {@link Builder} to build a {@link CroutonStyle} upon. */
public Builder() {
configuration = CroutonConfiguration.DEFAULT;
paddingInPixels = 10;
backgroundColorResourceId = android.R.color.holo_blue_light;
backgroundDrawableResourceId = 0;
backgroundColorValue = -1;
isTileEnabled = false;
textColorResourceId = android.R.color.white;
heightInPixels = LayoutParams.WRAP_CONTENT;
widthInPixels = LayoutParams.MATCH_PARENT;
gravity = Gravity.CENTER;
imageDrawable = null;
imageResId = 0;
imageScaleType = ImageView.ScaleType.FIT_XY;
}
/**
* Creates a {@link Builder} to build a {@link CroutonStyle} upon.
*
* @param baseStyle The base {@link CroutonStyle} to use for this
* {@link CroutonStyle} .
*/
public Builder(final CroutonStyle baseStyle) {
configuration = baseStyle.configuration;
backgroundColorValue = baseStyle.backgroundColorValue;
backgroundColorResourceId = baseStyle.backgroundColorResourceId;
backgroundDrawableResourceId = baseStyle.backgroundDrawableResourceId;
isTileEnabled = baseStyle.isTileEnabled;
textColorResourceId = baseStyle.textColorResourceId;
heightInPixels = baseStyle.heightInPixels;
heightDimensionResId = baseStyle.heightDimensionResId;
widthInPixels = baseStyle.widthInPixels;
widthDimensionResId = baseStyle.widthDimensionResId;
gravity = baseStyle.gravity;
imageDrawable = baseStyle.imageDrawable;
textSize = baseStyle.textSize;
textShadowColorResId = baseStyle.textShadowColorResId;
textShadowRadius = baseStyle.textShadowRadius;
textShadowDx = baseStyle.textShadowDx;
textShadowDy = baseStyle.textShadowDy;
textAppearanceResId = baseStyle.textAppearanceResId;
imageResId = baseStyle.imageResId;
imageScaleType = baseStyle.imageScaleType;
paddingInPixels = baseStyle.paddingInPixels;
paddingDimensionResId = baseStyle.paddingDimensionResId;
}
/** @return a configured {@link CroutonStyle} object. */
public CroutonStyle build() {
return new CroutonStyle(this);
}
/**
* Set the backgroundColorResourceId option of the {@link Crouton}.
*
* @param backgroundColorResourceId The backgroundColorResourceId's
* resource id.
* @return the {@link Builder}.
*/
public Builder setBackgroundColor(final int backgroundColorResourceId) {
this.backgroundColorResourceId = backgroundColorResourceId;
return this;
}
/**
* Set the backgroundColorResourceValue option of the {@link Crouton}.
*
* @param backgroundColorValue The backgroundColorResourceValue's e.g.
* 0xffff4444;
* @return the {@link Builder}.
*/
public Builder setBackgroundColorValue(final int backgroundColorValue) {
this.backgroundColorValue = backgroundColorValue;
return this;
}
/**
* Set the backgroundDrawableResourceId option for the {@link Crouton}.
*
* @param backgroundDrawableResourceId Resource ID of a
* backgroundDrawableResourceId image drawable.
* @return the {@link Builder}.
*/
public Builder setBackgroundDrawable(final int backgroundDrawableResourceId) {
this.backgroundDrawableResourceId = backgroundDrawableResourceId;
return this;
}
/**
* Set the {@link CroutonConfiguration} option of the {@link Crouton}.
*
* @param configuration The {@link CroutonConfiguration}.
* @return the {@link Builder}.
*/
public Builder setConfiguration(final CroutonConfiguration configuration) {
this.configuration = configuration;
return this;
}
/**
* Set the gravity option for the {@link Crouton}.
*
* @param gravity The text's gravity as provided by {@link Gravity}.
* @return the {@link Builder}.
*/
public Builder setGravity(final int gravity) {
this.gravity = gravity;
return this;
}
/**
* Set the heightInPixels option for the {@link Crouton}.
*
* @param height The height of the {@link Crouton} in pixel. Can also be
* {@link LayoutParams#MATCH_PARENT} or
* {@link LayoutParams#WRAP_CONTENT}.
* @return the {@link Builder}.
*/
public Builder setHeight(final int height) {
heightInPixels = height;
return this;
}
/**
* Set the resource id for the height option for the {@link Crouton}.
*
* @param heightDimensionResId Resource ID of a dimension for the height
* of the {@link Crouton}.
* @return the {@link Builder}.
*/
public Builder setHeightDimensionResId(final int heightDimensionResId) {
this.heightDimensionResId = heightDimensionResId;
return this;
}
/**
* Set the image option for the {@link Crouton}.
*
* @param imageDrawable An additional image to display in the
* {@link Crouton}.
* @return the {@link Builder}.
*/
public Builder setImageDrawable(final Drawable imageDrawable) {
this.imageDrawable = imageDrawable;
return this;
}
/**
* Set the image resource option for the {@link Crouton}.
*
* @param imageResId An additional image to display in the
* {@link Crouton}.
* @return the {@link Builder}.
*/
public Builder setImageResource(final int imageResId) {
this.imageResId = imageResId;
return this;
}
/** The {@link android.widget.ImageView.ScaleType} for the image. */
public Builder setImageScaleType(final ImageView.ScaleType imageScaleType) {
this.imageScaleType = imageScaleType;
return this;
}
/** The resource id for the padding for the crouton view's content. */
public Builder setPaddingDimensionResId(final int paddingResId) {
paddingDimensionResId = paddingResId;
return this;
}
/** The padding for the crouton view's content in pixels. */
public Builder setPaddingInPixels(final int padding) {
paddingInPixels = padding;
return this;
}
/** The text appearance resource id for the text. */
public Builder setTextAppearance(final int textAppearanceResId) {
this.textAppearanceResId = textAppearanceResId;
return this;
}
/**
* Set the textColorResourceId option for the {@link Crouton}.
*
* @param textColor The resource id of the text colorResourceId.
* @return the {@link Builder}.
*/
public Builder setTextColor(final int textColor) {
textColorResourceId = textColor;
return this;
}
/** The text shadow color resource id. */
public Builder setTextShadowColor(final int textShadowColorResId) {
this.textShadowColorResId = textShadowColorResId;
return this;
}
/** The text shadow horizontal offset. */
public Builder setTextShadowDx(final float textShadowDx) {
this.textShadowDx = textShadowDx;
return this;
}
/** The text shadow vertical offset. */
public Builder setTextShadowDy(final float textShadowDy) {
this.textShadowDy = textShadowDy;
return this;
}
/** The text shadow radius. */
public Builder setTextShadowRadius(final float textShadowRadius) {
this.textShadowRadius = textShadowRadius;
return this;
}
/** The text size in sp. */
public Builder setTextSize(final int textSize) {
this.textSize = textSize;
return this;
}
/**
* Set the isTileEnabled option for the {@link Crouton}.
*
* @param isTileEnabled <code>true</code> if you want the
* backgroundResourceId to be tiled, else <code>false</code>.
* @return the {@link Builder}.
*/
public Builder setTileEnabled(final boolean isTileEnabled) {
this.isTileEnabled = isTileEnabled;
return this;
}
/**
* Set the widthInPixels option for the {@link Crouton}.
*
* @param width The width of the {@link Crouton} in pixel. Can also be
* {@link LayoutParams#MATCH_PARENT} or
* {@link LayoutParams#WRAP_CONTENT}.
* @return the {@link Builder}.
*/
public Builder setWidth(final int width) {
widthInPixels = width;
return this;
}
/**
* Set the resource id for the width option for the {@link Crouton}.
*
* @param widthDimensionResId Resource ID of a dimension for the width
* of the {@link Crouton}.
* @return the {@link Builder}.
*/
public Builder setWidthDimensionResId(final int widthDimensionResId) {
this.widthDimensionResId = widthDimensionResId;
return this;
}
}
}

View File

@ -1,83 +0,0 @@
/*
* Copyright 2012 - 2013 Benjamin Weiss
* Copyright 2012 Neofonie Mobile GmbH
*
* 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 de.keyboardsurfer.android.widget.crouton;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
/** Builds the default animations for showing and hiding a {@link Crouton}. */
final class DefaultAnimationsBuilder {
private static final long DURATION = 400;
private static Animation slideInDownAnimation, slideOutUpAnimation;
private static int lastInAnimationHeight, lastOutAnimationHeight;
private DefaultAnimationsBuilder() {
/* no-op */
}
private static boolean areLastMeasuredAnimationHeightAndCurrentEqual(final int lastHeight, final View croutonView) {
return lastHeight == croutonView.getMeasuredHeight();
}
private static boolean areLastMeasuredInAnimationHeightAndCurrentEqual(final View croutonView) {
return areLastMeasuredAnimationHeightAndCurrentEqual(lastInAnimationHeight, croutonView);
}
private static boolean areLastMeasuredOutAnimationHeightAndCurrentEqual(final View croutonView) {
return areLastMeasuredAnimationHeightAndCurrentEqual(lastOutAnimationHeight, croutonView);
}
private static void setLastInAnimationHeight(final int lastInAnimationHeight) {
DefaultAnimationsBuilder.lastInAnimationHeight = lastInAnimationHeight;
}
private static void setLastOutAnimationHeight(final int lastOutAnimationHeight) {
DefaultAnimationsBuilder.lastOutAnimationHeight = lastOutAnimationHeight;
}
/**
* @param croutonView The croutonView which gets animated.
* @return The default Animation for a showing {@link Crouton}.
*/
static Animation buildDefaultSlideInDownAnimation(final View croutonView) {
if (!areLastMeasuredInAnimationHeightAndCurrentEqual(croutonView) || null == slideInDownAnimation) {
slideInDownAnimation = new TranslateAnimation(0, 0, // X: from, to
-croutonView.getMeasuredHeight(), 0 // Y: from, to
);
slideInDownAnimation.setDuration(DURATION);
setLastInAnimationHeight(croutonView.getMeasuredHeight());
}
return slideInDownAnimation;
}
/**
* @param croutonView The croutonView which gets animated.
* @return The default Animation for a hiding {@link Crouton}.
*/
static Animation buildDefaultSlideOutUpAnimation(final View croutonView) {
if (!areLastMeasuredOutAnimationHeightAndCurrentEqual(croutonView) || null == slideOutUpAnimation) {
slideOutUpAnimation = new TranslateAnimation(0, 0, // X: from, to
0, -croutonView.getMeasuredHeight() // Y: from, to
);
slideOutUpAnimation.setDuration(DURATION);
setLastOutAnimationHeight(croutonView.getMeasuredHeight());
}
return slideOutUpAnimation;
}
}

View File

@ -159,17 +159,6 @@ public interface Constants extends TwidereConstants {
public static final float DEFAULT_PULL_TO_REFRESH_SCROLL_DISTANCE = 0.3f;
public static final int HOLO_RED_DARK = 0xffcc0000;
public static final int HOLO_RED_LIGHT = 0xffff4444;
public static final int HOLO_ORANGE_DARK = 0xffff8800;
public static final int HOLO_ORANGE_LIGHT = 0xffffbb33;
public static final int HOLO_GREEN_DARK = 0xff669900;
public static final int HOLO_GREEN_LIGHT = 0xff99cc00;
public static final int HOLO_BLUE_DARK = 0xff0099cc;
public static final int HOLO_BLUE_LIGHT = 0xff33b5e5;
public static final int HOLO_PURPLE_DARK = 0xff9933cc;
public static final int HOLO_PURPLE_LIGHT = 0xffaa66cc;
public static final String ENTRY_PREFERENCES = "preferences.json";
public static final String ENTRY_NICKNAMES = "nicknames.json";
public static final String ENTRY_USER_COLORS = "user_colors.json";

View File

@ -25,44 +25,42 @@ import android.net.Uri;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.Window;
import de.keyboardsurfer.android.widget.crouton.Crouton;
import de.keyboardsurfer.android.widget.crouton.CroutonStyle;
import android.widget.Toast;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.fragment.BaseWebViewFragment;
public class BrowserActivity extends BaseSupportActivity {
private Uri mUri = Uri.parse("about:blank");
private Uri mUri = Uri.parse("about:blank");
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case MENU_HOME:
finish();
break;
}
return super.onOptionsItemSelected(item);
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case MENU_HOME:
finish();
break;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onCreate(final Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
super.onCreate(savedInstanceState);
getActionBar().setDisplayHomeAsUpEnabled(true);
mUri = getIntent().getData();
if (mUri == null) {
Crouton.showText(this, R.string.error_occurred, CroutonStyle.ALERT);
finish();
return;
}
final FragmentTransaction ft = getFragmentManager().beginTransaction();
final Fragment fragment = Fragment.instantiate(this, BaseWebViewFragment.class.getName());
final Bundle bundle = new Bundle();
bundle.putString(EXTRA_URI, mUri.toString());
fragment.setArguments(bundle);
ft.replace(android.R.id.content, fragment);
ft.commit();
}
@Override
protected void onCreate(final Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
super.onCreate(savedInstanceState);
getActionBar().setDisplayHomeAsUpEnabled(true);
mUri = getIntent().getData();
if (mUri == null) {
Toast.makeText(this, R.string.error_occurred, Toast.LENGTH_SHORT).show();
finish();
return;
}
final FragmentTransaction ft = getFragmentManager().beginTransaction();
final Fragment fragment = Fragment.instantiate(this, BaseWebViewFragment.class.getName());
final Bundle bundle = new Bundle();
bundle.putString(EXTRA_URI, mUri.toString());
fragment.setArguments(bundle);
ft.replace(android.R.id.content, fragment);
ft.commit();
}
}

View File

@ -122,9 +122,6 @@ import java.util.Collections;
import java.util.List;
import java.util.TreeSet;
import de.keyboardsurfer.android.widget.crouton.Crouton;
import de.keyboardsurfer.android.widget.crouton.CroutonStyle;
import static android.os.Environment.getExternalStorageState;
import static android.text.TextUtils.isEmpty;
import static org.mariotaku.twidere.model.ParcelableLocation.isValidLocation;
@ -718,7 +715,7 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa
}
mRecentLocation = location != null ? new ParcelableLocation(location) : null;
} else {
Crouton.showText(this, R.string.cannot_get_location, CroutonStyle.ALERT);
Toast.makeText(this, R.string.cannot_get_location, Toast.LENGTH_SHORT).show();
}
return provider != null;
}
@ -1370,7 +1367,7 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa
activity.setMenu();
activity.updateTextCount();
if (!result) {
Crouton.showText(activity, R.string.error_occurred, CroutonStyle.ALERT);
Toast.makeText(activity, R.string.error_occurred, Toast.LENGTH_SHORT).show();
}
}
@ -1416,7 +1413,7 @@ public class ComposeActivity extends BaseSupportDialogActivity implements TextWa
mActivity.removeAllMedia(Arrays.asList(mMedia));
mActivity.setMenu();
if (!result) {
Crouton.showText(mActivity, R.string.error_occurred, CroutonStyle.ALERT);
Toast.makeText(mActivity, R.string.error_occurred, Toast.LENGTH_SHORT).show();
}
}

View File

@ -56,6 +56,7 @@ import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.MarginLayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.FrameLayout.LayoutParams;
import android.widget.ProgressBar;
@ -72,6 +73,7 @@ import org.mariotaku.twidere.fragment.iface.IBaseFragment;
import org.mariotaku.twidere.fragment.iface.IBasePullToRefreshFragment;
import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface;
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback;
import org.mariotaku.twidere.fragment.support.AccountsDashboardFragment;
import org.mariotaku.twidere.fragment.support.DirectMessagesFragment;
import org.mariotaku.twidere.fragment.support.TrendsSuggectionsFragment;
import org.mariotaku.twidere.graphic.EmptyDrawable;
@ -92,6 +94,7 @@ import org.mariotaku.twidere.util.UnreadCountUtils;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.util.accessor.ViewAccessor;
import org.mariotaku.twidere.view.ExtendedViewPager;
import org.mariotaku.twidere.view.HomeContentFrameLayout;
import org.mariotaku.twidere.view.HomeSlidingMenu;
import org.mariotaku.twidere.view.LeftDrawerFrameLayout;
import org.mariotaku.twidere.view.RightDrawerFrameLayout;
@ -166,6 +169,7 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
private View mActionBarOverlay;
private LeftDrawerFrameLayout mLeftDrawerContainer;
private RightDrawerFrameLayout mRightDrawerContainer;
private HomeContentFrameLayout mHomeContentFrameLayout;
private Fragment mCurrentVisibleFragment;
private UpdateUnreadCountTask mUpdateUnreadCountTask;
@ -250,6 +254,7 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
mTabsContainer = findViewById(R.id.tabs_container);
mTabIndicator = (TabPagerIndicator) findViewById(R.id.main_tabs);
mActionBarOverlay = findViewById(R.id.actionbar_overlay);
mHomeContentFrameLayout = (HomeContentFrameLayout) findViewById(R.id.home_content);
}
@Override
@ -487,6 +492,10 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
@Override
protected void onCreate(final Bundle savedInstanceState) {
setUiOptions(getWindow());
final Window window = getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.requestFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
if (!isDatabaseReady(this)) {
Toast.makeText(this, R.string.preparing_database_toast, Toast.LENGTH_SHORT).show();
@ -576,6 +585,7 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
mTabIndicator.setStripColor(contrastColor);
mTabIndicator.setIconColor(contrastColor);
ActivityAccessor.setTaskDescription(this, new TaskDescriptionCompat(null, null, themeColor));
mHomeContentFrameLayout.setColor(themeColor, actionBarAlpha);
} else {
final int backgroundColor = ThemeUtils.getThemeBackgroundColor(mTabIndicator.getItemContext());
final int foregroundColor = ThemeUtils.getThemeForegroundColor(mTabIndicator.getItemContext());
@ -584,6 +594,7 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
homeActionButton.setIconColor(foregroundColor, Mode.SRC_ATOP);
mTabIndicator.setStripColor(themeColor);
mTabIndicator.setIconColor(foregroundColor);
mHomeContentFrameLayout.setColor(backgroundColor, actionBarAlpha);
}
mTabIndicator.setAlpha(actionBarAlpha / 255f);
mActionsButton.setAlpha(actionBarAlpha / 255f);
@ -904,6 +915,14 @@ public class HomeActivity extends BaseSupportActivity implements OnClickListener
notifyControlBarOffsetChanged();
}
public void setSystemWindowInsets(Rect insets) {
mHomeContentFrameLayout.setStatusBarHeight(insets.top);
final Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.left_drawer);
if (fragment instanceof AccountsDashboardFragment) {
((AccountsDashboardFragment) fragment).setStatusBarHeight(insets.top);
}
}
private static final class AccountChangeObserver extends ContentObserver {
private final HomeActivity mActivity;

View File

@ -152,11 +152,13 @@ public class LinkHandlerActivity extends BaseSupportActivity implements OnClickL
}
}
private void setUiOptions(final Window window, final Uri data) {
if (FlymeUtils.hasSmartBar()) {
window.setUiOptions(ActivityInfo.UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW);
} else {
window.setUiOptions(0);
private void setUiOptions(final Window window, final Uri uri) {
if (!FlymeUtils.hasSmartBar()) return;
switch (matchLinkId(uri)) {
case LINK_ID_USER: {
window.setUiOptions(ActivityInfo.UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW);
break;
}
}
}

View File

@ -43,6 +43,7 @@ import android.view.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Toast;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.SettingsActivity;
@ -60,9 +61,6 @@ import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.util.net.TwidereHostResolverFactory;
import org.mariotaku.twidere.util.net.TwidereHttpClientFactory;
import de.keyboardsurfer.android.widget.crouton.Crouton;
import de.keyboardsurfer.android.widget.crouton.CroutonLifecycleCallback;
import de.keyboardsurfer.android.widget.crouton.CroutonStyle;
import twitter4j.Twitter;
import twitter4j.TwitterConstants;
import twitter4j.TwitterException;
@ -87,8 +85,8 @@ import static org.mariotaku.twidere.util.Utils.isUserLoggedIn;
import static org.mariotaku.twidere.util.Utils.showErrorMessage;
import static org.mariotaku.twidere.util.Utils.trim;
public class SignInActivity extends BaseSupportActivity implements TwitterConstants, OnClickListener, TextWatcher,
CroutonLifecycleCallback {
public class SignInActivity extends BaseSupportActivity implements TwitterConstants, OnClickListener,
TextWatcher {
private static final String TWITTER_SIGNUP_URL = "https://twitter.com/signup";
private static final String EXTRA_API_LAST_CHANGE = "api_last_change";
@ -153,10 +151,8 @@ public class SignInActivity extends BaseSupportActivity implements TwitterConsta
@Override
public void onBackPressed() {
if (mTask != null && mTask.getStatus() == AsyncTask.Status.RUNNING && !mBackPressed) {
final CroutonStyle.Builder builder = new CroutonStyle.Builder(CroutonStyle.INFO);
final Crouton crouton = Crouton.makeText(this, R.string.signing_in_please_wait, builder.build());
crouton.setLifecycleCallback(this);
crouton.show();
final Toast toast = Toast.makeText(this, R.string.signing_in_please_wait, Toast.LENGTH_SHORT);
toast.show();
return;
}
if (mTask != null && mTask.getStatus() == AsyncTask.Status.RUNNING) {
@ -208,11 +204,6 @@ public class SignInActivity extends BaseSupportActivity implements TwitterConsta
super.onDestroy();
}
@Override
public void onDisplayed() {
mBackPressed = true;
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
@ -267,11 +258,6 @@ public class SignInActivity extends BaseSupportActivity implements TwitterConsta
return super.onPrepareOptionsMenu(menu);
}
@Override
public void onRemoved() {
mBackPressed = false;
}
@Override
public void onSaveInstanceState(final Bundle outState) {
saveEditedText();
@ -480,12 +466,12 @@ public class SignInActivity extends BaseSupportActivity implements TwitterConsta
startActivity(intent);
finish();
} else if (result.already_logged_in) {
Crouton.makeText(this, R.string.error_already_logged_in, CroutonStyle.ALERT).show();
Toast.makeText(this, R.string.error_already_logged_in, Toast.LENGTH_SHORT).show();
} else {
if (result.exception instanceof AuthenticityTokenException) {
Crouton.makeText(this, R.string.wrong_api_key, CroutonStyle.ALERT).show();
Toast.makeText(this, R.string.wrong_api_key, Toast.LENGTH_SHORT).show();
} else if (result.exception instanceof WrongUserPassException) {
Crouton.makeText(this, R.string.wrong_username_password, CroutonStyle.ALERT).show();
Toast.makeText(this, R.string.wrong_username_password, Toast.LENGTH_SHORT).show();
} else if (result.exception instanceof AuthenticationException) {
showErrorMessage(this, getString(R.string.action_signing_in), result.exception.getCause(), true);
} else {

View File

@ -64,10 +64,6 @@ import org.mariotaku.twidere.view.iface.IExtendedView.OnSizeChangedListener;
import java.io.File;
import de.keyboardsurfer.android.widget.crouton.Crouton;
import de.keyboardsurfer.android.widget.crouton.CroutonLifecycleCallback;
import de.keyboardsurfer.android.widget.crouton.CroutonStyle;
import static android.text.TextUtils.isEmpty;
import static org.mariotaku.twidere.util.Utils.createPickImageIntent;
import static org.mariotaku.twidere.util.Utils.createTakePhotoIntent;
@ -75,7 +71,7 @@ import static org.mariotaku.twidere.util.Utils.isMyAccount;
import static org.mariotaku.twidere.util.Utils.showErrorMessage;
public class UserProfileEditorActivity extends BaseSupportActivity implements OnSizeChangedListener, TextWatcher,
OnClickListener, CroutonLifecycleCallback, LoaderCallbacks<SingleResponse<ParcelableUser>> {
OnClickListener, LoaderCallbacks<SingleResponse<ParcelableUser>> {
private static final int LOADER_ID_USER = 1;
@ -196,10 +192,8 @@ public class UserProfileEditorActivity extends BaseSupportActivity implements On
@Override
public void onBackPressed() {
if (mHasUnsavedChanges() && !mBackPressed) {
final CroutonStyle.Builder builder = new CroutonStyle.Builder(CroutonStyle.INFO);
final Crouton crouton = Crouton.makeText(this, R.string.unsaved_change_back_pressed, builder.build());
crouton.setLifecycleCallback(this);
crouton.show();
final Toast toast = Toast.makeText(this, R.string.unsaved_change_back_pressed, Toast.LENGTH_SHORT);
toast.show();
return;
}
super.onBackPressed();
@ -266,11 +260,6 @@ public class UserProfileEditorActivity extends BaseSupportActivity implements On
return true;
}
@Override
public void onDisplayed() {
mBackPressed = true;
}
@Override
public void onLoaderReset(final Loader<SingleResponse<ParcelableUser>> loader) {
@ -317,11 +306,6 @@ public class UserProfileEditorActivity extends BaseSupportActivity implements On
return super.onPrepareOptionsMenu(menu);
}
@Override
public void onRemoved() {
mBackPressed = false;
}
@Override
public void onSizeChanged(final View view, final int w, final int h, final int oldw, final int oldh) {
}

View File

@ -46,9 +46,12 @@ import org.mariotaku.twidere.view.ForegroundColorView;
public final class ColorPickerDialog extends AlertDialog implements Constants, OnColorChangedListener {
private final static int[] COLORS = {HOLO_RED_DARK, HOLO_RED_LIGHT, HOLO_ORANGE_DARK, HOLO_ORANGE_LIGHT,
HOLO_GREEN_LIGHT, HOLO_GREEN_DARK, HOLO_BLUE_LIGHT, HOLO_BLUE_DARK, HOLO_PURPLE_DARK, HOLO_PURPLE_LIGHT,
Color.WHITE};
private final static int[] COLORS = {R.color.material_red, R.color.material_pink,
R.color.material_purple, R.color.material_deep_purple, R.color.material_indigo,
R.color.material_blue, R.color.material_light_blue, R.color.material_cyan,
R.color.material_teal, R.color.material_green, R.color.material_light_green,
R.color.material_lime, R.color.material_yellow, R.color.material_amber,
R.color.material_orange, R.color.material_deep_orange};
private final ColorsAdapter mColorsAdapter;
@ -127,8 +130,9 @@ public final class ColorPickerDialog extends AlertDialog implements Constants, O
}
private void initColors() {
for (final int color : COLORS) {
mColorsAdapter.add(color);
final Resources resources = getContext().getResources();
for (final int colorRes : COLORS) {
mColorsAdapter.add(resources.getColor(colorRes));
}
}

View File

@ -99,6 +99,7 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement
private ImageView mAccountProfileBannerView, mAccountProfileImageView;
private TextView mAccountProfileNameView, mAccountProfileScreenNameView;
private Switch mAccountsToggle;
private View mAccountProfileContainer;
private Context mThemedContext;
private ImageLoaderWrapper mImageLoader;
@ -124,6 +125,7 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement
layoutManager.setStackFromEnd(true);
mAccountsSelector.setLayoutManager(layoutManager);
mAccountsSelector.setAdapter(mAccountsAdapter);
mAccountProfileContainer = mAccountSelectorView.findViewById(R.id.profile_container);
mAccountProfileImageView = (ImageView) mAccountSelectorView.findViewById(R.id.profile_image);
mAccountProfileBannerView = (ImageView) mAccountSelectorView.findViewById(R.id.profile_banner);
mAccountProfileNameView = (TextView) mAccountSelectorView.findViewById(R.id.name);
@ -258,8 +260,6 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement
@Override
public void onLoaderReset(final Loader<Cursor> loader) {
//TODO
// mAccountsAdapter.changeCursor(null);
mAccountsAdapter.changeCursor(null);
}
@ -269,8 +269,6 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement
data.moveToFirst();
mAccountsAdapter.setSelectedAccountId(data.getLong(data.getColumnIndex(Accounts.ACCOUNT_ID)));
}
//TODO
// mAccountsAdapter.changeCursor(data);
mAccountsAdapter.changeCursor(data);
updateAccountOptionsSeparatorLabel();
updateDefaultAccountState();
@ -355,6 +353,10 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement
mResolver.update(Accounts.CONTENT_URI, values, where, null);
}
public void setStatusBarHeight(int height) {
mAccountProfileContainer.setPadding(0, height, 0, 0);
}
private static final class AccountOptionsAdapter extends OptionItemsAdapter {
@ -434,6 +436,7 @@ public class AccountsDashboardFragment extends BaseSupportListFragment implement
if (c.getLong(mIndices.account_id) == mSelectedAccountId) {
c.moveToNext();
}
holder.itemView.setAlpha(c.getInt(mIndices.is_activated) == 1 ? 1 : 0.5f);
mImageLoader.displayProfileImage(holder.icon, c.getString(mIndices.profile_image_url));
}

View File

@ -51,7 +51,6 @@ import android.util.Log;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View;
@ -70,7 +69,6 @@ import org.mariotaku.refreshnow.widget.RefreshMode;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.support.AccountSelectorActivity;
import org.mariotaku.twidere.activity.support.ColorPickerDialogActivity;
import org.mariotaku.twidere.activity.support.LinkHandlerActivity;
import org.mariotaku.twidere.adapter.ParcelableStatusesListAdapter;
import org.mariotaku.twidere.adapter.iface.IStatusesListAdapter;
import org.mariotaku.twidere.app.TwidereApplication;
@ -84,7 +82,6 @@ import org.mariotaku.twidere.task.AsyncTask;
import org.mariotaku.twidere.text.method.StatusContentMovementMethod;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.ClipboardUtils;
import org.mariotaku.twidere.util.FlymeUtils;
import org.mariotaku.twidere.util.ImageLoaderWrapper;
import org.mariotaku.twidere.util.MediaPreviewUtils;
import org.mariotaku.twidere.util.MediaPreviewUtils.OnMediaClickListener;
@ -342,12 +339,8 @@ public class StatusFragment extends ParcelableStatusesListFragment implements On
args.putLong(EXTRA_ACCOUNT_ID, status.account_id);
args.putLong(EXTRA_STATUS_ID, status.id);
args.putParcelable(EXTRA_STATUS, status);
if (shouldUseNativeMenu()) {
getActivity().supportInvalidateOptionsMenu();
} else {
setMenuForStatus(getActivity(), mMenuBar.getMenu(), status);
mMenuBar.show();
}
setMenuForStatus(getActivity(), mMenuBar.getMenu(), status);
mMenuBar.show();
updateUserColor();
mProfileView.drawEnd(getAccountColor(getActivity(), status.account_id));
@ -461,7 +454,6 @@ public class StatusFragment extends ParcelableStatusesListFragment implements On
super.onActivityCreated(savedInstanceState);
mLocale = getResources().getConfiguration().locale;
setRefreshMode(shouldEnablePullToRefresh() ? RefreshMode.BOTH : RefreshMode.NONE);
setHasOptionsMenu(shouldUseNativeMenu());
setListShownNoAnimation(true);
mHandler = new Handler();
mListView = getListView();
@ -483,7 +475,6 @@ public class StatusFragment extends ParcelableStatusesListFragment implements On
mRepliesContainer.setOnClickListener(this);
mRetweetsContainer.setOnClickListener(this);
mFavoritesContainer.setOnClickListener(this);
mMenuBar.setVisibility(shouldUseNativeMenu() ? View.GONE : View.VISIBLE);
mMenuBar.inflate(R.menu.menu_status);
mMenuBar.setIsBottomBar(true);
mMenuBar.setOnMenuItemClickListener(mMenuItemClickListener);
@ -581,12 +572,6 @@ public class StatusFragment extends ParcelableStatusesListFragment implements On
return true;
}
@Override
public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
if (!shouldUseNativeMenu()) return;
inflater.inflate(R.menu.menu_status, menu);
}
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_details_page, container, false);
@ -662,12 +647,6 @@ public class StatusFragment extends ParcelableStatusesListFragment implements On
openImageDirectly(getActivity(), status.account_id, media.url);
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
if (!shouldUseNativeMenu() || mStatus == null) return false;
return handleMenuItemClick(item);
}
@Override
public boolean onPrepareActionMode(final ActionMode mode, final Menu menu) {
final int start = mTextView.getSelectionStart(), end = mTextView.getSelectionEnd();
@ -678,12 +657,6 @@ public class StatusFragment extends ParcelableStatusesListFragment implements On
return false;
}
@Override
public void onPrepareOptionsMenu(final Menu menu) {
if (!shouldUseNativeMenu() || mStatus == null) return;
setMenuForStatus(getActivity(), menu, mStatus);
}
@Override
public void onScroll(final AbsListView view, final int firstVisibleItem, final int visibleItemCount,
final int totalItemCount) {
@ -937,11 +910,6 @@ public class StatusFragment extends ParcelableStatusesListFragment implements On
}
}
private boolean shouldUseNativeMenu() {
final boolean isInLinkHandler = getActivity() instanceof LinkHandlerActivity;
return isInLinkHandler && FlymeUtils.hasSmartBar();
}
private void showConversation() {
if (mConversationTask != null && mConversationTask.getStatus() == AsyncTask.Status.RUNNING) {
mConversationTask.cancel(true);

View File

@ -26,6 +26,7 @@ import android.net.Uri;
import android.text.TextUtils;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
public class AccountPreferences implements Constants {
@ -46,7 +47,7 @@ public class AccountPreferences implements Constants {
public int getDefaultNotificationLightColor() {
final Account a = Account.getAccount(mContext, mAccountId);
return a != null ? a.color : HOLO_BLUE_LIGHT;
return a != null ? a.color : mContext.getResources().getColor(R.color.material_light_blue);
}
public int getDirectMessagesNotificationType() {

View File

@ -179,11 +179,11 @@ public abstract class AccountsListPreference extends PreferenceCategory implemen
@Override
protected void onBindView(@NonNull final View view) {
super.onBindView(view);
final View iconView = view.findViewById(android.R.id.icon);
if (iconView instanceof ImageView) {
final ImageView imageView = (ImageView) iconView;
imageView.setScaleType(ScaleType.CENTER_CROP);
}
// final View iconView = view.findViewById(android.R.id.icon);
// if (iconView instanceof ImageView) {
// final ImageView imageView = (ImageView) iconView;
// imageView.setScaleType(ScaleType.CENTER_CROP);
// }
final View titleView = view.findViewById(android.R.id.title);
if (titleView instanceof TextView) {
((TextView) titleView).setSingleLine(true);

View File

@ -111,7 +111,7 @@ public class ColorPickerPreference extends Preference implements DialogInterface
protected void onBindView(@NonNull final View view) {
super.onBindView(view);
final ImageView imageView = (ImageView) view.findViewById(R.id.color);
imageView.setImageBitmap(ColorPickerView.getColorPreviewBitmap(getContext(), getValue()));
imageView.setImageBitmap(ColorPickerView.getColorPreviewBitmap(getContext(), getValue(), false));
}
@Override

View File

@ -86,7 +86,7 @@ public class ThemePreviewPreference extends Preference implements Constants, OnS
final View windowContentOverlayView = view.findViewById(R.id.theme_preview_window_content_overlay);
final View actionBarView = view.findViewById(R.id.actionbar);
final TextView actionBarTitleView = (TextView) view.findViewById(R.id.actionbar_title);
final MenuBar actionBarSplitView = (MenuBar) view.findViewById(R.id.actionbar_split);
final MenuBar actionBarSplitView = (MenuBar) view.findViewById(R.id.menu_bar);
final View statusContentView = view.findViewById(R.id.theme_preview_status_content);
final int defaultTextSize = getDefaultTextSize(context);
@ -95,7 +95,6 @@ public class ThemePreviewPreference extends Preference implements Constants, OnS
ViewAccessor.setBackground(windowBackgroundView, ThemeUtils.getWindowBackground(context));
ViewAccessor.setBackground(windowContentOverlayView, ThemeUtils.getWindowContentOverlay(context));
ViewAccessor.setBackground(actionBarView, ThemeUtils.getActionBarBackground(context, themeRes));
ViewAccessor.setBackground(actionBarSplitView, ThemeUtils.getActionBarSplitBackground(context, themeRes));
actionBarTitleView.setTextAppearance(context, titleTextAppearance);
actionBarSplitView.setEnabled(false);
@ -111,17 +110,13 @@ public class ThemePreviewPreference extends Preference implements Constants, OnS
final TextView screenNameView = (TextView) statusContentView.findViewById(R.id.screen_name);
final TextView textView = (TextView) statusContentView.findViewById(R.id.text);
final TextView timeSourceView = (TextView) statusContentView.findViewById(R.id.time_source);
// final TextView retweetView = (TextView)
// statusContentView.findViewById(R.id.retweet_view);
nameView.setTextSize(defaultTextSize * 1.25f);
textView.setTextSize(defaultTextSize * 1.25f);
screenNameView.setTextSize(defaultTextSize * 0.85f);
timeSourceView.setTextSize(defaultTextSize * 0.85f);
// retweetView.setTextSize(defaultTextSize * 0.85f);
profileView.setBackgroundResource(0);
// retweetView.setBackgroundResource(0);
textView.setTextIsSelectable(false);
profileImageView.setImageResource(R.drawable.ic_launcher);

View File

@ -27,6 +27,7 @@ import android.os.Bundle;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.twitter.Extractor;
@ -48,9 +49,6 @@ import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import de.keyboardsurfer.android.widget.crouton.Crouton;
import de.keyboardsurfer.android.widget.crouton.CroutonStyle;
import static org.mariotaku.twidere.util.Utils.getAccountScreenNames;
import static org.mariotaku.twidere.util.content.ContentResolverUtils.bulkDelete;
import static org.mariotaku.twidere.util.content.ContentResolverUtils.bulkInsert;
@ -154,7 +152,7 @@ public class MultiSelectEventHandler implements Constants, ActionMode.Callback,
}
bulkDelete(resolver, Filters.Users.CONTENT_URI, Filters.Users.USER_ID, userIds, null, false);
bulkInsert(resolver, Filters.Users.CONTENT_URI, valuesList);
Crouton.showText(mActivity, R.string.message_users_muted, CroutonStyle.INFO);
Toast.makeText(mActivity, R.string.message_users_muted, Toast.LENGTH_SHORT).show();
mode.finish();
mActivity.sendBroadcast(new Intent(BROADCAST_MULTI_MUTESTATE_CHANGED));
break;

View File

@ -19,9 +19,6 @@
package org.mariotaku.twidere.util;
import static android.text.TextUtils.isEmpty;
import static org.mariotaku.twidere.util.Utils.getImageMimeType;
import android.app.Activity;
import android.app.DialogFragment;
import android.app.FragmentManager;
@ -31,9 +28,7 @@ import android.os.AsyncTask;
import android.os.Environment;
import android.util.Log;
import android.webkit.MimeTypeMap;
import de.keyboardsurfer.android.widget.crouton.Crouton;
import de.keyboardsurfer.android.widget.crouton.CroutonStyle;
import android.widget.Toast;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
@ -42,83 +37,85 @@ import org.mariotaku.twidere.fragment.ProgressDialogFragment;
import java.io.File;
import java.io.IOException;
import static android.text.TextUtils.isEmpty;
import static org.mariotaku.twidere.util.Utils.getImageMimeType;
public class SaveImageTask extends AsyncTask<Void, Void, File> implements Constants {
private static final String PROGRESS_FRAGMENT_TAG = "progress";
private static final String PROGRESS_FRAGMENT_TAG = "progress";
private final File src;
private final Activity activity;
private final File src;
private final Activity activity;
public SaveImageTask(final Activity activity, final File src) {
this.activity = activity;
this.src = src;
}
public SaveImageTask(final Activity activity, final File src) {
this.activity = activity;
this.src = src;
}
@Override
protected File doInBackground(final Void... args) {
if (src == null) return null;
return saveImage(activity, src);
}
@Override
protected File doInBackground(final Void... args) {
if (src == null) return null;
return saveImage(activity, src);
}
@Override
protected void onCancelled() {
final FragmentManager fm = activity.getFragmentManager();
final DialogFragment fragment = (DialogFragment) fm.findFragmentByTag(PROGRESS_FRAGMENT_TAG);
if (fragment != null && fragment.isVisible()) {
fragment.dismiss();
}
super.onCancelled();
}
@Override
protected void onCancelled() {
final FragmentManager fm = activity.getFragmentManager();
final DialogFragment fragment = (DialogFragment) fm.findFragmentByTag(PROGRESS_FRAGMENT_TAG);
if (fragment != null && fragment.isVisible()) {
fragment.dismiss();
}
super.onCancelled();
}
@Override
protected void onPostExecute(final File result) {
final FragmentManager fm = activity.getFragmentManager();
final DialogFragment fragment = (DialogFragment) fm.findFragmentByTag(PROGRESS_FRAGMENT_TAG);
if (fragment != null) {
fragment.dismiss();
}
super.onPostExecute(result);
if (result != null && result.exists()) {
Crouton.showText(activity, activity.getString(R.string.file_saved_to, result.getPath()),
CroutonStyle.CONFIRM);
} else {
Crouton.showText(activity, R.string.error_occurred, CroutonStyle.ALERT);
}
}
@Override
protected void onPostExecute(final File result) {
final FragmentManager fm = activity.getFragmentManager();
final DialogFragment fragment = (DialogFragment) fm.findFragmentByTag(PROGRESS_FRAGMENT_TAG);
if (fragment != null) {
fragment.dismiss();
}
super.onPostExecute(result);
if (result != null && result.exists()) {
Toast.makeText(activity, R.string.saved_to_gallery, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(activity, R.string.error_occurred, Toast.LENGTH_SHORT).show();
}
}
@Override
protected void onPreExecute() {
final DialogFragment fragment = new ProgressDialogFragment();
fragment.setCancelable(false);
fragment.show(activity.getFragmentManager(), PROGRESS_FRAGMENT_TAG);
super.onPreExecute();
}
@Override
protected void onPreExecute() {
final DialogFragment fragment = new ProgressDialogFragment();
fragment.setCancelable(false);
fragment.show(activity.getFragmentManager(), PROGRESS_FRAGMENT_TAG);
super.onPreExecute();
}
public static File saveImage(final Context context, final File image_file) {
if (context == null && image_file == null) return null;
try {
final String name = image_file.getName();
if (isEmpty(name)) return null;
final String mimeType = getImageMimeType(image_file);
final MimeTypeMap map = MimeTypeMap.getSingleton();
final String extension = map.getExtensionFromMimeType(mimeType);
if (extension == null) return null;
final String nameToSave = name.indexOf(".") != -1 ? name : name + "." + extension;
final File pubDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
if (pubDir == null) return null;
final File saveDir = new File(pubDir, "Twidere");
if (!saveDir.isDirectory() && !saveDir.mkdirs()) return null;
final File saveFile = new File(saveDir, nameToSave);
FileUtils.copyFile(image_file, saveFile);
if (mimeType != null) {
MediaScannerConnection.scanFile(context, new String[] { saveFile.getPath() },
new String[] { mimeType }, null);
}
return saveFile;
} catch (final IOException e) {
Log.w(LOGTAG, "Failed to save file", e);
return null;
}
}
public static File saveImage(final Context context, final File image_file) {
if (context == null && image_file == null) return null;
try {
final String name = image_file.getName();
if (isEmpty(name)) return null;
final String mimeType = getImageMimeType(image_file);
final MimeTypeMap map = MimeTypeMap.getSingleton();
final String extension = map.getExtensionFromMimeType(mimeType);
if (extension == null) return null;
final String nameToSave = name.indexOf(".") != -1 ? name : name + "." + extension;
final File pubDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
if (pubDir == null) return null;
final File saveDir = new File(pubDir, "Twidere");
if (!saveDir.isDirectory() && !saveDir.mkdirs()) return null;
final File saveFile = new File(saveDir, nameToSave);
FileUtils.copyFile(image_file, saveFile);
if (mimeType != null) {
MediaScannerConnection.scanFile(context, new String[]{saveFile.getPath()},
new String[]{mimeType}, null);
}
return saveFile;
} catch (final IOException e) {
Log.w(LOGTAG, "Failed to save file", e);
return null;
}
}
}

View File

@ -207,9 +207,6 @@ import java.util.regex.Pattern;
import javax.net.ssl.SSLException;
import de.keyboardsurfer.android.widget.crouton.Crouton;
import de.keyboardsurfer.android.widget.crouton.CroutonConfiguration;
import de.keyboardsurfer.android.widget.crouton.CroutonStyle;
import edu.ucdavis.earlybird.UCDService;
import twitter4j.DirectMessage;
import twitter4j.EntitySupport;
@ -1604,11 +1601,11 @@ public final class Utils implements Constants, TwitterConstants {
public static int getCardHighlightColor(final boolean is_mention, final boolean is_favorite,
final boolean is_retweet) {
if (is_mention)
return HOLO_BLUE_LIGHT;
else if (is_favorite)
return HOLO_ORANGE_LIGHT;
else if (is_retweet) return HOLO_GREEN_LIGHT;
// if (is_mention)
// return HOLO_BLUE_LIGHT;
// else if (is_favorite)
// return HOLO_ORANGE_LIGHT;
// else if (is_retweet) return HOLO_GREEN_LIGHT;
return Color.TRANSPARENT;
}
@ -3606,34 +3603,26 @@ public final class Utils implements Constants, TwitterConstants {
return mPreferences.getBoolean(KEY_STOP_AUTO_REFRESH_WHEN_BATTERY_LOW, true);
}
public static void showErrorMessage(final Context context, final CharSequence message, final boolean long_message) {
public static void showErrorMessage(final Context context, final CharSequence message, final boolean longMessage) {
if (context == null) return;
if (context instanceof Activity) {
final Crouton crouton = Crouton.makeText((Activity) context, message, CroutonStyle.ALERT);
final CroutonConfiguration.Builder cb = new CroutonConfiguration.Builder();
cb.setDuration(long_message ? CroutonConfiguration.DURATION_LONG : CroutonConfiguration.DURATION_SHORT);
crouton.setConfiguration(cb.build());
crouton.show();
} else {
final Toast toast = Toast.makeText(context, message, long_message ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT);
toast.show();
}
final Toast toast = Toast.makeText(context, message, longMessage ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT);
toast.show();
}
public static void showErrorMessage(final Context context, final CharSequence action, final CharSequence message,
final boolean long_message) {
public static void showErrorMessage(final Context context, final CharSequence action,
final CharSequence message, final boolean longMessage) {
if (context == null) return;
showErrorMessage(context, getErrorMessage(context, message), long_message);
showErrorMessage(context, getErrorMessage(context, message), longMessage);
}
public static void showErrorMessage(final Context context, final CharSequence action, final Throwable t,
final boolean long_message) {
public static void showErrorMessage(final Context context, final CharSequence action,
final Throwable t, final boolean longMessage) {
if (context == null) return;
if (t instanceof TwitterException) {
showTwitterErrorMessage(context, action, (TwitterException) t, long_message);
showTwitterErrorMessage(context, action, (TwitterException) t, longMessage);
return;
}
showErrorMessage(context, getErrorMessage(context, action, t), long_message);
showErrorMessage(context, getErrorMessage(context, action, t), longMessage);
}
public static void showErrorMessage(final Context context, final int action, final String desc,
@ -3650,16 +3639,8 @@ public final class Utils implements Constants, TwitterConstants {
public static void showInfoMessage(final Context context, final CharSequence message, final boolean long_message) {
if (context == null || isEmpty(message)) return;
// if (context instanceof Activity) {
// final Crouton crouton = Crouton.makeText((Activity) context, message, CroutonStyle.INFO);
// final CroutonConfiguration.Builder cb = new CroutonConfiguration.Builder();
// cb.setDuration(long_message ? CroutonConfiguration.DURATION_LONG : CroutonConfiguration.DURATION_SHORT);
// crouton.setConfiguration(cb.build());
// crouton.show();
// } else {
final Toast toast = Toast.makeText(context, message, long_message ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT);
toast.show();
// }
}
public static void showInfoMessage(final Context context, final int resId, final boolean long_message) {
@ -3696,18 +3677,10 @@ public final class Utils implements Constants, TwitterConstants {
cheatSheet.show();
}
public static void showOkMessage(final Context context, final CharSequence message, final boolean long_message) {
public static void showOkMessage(final Context context, final CharSequence message, final boolean longMessage) {
if (context == null || isEmpty(message)) return;
if (context instanceof Activity) {
final Crouton crouton = Crouton.makeText((Activity) context, message, CroutonStyle.CONFIRM);
final CroutonConfiguration.Builder cb = new CroutonConfiguration.Builder();
cb.setDuration(long_message ? CroutonConfiguration.DURATION_LONG : CroutonConfiguration.DURATION_SHORT);
crouton.setConfiguration(cb.build());
crouton.show();
} else {
final Toast toast = Toast.makeText(context, message, long_message ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT);
toast.show();
}
final Toast toast = Toast.makeText(context, message, longMessage ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT);
toast.show();
}
public static void showOkMessage(final Context context, final int resId, final boolean long_message) {
@ -3758,18 +3731,10 @@ public final class Utils implements Constants, TwitterConstants {
showErrorMessage(context, message, long_message);
}
public static void showWarnMessage(final Context context, final CharSequence message, final boolean long_message) {
public static void showWarnMessage(final Context context, final CharSequence message, final boolean longMessage) {
if (context == null || isEmpty(message)) return;
if (context instanceof Activity) {
final Crouton crouton = Crouton.makeText((Activity) context, message, CroutonStyle.WARN);
final CroutonConfiguration.Builder cb = new CroutonConfiguration.Builder();
cb.setDuration(long_message ? CroutonConfiguration.DURATION_LONG : CroutonConfiguration.DURATION_SHORT);
crouton.setConfiguration(cb.build());
crouton.show();
} else {
final Toast toast = Toast.makeText(context, message, long_message ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT);
toast.show();
}
final Toast toast = Toast.makeText(context, message, longMessage ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT);
toast.show();
}
public static void showWarnMessage(final Context context, final int resId, final boolean long_message) {

View File

@ -0,0 +1,69 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.widget.FrameLayout;
/**
* Created by mariotaku on 14/11/26.
*/
public class HomeContentFrameLayout extends FrameLayout {
private final Paint mPaint;
private int mStatusBarHeight;
public HomeContentFrameLayout(Context context) {
this(context, null);
}
public HomeContentFrameLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public HomeContentFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
setWillNotDraw(false);
}
public void setColor(int color, int alpha) {
mPaint.setColor(color);
mPaint.setAlpha(alpha);
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawRect(0, 0, canvas.getWidth(), mStatusBarHeight, mPaint);
}
public void setStatusBarHeight(int height) {
mStatusBarHeight = height;
setPadding(0, height, 0, 0);
invalidate();
}
}

View File

@ -56,6 +56,7 @@ public class HomeSlidingMenu extends SlidingMenu implements Constants {
@Override
protected boolean fitSystemWindows(Rect insets) {
mActivity.setSystemWindowInsets(insets);
return false;
}

View File

@ -66,7 +66,7 @@ public class DirectMessageConversationViewHolder extends CardViewHolder {
lp.gravity = isOutgoing ? Gravity.RIGHT : Gravity.LEFT;
message_content.setLayoutParams(lp);
if (isOutgoing) {
message_content.setBubbleColorFilter(new LightingColorFilter(0xFFC0FFC4, 0x00102015));
message_content.setBubbleColorFilter(new LightingColorFilter(0xFF90B096, 0x00203324));
} else {
message_content.clearBubbleColorFilter();
}

View File

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<merge
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<org.mariotaku.twidere.view.HomeSlidingMenu
android:id="@+id/home_menu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:viewAbove="@layout/activity_home_content"/>
</merge>

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
<org.mariotaku.twidere.view.HomeContentFrameLayout
android:id="@+id/home_content"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
@ -22,8 +23,7 @@
style="?android:actionBarStyle"
android:layout_width="match_parent"
android:layout_height="?android:actionBarSize"
android:layout_weight="0"
android:theme="?android:actionBarWidgetTheme"/>
android:layout_weight="0"/>
<View
android:id="@+id/actionbar_overlay"
@ -34,4 +34,4 @@
</LinearLayout>
<include layout="@layout/layout_home_actions_button"/>
</FrameLayout>
</org.mariotaku.twidere.view.HomeContentFrameLayout>

View File

@ -10,72 +10,77 @@
android:layout_height="match_parent"
android:layout_alignBottom="@id/profile_container"
android:layout_alignTop="@id/profile_container"
android:alpha="0.33"
android:alpha="0.5"
android:contentDescription="@string/profile_banner"
android:scaleType="centerCrop"/>
<RelativeLayout
<FrameLayout
android:id="@+id/profile_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/element_spacing_normal"
android:paddingLeft="@dimen/element_spacing_large"
android:paddingRight="@dimen/element_spacing_large"
android:paddingTop="@dimen/element_spacing_normal">
android:layout_height="wrap_content">
<org.mariotaku.twidere.view.CircularImageView
android:id="@+id/profile_image"
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.support.v7.widget.RecyclerView
android:id="@+id/account_selector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/profile_image"
android:layout_alignParentRight="true"
android:layout_alignTop="@id/profile_image"
android:layout_marginBottom="@dimen/element_spacing_large"
android:layout_toRightOf="@id/profile_image"/>
<LinearLayout
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_below="@id/profile_image"
android:gravity="center_vertical"
android:orientation="horizontal">
android:layout_height="wrap_content"
android:paddingBottom="@dimen/element_spacing_normal"
android:paddingLeft="@dimen/element_spacing_large"
android:paddingRight="@dimen/element_spacing_large"
android:paddingTop="@dimen/element_spacing_normal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<org.mariotaku.twidere.view.CircularImageView
android:id="@+id/profile_image"
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"/>
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:textAppearanceSmall"
android:textColor="?android:textColorPrimary"
android:textStyle="bold"/>
<TextView
android:id="@+id/screen_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:textAppearanceSmall"/>
</LinearLayout>
<Switch
android:id="@+id/toggle"
<android.support.v7.widget.RecyclerView
android:id="@+id/account_selector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"/>
</LinearLayout>
</RelativeLayout>
android:layout_alignBottom="@id/profile_image"
android:layout_alignParentRight="true"
android:layout_alignTop="@id/profile_image"
android:layout_marginBottom="@dimen/element_spacing_large"
android:layout_toRightOf="@id/profile_image"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_below="@id/profile_image"
android:gravity="center_vertical"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:textAppearanceSmall"
android:textColor="?android:textColorPrimary"
android:textStyle="bold"/>
<TextView
android:id="@+id/screen_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:textAppearanceSmall"/>
</LinearLayout>
<Switch
android:id="@+id/toggle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"/>
</LinearLayout>
</RelativeLayout>
</FrameLayout>
</RelativeLayout>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<View
android:id="@+id/theme_preview_window_wallpaper"
@ -33,7 +32,7 @@
android:orientation="horizontal">
<TextView
<org.mariotaku.twidere.view.ActionBarTitleView
android:id="@+id/actionbar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@ -22,11 +22,4 @@
android:layout_alignTop="@+id/status_content"/>
</RelativeLayout>
<org.mariotaku.twidere.view.TwidereMenuBar
android:id="@+id/actionbar_split"
android:layout_width="match_parent"
android:layout_height="?android:actionBarSize"
android:layout_weight="0"
android:max="@integer/max_action_buttons_bottom"/>
</LinearLayout>

View File

@ -1,3 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
</resources>

View File

@ -0,0 +1,21 @@
<resources>
<color name="material_red">#F44336</color>
<color name="material_pink">#E91E63</color>
<color name="material_purple">#9C27B0</color>
<color name="material_deep_purple">#673AB7</color>
<color name="material_indigo">#3F51B5</color>
<color name="material_blue">#2196F3</color>
<color name="material_light_blue">#03A9F4</color>
<color name="material_cyan">#00BCD4</color>
<color name="material_teal">#009688</color>
<color name="material_green">#4CAF50</color>
<color name="material_light_green">#8BC34A</color>
<color name="material_lime">#CDDC39</color>
<color name="material_yellow">#FFEB3B</color>
<color name="material_amber">#FFC107</color>
<color name="material_orange">#FF9800</color>
<color name="material_deep_orange">#FF5722</color>
<color name="material_brown">#796648</color>
<color name="material_grey">#9E9E9E</color>
<color name="material_blue_grey">#607D8B</color>
</resources>

View File

@ -159,6 +159,7 @@
<string name="save_as">Save as</string>
<string name="please_wait">Please wait.</string>
<string name="file_saved_to">File saved to <xliff:g id="filename">%s</xliff:g> .</string>
<string name="saved_to_gallery">Saved to gallery.</string>
<string name="proxy">Proxy</string>
<string name="http_proxy">HTTP Proxy</string>
<string name="http_proxy_summary">Use HTTP Proxy for all network requests.</string>