I have tried to implement a custom MaterialDatePicker calendar, but this method asks for a DateSelector, and I ask what is a DateSelector?
/**
* Sets the Builder's selection manager to the provided {#link DateSelector}.
*
* #hide
*/
#RestrictTo(LIBRARY_GROUP)
#NonNull
public static <S> Builder<S> customDatePicker(#NonNull DateSelector<S> dateSelector) {
return new Builder<>(dateSelector);
}
This says the description of the Interface DateSelector
/**
* Interface for users of {#link MaterialCalendar<S>} to control how the Calendar displays and
* returns selections.
*
* <p>Implementors must implement {#link Parcelable} so that selection can be maintained through
* Lifecycle events (e.g., Fragment destruction).
*
* <p>Dates are represented as times in UTC milliseconds.
*
* #param <S> The type of item available when cells are selected in the {#link AdapterView}
* #hide
*/
Related
I am asking this because of the confusion about the created state:
From docs on onCreate():
You must implement this callback, which fires when the system first creates the activity. On activity creation, the activity enters the Created state. In the onCreate() method, you perform basic application startup logic that should happen only once for the entire life of the activity.
It raises following questions:
Does the CREATED state occur before or after the call to onCreate()?
Is the CREATED state constant used below different from the theoretical meaning of state being defined in the above excerpt, i.e, I should just read this and move on not focusing on the created state phrase?
Before you answer, there is the Lifecycle.State class from Lifecycle Aware components where in you can see the meaning of various states as follows:
/**
* Lifecycle states. You can consider the states as the nodes in a graph and
* {#link Event}s as the edges between these nodes.
*/
#SuppressWarnings("WeakerAccess")
public enum State {
/**
* Destroyed state for a LifecycleOwner. After this event, this Lifecycle will not dispatch
* any more events. For instance, for an {#link android.app.Activity}, this state is reached
* <b>right before</b> Activity's {#link android.app.Activity#onDestroy() onDestroy} call.
*/
DESTROYED,
/**
* Initialized state for a LifecycleOwner. For an {#link android.app.Activity}, this is
* the state when it is constructed but has not received
* {#link android.app.Activity#onCreate(android.os.Bundle) onCreate} yet.
*/
INITIALIZED,
/**
* Created state for a LifecycleOwner. For an {#link android.app.Activity}, this state
* is reached in two cases:
* <ul>
* <li>after {#link android.app.Activity#onCreate(android.os.Bundle) onCreate} call;
* <li><b>right before</b> {#link android.app.Activity#onStop() onStop} call.
* </ul>
*/
CREATED,
/**
* Started state for a LifecycleOwner. For an {#link android.app.Activity}, this state
* is reached in two cases:
* <ul>
* <li>after {#link android.app.Activity#onStart() onStart} call;
* <li><b>right before</b> {#link android.app.Activity#onPause() onPause} call.
* </ul>
*/
STARTED,
/**
* Resumed state for a LifecycleOwner. For an {#link android.app.Activity}, this state
* is reached after {#link android.app.Activity#onResume() onResume} is called.
*/
RESUMED;
/**
* Compares if this State is greater or equal to the given {#code state}.
*
* #param state State to compare with
* #return true if this State is greater or equal to the given {#code state}
*/
public boolean isAtLeast(#NonNull State state) {
return compareTo(state) >= 0;
}
}
I would like to believe the CREATED state occurs after the call to onCreate() because CREATED implies that at that moment it already has been created while onCreate() as from the name implies it is under creation for now and the comment in the Lifecycle.State class implies the same for CREATED state.
So to conclude:
onCreate() -> Under the process of creation
CREATED -> Already has finished the process of creation
The comment from LifeCycle state implies same as said
/**
* Created state for a LifecycleOwner. For an {#link android.app.Activity}, this state
* is reached in two cases:
* <ul>
* <li>after {#link android.app.Activity#onCreate(android.os.Bundle) onCreate} call;
* <li><b>right before</b> {#link android.app.Activity#onStop() onStop} call.
* </ul>
public abstract class SupportAnimator extends Animator {
WeakReference<RevealAnimator> mTarget;
public SupportAnimator(RevealAnimator target) {
mTarget = new WeakReference<>(target);
}
/**
* #return true if using native android animation framework, otherwise is
* nineoldandroids
*/
public abstract boolean isNativeAnimator();
/**
* #return depends from {#link android.os.Build.VERSION} if sdk version
* {#link android.os.Build.VERSION_CODES#LOLLIPOP} and greater will
* return {#link android.animation.Animator}
*/
public abstract Object get();
/**
* Starts this animation. If the animation has a nonzero startDelay, the
* animation will start running after that delay elapses. A non-delayed
* animation will have its initial value(s) set immediately, followed by
* calls to
* {#link android.animation.Animator.AnimatorListener#onAnimationStart(android.animation.Animator)}
* for any listeners of this animator.
*
* <p>
* The animation started by calling this method will be run on the thread
* that called this method. This thread should have a Looper on it (a
* runtime exception will be thrown if this is not the case). Also, if the
* animation will animate properties of objects in the view hierarchy, then
* the calling thread should be the UI thread for that view hierarchy.
* </p>
*
*/
public abstract void start();
/**
* Adds a listener to the set of listeners that are sent events through the
* life of an animation, such as start, repeat, and end.
*
* #param listener
* the listener to be added to the current set of listeners for
* this animation.
*/
public abstract void addListener(AnimatorListener listener);
/**
* Returns whether this Animator is currently running (having been started
* and gone past any initial startDelay period and not yet ended).
*
* #return Whether the Animator is running.
*/
public abstract boolean isRunning();
/**
* Cancels the animation. Unlike {#link #end()}, <code>cancel()</code>
* causes the animation to stop in its tracks, sending an
* {#link AnimatorListener#onAnimationCancel()} to its listeners, followed
* by an {#link AnimatorListener#onAnimationEnd()} message.
*
* <p>
* This method must be called on the thread that is running the animation.
* </p>
*/
public abstract void cancel();
/**
* Ends the animation. This causes the animation to assign the end value of
* the property being animated, then calling the
* {#link AnimatorListener#onAnimationEnd()} method on its listeners.
*
* <p>
* This method must be called on the thread that is running the animation.
* </p>
*/
public void end() {
}
/**
* This method tells the object to use appropriate information to extract
* starting values for the animation. For example, a AnimatorSet object will
* pass this call to its child objects to tell them to set up the values. A
* ObjectAnimator object will use the information it has about its target
* object and PropertyValuesHolder objects to get the start values for its
* properties. A ValueAnimator object will ignore the request since it does
* not have enough information (such as a target object) to gather these
* values.
*/
public void setupStartValues() {
}
/**
* This method tells the object to use appropriate information to extract
* ending values for the animation. For example, a AnimatorSet object will
* pass this call to its child objects to tell them to set up the values. A
* ObjectAnimator object will use the information it has about its target
* object and PropertyValuesHolder objects to get the start values for its
* properties. A ValueAnimator object will ignore the request since it does
* not have enough information (such as a target object) to gather these
* values.
*/
public void setupEndValues() {
}
/**
* Experimental feature
*/
public SupportAnimator reverse() {
if (isRunning()) {
return null;
}
RevealAnimator target = mTarget.get();
if (target != null) {
return target.startReverseAnimation();
}
return null;
}
/**
* <p>
* An animation listener receives notifications from an animation.
* Notifications indicate animation related events, such as the end or the
* repetition of the animation.
* </p>
*/
public interface AnimatorListener {
/**
* <p>
* Notifies the start of the animation.
* </p>
*/
void onAnimationStart();
/**
* <p>
* Notifies the end of the animation. This callback is not invoked for
* animations with repeat count set to INFINITE.
* </p>
*/
void onAnimationEnd();
/**
* <p>
* Notifies the cancellation of the animation. This callback is not
* invoked for animations with repeat count set to INFINITE.
* </p>
*/
void onAnimationCancel();
/**
* <p>
* Notifies the repetition of the animation.
* </p>
*/
void onAnimationRepeat();
}
/**
* <p>
* Provides default implementation for AnimatorListener.
* </p>
*/
public static abstract class SimpleAnimatorListener implements
AnimatorListener {
#Override
public void onAnimationStart() {
}
#Override
public void onAnimationEnd() {
}
#Override
public void onAnimationCancel() {
}
#Override
public void onAnimationRepeat() {
}
}
}
Its an abstract Class and extends by Animator.
and when I use this in next class
if (LOLLIPOP_PLUS) {
return new SupportAnimator(
android.view.ViewAnimationUtils.createCircularReveal(view,
centerX, centerY, startRadius, endRadius),
revealLayout);
}
ObjectAnimator reveal = ObjectAnimator.ofFloat(revealLayout,
CLIP_RADIUS, startRadius, endRadius);
reveal.addListener(new RevealAnimator.RevealFinishedIceCreamSandwich(
revealLayout, layerType));
return new SupportAnimator(reveal, revealLayout);
}
the return new SupportAnimator returns an exception of Cannot instantiate the type SupportAnimator,
its use for Circular Reveal animation and i use this in eclipse, is this suitable to work fine.
So basically what I'm trying to do is, make a first network call. And if the called RESTful web service returns 1, make a second network call. If the web service returns 0, then do not make the second network call.
Here's my code
final ApiInterface apiInterface=restAdapter.create(ApiInterface.class);
apiInterface.submitDataToAnalyze("dataToAnalyze","852741963",1,"123","lalala","2015-11-20")
.flatMap(new Func1<BasicResponse, Observable<?>>() {
#Override
public Observable<?> call(BasicResponse basicResponse) {
if (basicResponse.getResult() == 1){
return apiInterface.getSuggestion("dataToAnalyze","852741963",1,"123","lalala","2015-11-20");
}else{
return 0; //error
}
}
}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
Obviously the code above is wrong, since it should always return Observable. So how should my code be written, if the first network call returns 0?
I think the best practice is to return Observable.error(new Throwable("..."))
taken from the javadoc :
/**
* Returns an Observable that invokes an {#link Observer}'s {#link Observer#onError onError} method when the
* Observer subscribes to it.
* <p>
* <img width="640" height="190" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/error.png" alt="">
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{#code error} does not operate by default on a particular {#link Scheduler}.</dd>
* </dl>
*
* #param exception
* the particular Throwable to pass to {#link Observer#onError onError}
* #param <T>
* the type of the items (ostensibly) emitted by the Observable
* #return an Observable that invokes the {#link Observer}'s {#link Observer#onError onError} method when
* the Observer subscribes to it
* #see ReactiveX operators documentation: Throw
*/
Activities are called in this way (an example):
Intent i = new Intent(context, MyActivity.class);
i.putExtra("par1", "value1");
i.putExtra("par2", 2);
startActivityForResult(i);
How can I comment MyActivity class with JavaDoc like methods?
For example in this case:
/**
* This activity show some data
* #param par1 String value of parameter1
* #param par2 int number of records to show
* #return returnValue boolean true if data is showed, false otherwise
*/
to have an idea of which parameters intent expects and what type of return offers.
Just write the JavaDoc part right in top of the class declaration.
/**
* JavaDoc
*/
public class MyActivity {
Right Click on a Method Name-> Source-> Generate Element Comment.
Shortcut
ALT+SHIFT+J
Declare the parameter constants as public static final String and add javadoc field documentation there.
Use #links to bind things together.
Example:
/**
* String containing foo parameter for {#link #XyzzyActivity}
*/
public static final String EXTRA_FOO = "par1";
/**
* XyzzyActivity
*
* Parameters understood: {#link #EXTRA_FOO}, ...
*
* Returns...
*/
Type /** at the top of your method, then press ENTER key. The comment part will become something like this:
/**
*
* #return
*/
You are also allowed to add
#author – who wrote this code
#version – when was it changed
#param – describe method parameters
#return – describe method return values
#throws – describe exceptions thrown
#see – link to other, related items (e.g. “See also…”)
#since – describe when code was introduced (e.g. API Level)
#deprecated - describe deprecated item and what alternative to use instead
I have read about this kind of problem here but the answers don't seem to be working.
I show a Toast when user clicks a button. When the user continously clicks the button the toast keeps on being displayed again and again even when the user exits the activity.
The length of the toast is short. Length of the toast cannot be changed as the text is long.
This is what i have tried as of now:
Toast toast;
toast=Toast.makeText(getApplicationContext(),"text",Toast.LENGTH_SHORT);
if(toast.getView().isShown()==false){
toast.show();
}
This did not work.
I tried :
if(toast.getView().isShown()==true){
toast.cancel();
}
in the onStop(). For some reason the cancel method never works.
If i put the .cancel() before i show the app... then there would be another null check for that. But after doing that also it did not work. I can show a dialog box instead of a toast but that would not be a solution.
Is there any way to check whether a toast is being displayed or not?
For reference
Toast Message in Android
How to avoid a Toast if there's one Toast already being shown
How to prevent Multiple Toast Overlaps
Cancelling an already open toast in Android
The trick is to keep track of the last Toast that was shown, and to cancel that one.
What I have done is to create a Toast wrapper, that contains a static reference to the last Toast displayed.
When I need to show a new one, I first cancel the static reference, before showing the new one (and saving it in the static).
Here's full code of the Boast wrapper I made - it mimics enough of the Toast methods for me to use it. By default the Boast will cancel the previous one, so you don't build up a queue of Toasts waiting to be displayed.
This code can be found in my Github gist:
mobiRic/Boast
If you just want to know how to cancel the notifications when exiting your app, you will find lots of help in there. If you have improvements or suggestions, please feel free to fork it and get in touch. This is a very old answer, but code has been stable in production on a few apps for some time.
BTW - this should be a direct drop-in replacement for Toast in most use cases.
package mobi.glowworm.lib.ui.widget;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.support.annotation.Nullable;
import android.widget.Toast;
import java.lang.ref.WeakReference;
/**
* {#link Toast} decorator allowing for easy cancellation of notifications. Use this class if you
* want subsequent Toast notifications to overwrite current ones. </p>
* <p/>
* By default, a current {#link Boast} notification will be cancelled by a subsequent notification.
* This default behaviour can be changed by calling certain methods like {#link #show(boolean)}.
*/
public class Boast {
/**
* Keeps track of certain Boast notifications that may need to be cancelled. This functionality
* is only offered by some of the methods in this class.
* <p>
* Uses a {#link WeakReference} to avoid leaking the activity context used to show the original {#link Toast}.
*/
#Nullable
private volatile static WeakReference<Boast> weakBoast = null;
#Nullable
private static Boast getGlobalBoast() {
if (weakBoast == null) {
return null;
}
return weakBoast.get();
}
private static void setGlobalBoast(#Nullable Boast globalBoast) {
Boast.weakBoast = new WeakReference<>(globalBoast);
}
// ////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Internal reference to the {#link Toast} object that will be displayed.
*/
private Toast internalToast;
// ////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Private constructor creates a new {#link Boast} from a given {#link Toast}.
*
* #throws NullPointerException if the parameter is <code>null</code>.
*/
private Boast(Toast toast) {
// null check
if (toast == null) {
throw new NullPointerException("Boast.Boast(Toast) requires a non-null parameter.");
}
internalToast = toast;
}
// ////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Make a standard {#link Boast} that just contains a text view.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param text The text to show. Can be formatted text.
* #param duration How long to display the message. Either {#link Toast#LENGTH_SHORT} or
* {#link Toast#LENGTH_LONG}
*/
#SuppressLint("ShowToast")
public static Boast makeText(Context context, CharSequence text, int duration) {
return new Boast(Toast.makeText(context, text, duration));
}
/**
* Make a standard {#link Boast} that just contains a text view with the text from a resource.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param resId The resource id of the string resource to use. Can be formatted text.
* #param duration How long to display the message. Either {#link Toast#LENGTH_SHORT} or
* {#link Toast#LENGTH_LONG}
* #throws Resources.NotFoundException if the resource can't be found.
*/
#SuppressLint("ShowToast")
public static Boast makeText(Context context, int resId, int duration)
throws Resources.NotFoundException {
return new Boast(Toast.makeText(context, resId, duration));
}
/**
* Make a standard {#link Boast} that just contains a text view. Duration defaults to
* {#link Toast#LENGTH_SHORT}.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param text The text to show. Can be formatted text.
*/
#SuppressLint("ShowToast")
public static Boast makeText(Context context, CharSequence text) {
return new Boast(Toast.makeText(context, text, Toast.LENGTH_SHORT));
}
/**
* Make a standard {#link Boast} that just contains a text view with the text from a resource.
* Duration defaults to {#link Toast#LENGTH_SHORT}.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param resId The resource id of the string resource to use. Can be formatted text.
* #throws Resources.NotFoundException if the resource can't be found.
*/
#SuppressLint("ShowToast")
public static Boast makeText(Context context, int resId) throws Resources.NotFoundException {
return new Boast(Toast.makeText(context, resId, Toast.LENGTH_SHORT));
}
// ////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Show a standard {#link Boast} that just contains a text view.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param text The text to show. Can be formatted text.
* #param duration How long to display the message. Either {#link Toast#LENGTH_SHORT} or
* {#link Toast#LENGTH_LONG}
*/
public static void showText(Context context, CharSequence text, int duration) {
Boast.makeText(context, text, duration).show();
}
/**
* Show a standard {#link Boast} that just contains a text view with the text from a resource.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param resId The resource id of the string resource to use. Can be formatted text.
* #param duration How long to display the message. Either {#link Toast#LENGTH_SHORT} or
* {#link Toast#LENGTH_LONG}
* #throws Resources.NotFoundException if the resource can't be found.
*/
public static void showText(Context context, int resId, int duration)
throws Resources.NotFoundException {
Boast.makeText(context, resId, duration).show();
}
/**
* Show a standard {#link Boast} that just contains a text view. Duration defaults to
* {#link Toast#LENGTH_SHORT}.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param text The text to show. Can be formatted text.
*/
public static void showText(Context context, CharSequence text) {
Boast.makeText(context, text, Toast.LENGTH_SHORT).show();
}
/**
* Show a standard {#link Boast} that just contains a text view with the text from a resource.
* Duration defaults to {#link Toast#LENGTH_SHORT}.
*
* #param context The context to use. Usually your {#link android.app.Application} or
* {#link android.app.Activity} object.
* #param resId The resource id of the string resource to use. Can be formatted text.
* #throws Resources.NotFoundException if the resource can't be found.
*/
public static void showText(Context context, int resId) throws Resources.NotFoundException {
Boast.makeText(context, resId, Toast.LENGTH_SHORT).show();
}
// ////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Close the view if it's showing, or don't show it if it isn't showing yet. You do not normally
* have to call this. Normally view will disappear on its own after the appropriate duration.
*/
public void cancel() {
internalToast.cancel();
}
/**
* Show the view for the specified duration. By default, this method cancels any current
* notification to immediately display the new one. For conventional {#link Toast#show()}
* queueing behaviour, use method {#link #show(boolean)}.
*
* #see #show(boolean)
*/
public void show() {
show(true);
}
/**
* Show the view for the specified duration. This method can be used to cancel the current
* notification, or to queue up notifications.
*
* #param cancelCurrent <code>true</code> to cancel any current notification and replace it with this new
* one
* #see #show()
*/
public void show(boolean cancelCurrent) {
// cancel current
if (cancelCurrent) {
final Boast cachedGlobalBoast = getGlobalBoast();
if ((cachedGlobalBoast != null)) {
cachedGlobalBoast.cancel();
}
}
// save an instance of this current notification
setGlobalBoast(this);
internalToast.show();
}
}
Instead of cancelling the toast. change the text. For Example
Toast t;
t = Toast.makeText(this, "hi", 3000);
t.show();
when you need a different toast then use
t.setText("bye");
t.show();
And If you want to dismiss the toast simply call t.cancel()
You can cancel individual Toasts by calling cancel() on the Toast object. AFAIK, there is no way for you to cancel all outstanding Toasts, though.
Try keeping the timestamp of the last toast, and don't allow any new toasts until a timeout period has elapsed.
Something like:
private static final long TOAST_TIMEOUT_MS = 2000; // tweak this constant
private static long lastToastTime = 0;
public void onButtonClicked() {
long now = System.currentTimeMillis();
if (lastToastTime + TOAST_TIMEOUT_MS < now) {
Toast.makeText(...).show();
lastToastTime = now;
}
}
I wouldn't worry about a single toast sticking around for a second after the user exits the app -- this is a pretty standard behavior.