Last active
December 28, 2015 18:29
-
-
Save robUx4/7543300 to your computer and use it in GitHub Desktop.
OrientationDrawable: a Drawable that handles orientation changes without allocating anything
updated with a fix when a Matrix is already applied in the canvas
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (C) 2013 LevelUp Studio | |
* | |
* 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 com.levelup.touiteur.pictures; | |
import android.graphics.Canvas; | |
import android.graphics.ColorFilter; | |
import android.graphics.Matrix; | |
import android.graphics.Rect; | |
import android.graphics.Region; | |
import android.graphics.drawable.Drawable; | |
/** | |
* A {@link android.graphics.drawable.Drawable Drawable} that handles an {@link OrientationDrawable.Orientation Orientation} | |
* change without allocating anything | |
*/ | |
public class OrientationDrawable extends Drawable implements Drawable.Callback { | |
private final Drawable mDrawable; | |
private Orientation orientation = Orientation.NORMAL; | |
public enum Orientation { | |
NORMAL, | |
ROTATE_90, | |
ROTATE_180, | |
ROTATE_270 | |
}; | |
/** | |
* Wrap a {@link android.graphics.drawable.Drawable Drawable} to allow {@link OrientationDrawable.Orientation Orientation} | |
* changes | |
* | |
* @param drawable wrapped {@code Drawable} | |
*/ | |
public OrientationDrawable(Drawable drawable) { | |
this.mDrawable = drawable; | |
mDrawable.setCallback(this); | |
} | |
/** | |
* Set the {@link OrientationDrawable.Orientation Orientation} to use to layout and display the wrapped | |
* {@link android.graphics.drawable.Drawable Drawable} | |
* | |
* @param orientation | |
* @return the {@code OrientationDrawable} that was modified | |
*/ | |
public OrientationDrawable setOrientation(Orientation orientation) { | |
if (this.orientation != orientation) { | |
this.orientation = orientation; | |
invalidateSelf(); | |
} | |
return this; | |
} | |
@Override | |
public void setBounds(int left, int top, int right, int bottom) { | |
super.setBounds(left, top, right, bottom); | |
if (orientation == Orientation.ROTATE_90 || orientation == Orientation.ROTATE_270) { | |
int tmp = left; | |
left = top; | |
top = tmp; | |
tmp = right; | |
right = bottom; | |
bottom = tmp; | |
} | |
mDrawable.setBounds(left, top, right, bottom); | |
} | |
@Override | |
public boolean getPadding(Rect padding) { | |
return mDrawable.getPadding(padding); | |
} | |
@Override | |
public void draw(Canvas canvas) { | |
if (orientation == Orientation.NORMAL) | |
mDrawable.draw(canvas); | |
else { | |
Matrix m = new Matrix(canvas.getMatrix()); | |
canvas.save(); | |
switch (orientation) { | |
case ROTATE_90: | |
m.preRotate(90, mDrawable.getIntrinsicHeight()/2, mDrawable.getIntrinsicHeight()/2); | |
canvas.setMatrix(m); | |
break; | |
case ROTATE_180: | |
m.preRotate(180, mDrawable.getIntrinsicWidth()/2, mDrawable.getIntrinsicHeight()/2); | |
canvas.setMatrix(m); | |
break; | |
case ROTATE_270: | |
m.preRotate(-90, mDrawable.getIntrinsicWidth()/2, mDrawable.getIntrinsicWidth()/2); | |
canvas.setMatrix(m); | |
break; | |
default: | |
break; | |
} | |
mDrawable.draw(canvas); | |
canvas.restore(); | |
} | |
} | |
@Override | |
public boolean isStateful() { | |
return mDrawable.isStateful(); | |
} | |
@Override | |
public boolean setState(final int[] stateSet) { | |
return mDrawable.setState(stateSet); | |
} | |
@Override | |
public int[] getState() { | |
return mDrawable.getState(); | |
} | |
@Override | |
public void jumpToCurrentState() { | |
mDrawable.jumpToCurrentState(); | |
} | |
@Override | |
public Drawable getCurrent() { | |
return mDrawable.getCurrent(); | |
} | |
@Override | |
public void setChangingConfigurations(int configs) { | |
mDrawable.setChangingConfigurations(configs); | |
} | |
@Override | |
public int getChangingConfigurations() { | |
return mDrawable.getChangingConfigurations(); | |
} | |
@Override | |
public boolean setVisible(boolean visible, boolean restart) { | |
return super.setVisible(visible, restart) || mDrawable.setVisible(visible, restart); | |
} | |
@Override | |
public void setAlpha(int alpha) { | |
mDrawable.setAlpha(alpha); | |
} | |
@Override | |
public void setColorFilter(ColorFilter cf) { | |
mDrawable.setColorFilter(cf); | |
} | |
@Override | |
public int getOpacity() { | |
return mDrawable.getOpacity(); | |
} | |
@Override | |
public Region getTransparentRegion() { | |
return mDrawable.getTransparentRegion(); | |
} | |
@Override | |
public Drawable mutate() { | |
mDrawable.mutate(); | |
return this; | |
} | |
@Override | |
public void setDither(boolean dither) { | |
mDrawable.setDither(dither); | |
} | |
@Override | |
public void setFilterBitmap(boolean filter) { | |
mDrawable.setFilterBitmap(filter); | |
} | |
public int getIntrinsicHeight() { | |
if (orientation == Orientation.ROTATE_90 || orientation == Orientation.ROTATE_270) | |
return mDrawable.getIntrinsicWidth(); | |
return mDrawable.getIntrinsicHeight(); | |
}; | |
@Override | |
public int getIntrinsicWidth() { | |
if (orientation == Orientation.ROTATE_90 || orientation == Orientation.ROTATE_270) | |
return mDrawable.getIntrinsicHeight(); | |
return mDrawable.getIntrinsicWidth(); | |
} | |
@Override | |
public int getMinimumHeight() { | |
if (orientation == Orientation.ROTATE_90 || orientation == Orientation.ROTATE_270) | |
return mDrawable.getMinimumWidth(); | |
return mDrawable.getMinimumHeight(); | |
} | |
@Override | |
public int getMinimumWidth() { | |
if (orientation == Orientation.ROTATE_90 || orientation == Orientation.ROTATE_270) | |
return mDrawable.getMinimumHeight(); | |
return mDrawable.getMinimumWidth(); | |
} | |
@Override | |
public void invalidateDrawable(Drawable who) { | |
invalidateSelf(); | |
} | |
@Override | |
public void scheduleDrawable(Drawable who, Runnable what, long when) { | |
scheduleSelf(what, when); | |
} | |
@Override | |
public void unscheduleDrawable(Drawable who, Runnable what) { | |
unscheduleSelf(what); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment