Skip to content

Instantly share code, notes, and snippets.

@Tombarr
Last active August 29, 2015 13:56
Show Gist options
  • Save Tombarr/9055643 to your computer and use it in GitHub Desktop.
Save Tombarr/9055643 to your computer and use it in GitHub Desktop.
package com.tombarrasso.android;
/*
* Copyright (c) 2014. Thomas James Barrasso
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
// Android Packages
import android.animation.ObjectAnimator;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.util.Property;
import android.widget.TextView;
// Java Packages
import java.security.SecureRandom;
import java.util.Random;
/**
* {@link TypeEvaluator} for shuffling text between two values. These values
* can be of varying lengths, but they must null be null.<br /><br />
*
* Sample usage:<br /><br />
*
* ObjectAnimator.setFrameDelay(ShuffleTextEvaluator.DEFAULT_FRAME_DELAY * 4);
* ObjectAnimator.ofObject(textView, ShuffleTextEvaluator.TEXT,
* new ShuffleTextEvaluator(), String.valueOf(textView.getText()), someNewString).start();
*
* Notice the {@link ValueAnimator#setFrameDelay(long)} call, which is to make this animation more
* appealing by slowing it down. Use {@link ShuffleTextEvaluator#DEFAULT_FRAME_DELAY} to reset the
* value for all other animations.
*/
public class ShuffleTextEvaluator implements TypeEvaluator<CharSequence> {
/**
* The default amount of time in ms between animation frames. According to
* {@link ValueAnimator} this is 10ms.
*/
public static final long DEFAULT_FRAME_DELAY = ValueAnimator.getFrameDelay();
public static final String PROPERTY_NAME = "text";
public static final Property<TextView, CharSequence> TEXT =
Property.of(TextView.class, CharSequence.class, PROPERTY_NAME);
private static Random rGen = new SecureRandom();
/**
* @return A randomly generated {@link String} between two values at
* a given fraction in an animation (used to determine length if
* start and end lengths differ).
*/
public static @NotNull CharSequence mash(final float fraction,
@NotNull final CharSequence start, @NotNull final CharSequence end) {
assert(null != start && null != end);
final int sLen = start.length(),
eLen = end.length(),
tLen = ((sLen == eLen) ? sLen : (sLen - (int) Math.ceil(fraction * (sLen - eLen))));
// Optimization: in the event that our end value is empty.
if (tLen <= 0) return "";
// Now build a StringBuffer of our desired length and fill it with random characters.
final char[] mash = new char[tLen];
// We use more or less characters from our start string depending on
// how far in the animation we are.
for (int i = 0; i < tLen; ++i) {
final CharSequence in;
if ((i / tLen) < fraction) {
in = end;
} else {
in = start;
}
mash[i] = randomChar(in);
}
return new String(mash);
}
/** @return A random {@link Character} from a {@link String}. */
public static char randomChar(final @NotNull CharSequence in) {
return in.charAt(rGen.nextInt(in.length()));
}
@Override
public CharSequence evaluate(final float fraction, final CharSequence startValue, final CharSequence endValue) {
// We have to avoid simple == because it's possible to "overshoot" the target value.
if (0f >= fraction) return startValue;
if (1f <= fraction) return endValue;
return mash(fraction, startValue, endValue);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment