Merge "Revert "Ensure calling mutate() on DrawableContainer creates a new state"" into lmp-mr1-dev

This commit is contained in:
John Reck
2014-11-25 15:54:23 +00:00
committed by Android (Google) Code Review
5 changed files with 35 additions and 75 deletions

View File

@@ -527,18 +527,14 @@ public class AnimatedStateListDrawable extends StateListDrawable {
@Override @Override
public Drawable mutate() { public Drawable mutate() {
if (!mMutated && super.mutate() == this) { if (!mMutated && super.mutate() == this) {
mState.mutate(); final AnimatedStateListState newState = new AnimatedStateListState(mState, this, null);
setConstantState(newState);
mMutated = true; mMutated = true;
} }
return this; return this;
} }
@Override
AnimatedStateListState cloneConstantState() {
return new AnimatedStateListState(mState, this, null);
}
/** /**
* @hide * @hide
*/ */
@@ -557,29 +553,23 @@ public class AnimatedStateListDrawable extends StateListDrawable {
int[] mAnimThemeAttrs; int[] mAnimThemeAttrs;
LongSparseLongArray mTransitions; final LongSparseLongArray mTransitions;
SparseIntArray mStateIds; final SparseIntArray mStateIds;
AnimatedStateListState(@Nullable AnimatedStateListState orig, AnimatedStateListState(@Nullable AnimatedStateListState orig,
@NonNull AnimatedStateListDrawable owner, @Nullable Resources res) { @NonNull AnimatedStateListDrawable owner, @Nullable Resources res) {
super(orig, owner, res); super(orig, owner, res);
if (orig != null) { if (orig != null) {
// Perform a shallow copy and rely on mutate() to deep-copy.
mAnimThemeAttrs = orig.mAnimThemeAttrs; mAnimThemeAttrs = orig.mAnimThemeAttrs;
mTransitions = orig.mTransitions; mTransitions = orig.mTransitions.clone();
mStateIds = orig.mStateIds; mStateIds = orig.mStateIds.clone();
} else { } else {
mTransitions = new LongSparseLongArray(); mTransitions = new LongSparseLongArray();
mStateIds = new SparseIntArray(); mStateIds = new SparseIntArray();
} }
} }
private void mutate() {
mTransitions = mTransitions.clone();
mStateIds = mStateIds.clone();
}
int addTransition(int fromId, int toId, @NonNull Drawable anim, boolean reversible) { int addTransition(int fromId, int toId, @NonNull Drawable anim, boolean reversible) {
final int pos = super.addChild(anim); final int pos = super.addChild(anim);
final long keyFromTo = generateTransitionKey(fromId, toId); final long keyFromTo = generateTransitionKey(fromId, toId);
@@ -651,7 +641,7 @@ public class AnimatedStateListDrawable extends StateListDrawable {
} }
} }
protected void setConstantState(@NonNull AnimatedStateListState state) { void setConstantState(@NonNull AnimatedStateListState state) {
super.setConstantState(state); super.setConstantState(state);
mState = state; mState = state;
@@ -660,7 +650,6 @@ public class AnimatedStateListDrawable extends StateListDrawable {
private AnimatedStateListDrawable(@Nullable AnimatedStateListState state, @Nullable Resources res) { private AnimatedStateListDrawable(@Nullable AnimatedStateListState state, @Nullable Resources res) {
super(null); super(null);
// Every animated state list drawable has its own constant state.
final AnimatedStateListState newState = new AnimatedStateListState(state, this, res); final AnimatedStateListState newState = new AnimatedStateListState(state, this, res);
setConstantState(newState); setConstantState(newState);
onStateChange(getState()); onStateChange(getState());

View File

@@ -342,17 +342,12 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An
@Override @Override
public Drawable mutate() { public Drawable mutate() {
if (!mMutated && super.mutate() == this) { if (!mMutated && super.mutate() == this) {
mAnimationState.mutate(); mAnimationState.mDurations = mAnimationState.mDurations.clone();
mMutated = true; mMutated = true;
} }
return this; return this;
} }
@Override
AnimationState cloneConstantState() {
return new AnimationState(mAnimationState, this, null);
}
/** /**
* @hide * @hide
*/ */
@@ -378,10 +373,6 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An
} }
} }
private void mutate() {
mDurations = mDurations.clone();
}
@Override @Override
public Drawable newDrawable() { public Drawable newDrawable() {
return new AnimationDrawable(this, null); return new AnimationDrawable(this, null);

View File

@@ -567,23 +567,12 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
@Override @Override
public Drawable mutate() { public Drawable mutate() {
if (!mMutated && super.mutate() == this) { if (!mMutated && super.mutate() == this) {
mDrawableContainerState = cloneConstantState();
mDrawableContainerState.mutate(); mDrawableContainerState.mutate();
mMutated = true; mMutated = true;
} }
return this; return this;
} }
/**
* Returns a shallow copy of the container's constant state to be used as
* the base state for {@link #mutate()}.
*
* @return a shallow copy of the constant state
*/
DrawableContainerState cloneConstantState() {
return mDrawableContainerState;
}
/** /**
* @hide * @hide
*/ */
@@ -844,7 +833,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
return false; return false;
} }
private void mutate() { final void mutate() {
// No need to call createAllFutures, since future drawables will // No need to call createAllFutures, since future drawables will
// mutate when they are prepared. // mutate when they are prepared.
final int N = mNumChildren; final int N = mNumChildren;

View File

@@ -146,17 +146,13 @@ public class LevelListDrawable extends DrawableContainer {
@Override @Override
public Drawable mutate() { public Drawable mutate() {
if (!mMutated && super.mutate() == this) { if (!mMutated && super.mutate() == this) {
mLevelListState.mutate(); mLevelListState.mLows = mLevelListState.mLows.clone();
mLevelListState.mHighs = mLevelListState.mHighs.clone();
mMutated = true; mMutated = true;
} }
return this; return this;
} }
@Override
LevelListState cloneConstantState() {
return new LevelListState(mLevelListState, this, null);
}
/** /**
* @hide * @hide
*/ */
@@ -173,7 +169,6 @@ public class LevelListDrawable extends DrawableContainer {
super(orig, owner, res); super(orig, owner, res);
if (orig != null) { if (orig != null) {
// Perform a shallow copy and rely on mutate() to deep-copy.
mLows = orig.mLows; mLows = orig.mLows;
mHighs = orig.mHighs; mHighs = orig.mHighs;
} else { } else {
@@ -182,11 +177,6 @@ public class LevelListDrawable extends DrawableContainer {
} }
} }
private void mutate() {
mLows = mLows.clone();
mHighs = mHighs.clone();
}
public void addLevel(int low, int high, Drawable drawable) { public void addLevel(int low, int high, Drawable drawable) {
int pos = addChild(drawable); int pos = addChild(drawable);
mLows[pos] = low; mLows[pos] = low;

View File

@@ -24,8 +24,6 @@ import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.res.Resources; import android.content.res.Resources;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.content.res.Resources.Theme; import android.content.res.Resources.Theme;
@@ -290,17 +288,20 @@ public class StateListDrawable extends DrawableContainer {
@Override @Override
public Drawable mutate() { public Drawable mutate() {
if (!mMutated && super.mutate() == this) { if (!mMutated && super.mutate() == this) {
mStateListState.mutate(); final int[][] sets = mStateListState.mStateSets;
final int count = sets.length;
mStateListState.mStateSets = new int[count][];
for (int i = 0; i < count; i++) {
final int[] set = sets[i];
if (set != null) {
mStateListState.mStateSets[i] = set.clone();
}
}
mMutated = true; mMutated = true;
} }
return this; return this;
} }
@Override
StateListState cloneConstantState() {
return new StateListState(mStateListState, this, null);
}
/** /**
* @hide * @hide
*/ */
@@ -327,24 +328,25 @@ public class StateListDrawable extends DrawableContainer {
super(orig, owner, res); super(orig, owner, res);
if (orig != null) { if (orig != null) {
// Perform a shallow copy and rely on mutate() to deep-copy. // Perform a deep copy.
final int[][] sets = orig.mStateSets;
final int count = sets.length;
mStateSets = new int[count][];
for (int i = 0; i < count; i++) {
final int[] set = sets[i];
if (set != null) {
mStateSets[i] = set.clone();
}
}
mThemeAttrs = orig.mThemeAttrs; mThemeAttrs = orig.mThemeAttrs;
mStateSets = orig.mStateSets; mStateSets = Arrays.copyOf(orig.mStateSets, orig.mStateSets.length);
} else { } else {
mThemeAttrs = null; mThemeAttrs = null;
mStateSets = new int[getCapacity()][]; mStateSets = new int[getCapacity()][];
} }
} }
private void mutate() {
mThemeAttrs = mThemeAttrs != null ? mThemeAttrs.clone() : null;
final int[][] stateSets = new int[mStateSets.length][];
for (int i = mStateSets.length - 1; i >= 0; i--) {
stateSets[i] = mStateSets[i] != null ? mStateSets[i].clone() : null;
}
}
int addStateSet(int[] stateSet, Drawable drawable) { int addStateSet(int[] stateSet, Drawable drawable) {
final int pos = addChild(drawable); final int pos = addChild(drawable);
mStateSets[pos] = stateSet; mStateSets[pos] = stateSet;
@@ -393,14 +395,13 @@ public class StateListDrawable extends DrawableContainer {
onStateChange(getState()); onStateChange(getState());
} }
protected void setConstantState(@NonNull StateListState state) { void setConstantState(StateListState state) {
super.setConstantState(state); super.setConstantState(state);
mStateListState = state; mStateListState = state;
} }
private StateListDrawable(StateListState state, Resources res) { private StateListDrawable(StateListState state, Resources res) {
// Every state list drawable has its own constant state.
final StateListState newState = new StateListState(state, this, res); final StateListState newState = new StateListState(state, this, res);
setConstantState(newState); setConstantState(newState);
onStateChange(getState()); onStateChange(getState());
@@ -410,7 +411,7 @@ public class StateListDrawable extends DrawableContainer {
* This constructor exists so subclasses can avoid calling the default * This constructor exists so subclasses can avoid calling the default
* constructor and setting up a StateListDrawable-specific constant state. * constructor and setting up a StateListDrawable-specific constant state.
*/ */
StateListDrawable(@Nullable StateListState state) { StateListDrawable(StateListState state) {
if (state != null) { if (state != null) {
setConstantState(state); setConstantState(state);
} }