我正在尝试制作一个动画按钮,并尝试了一个库代码并在我的项目中实现了可用的代码,除了这个之外,其他每个动画按钮代码都正常工作。
这是代码,如果有人可以帮助我,我会非常感激。
package com.dd.processbutton.iml;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import com.dd.processbutton.ProcessButton;
import com.dd.sample.R;
public class ActionProcessButton extends ProcessButton {
private ProgressBar mProgressBar;
private Mode mMode;
private int mColor1;
private int mColor2;
private int mColor3;
private int mColor4;
public enum Mode {
PROGRESS, ENDLESS;
}
public ActionProcessButton(Context context) {
super(context);
init(context);
}
public ActionProcessButton(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public ActionProcessButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
private void init(Context context) {
Resources res = context.getResources();
mMode = Mode.ENDLESS;
mColor1 = res.getColor(R.color.holo_blue_bright);
mColor2 = res.getColor(R.color.holo_green_light);
mColor3 = res.getColor(R.color.holo_orange_light);
mColor4 = res.getColor(R.color.holo_red_light);
}
public void setMode(Mode mode) {
mMode = mode;
}
public void setColorScheme(int color1, int color2, int color3, int color4) {
mColor1 = color1;
mColor2 = color2;
mColor3 = color3;
mColor4 = color4;
}
@Override
public void drawProgress(Canvas canvas) {
if (getBackground() != getNormalDrawable()) {
setBackgroundDrawable(getNormalDrawable());
}
switch (mMode) {
case ENDLESS:
drawEndlessProgress(canvas);
break;
case PROGRESS:
drawLineProgress(canvas);
break;
}
}
private void drawLineProgress(Canvas canvas) {
float scale = (float) getProgress() / (float) getMaxProgress();
float indicatorWidth = (float) getMeasuredWidth() * scale;
double indicatorHeightPercent = 0.05; // 5%
int bottom = (int) (getMeasuredHeight() - getMeasuredHeight()
* indicatorHeightPercent);
getProgressDrawable().setBounds(0, bottom, (int) indicatorWidth,
getMeasuredHeight());
getProgressDrawable().draw(canvas);
}
private void drawEndlessProgress(Canvas canvas) {
double indicatorHeight = getDimension(R.dimen.layer_padding);
int bottom = (int) (getMeasuredHeight() - indicatorHeight);
if (mProgressBar == null) {
mProgressBar = new ProgressBar(this);
mProgressBar.setBounds(0, bottom, getMeasuredWidth(),
getMeasuredHeight());
mProgressBar.setColorScheme(mColor1, mColor2, mColor3, mColor4);
mProgressBar.start();
}
if (getProgress() > 0) {
mProgressBar.draw(canvas);
}
}
public static class ProgressBar {
// Default progress animation colors are grays.
private final static int COLOR1 = 0xB3000000;
private final static int COLOR2 = 0x80000000;
private final static int COLOR3 = 0x4d000000;
private final static int COLOR4 = 0x1a000000;
// The duration of the animation cycle.
private static final int ANIMATION_DURATION_MS = 2000;
// The duration of the animation to clear the bar.
private static final int FINISH_ANIMATION_DURATION_MS = 1000;
// Interpolator for varying the speed of the animation.
private static final Interpolator INTERPOLATOR = new AccelerateDecelerateInterpolator();
private final Paint mPaint = new Paint();
private final RectF mClipRect = new RectF();
private float mTriggerPercentage;
private long mStartTime;
private long mFinishTime;
private boolean mRunning;
// Colors used when rendering the animation,
private int mColor1;
private int mColor2;
private int mColor3;
private int mColor4;
private View mParent;
private Rect mBounds = new Rect();
public ProgressBar(View parent) {
mParent = parent;
mColor1 = COLOR1;
mColor2 = COLOR2;
mColor3 = COLOR3;
mColor4 = COLOR4;
}
/**
* Set the four colors used in the progress animation. The first color
* will also be the color of the bar that grows in response to a user
* swipe gesture.
*
* @param color1
* Integer representation of a color.
* @param color2
* Integer representation of a color.
* @param color3
* Integer representation of a color.
* @param color4
* Integer representation of a color.
*/
void setColorScheme(int color1, int color2, int color3, int color4) {
mColor1 = color1;
mColor2 = color2;
mColor3 = color3;
mColor4 = color4;
}
/**
* Start showing the progress animation.
*/
void start() {
if (!mRunning) {
mTriggerPercentage = 0;
mStartTime = AnimationUtils.currentAnimationTimeMillis();
mRunning = true;
mParent.postInvalidate();
}
}
void draw(Canvas canvas) {
final int width = mBounds.width();
final int height = mBounds.height();
final int cx = width / 2;
final int cy = height / 2;
boolean drawTriggerWhileFinishing = false;
int restoreCount = canvas.save();
canvas.clipRect(mBounds);
if (mRunning || (mFinishTime > 0)) {
long now = AnimationUtils.currentAnimationTimeMillis();
long elapsed = (now - mStartTime) % ANIMATION_DURATION_MS;
long iterations = (now - mStartTime) / ANIMATION_DURATION_MS;
float rawProgress = (elapsed / (ANIMATION_DURATION_MS / 100f));
// If we're not running anymore, that means we're running
// through
// the finish animation.
if (!mRunning) {
// If the finish animation is done, don't draw anything, and
// don't repost.
if ((now - mFinishTime) >= FINISH_ANIMATION_DURATION_MS) {
mFinishTime = 0;
return;
}
// Otherwise, use a 0 opacity alpha layer to clear the
// animation
// from the inside out. This layer will prevent the circles
// from
// drawing within its bounds.
long finishElapsed = (now - mFinishTime)
% FINISH_ANIMATION_DURATION_MS;
float finishProgress = (finishElapsed / (FINISH_ANIMATION_DURATION_MS / 100f));
float pct = (finishProgress / 100f);
// Radius of the circle is half of the screen.
float clearRadius = width / 2
* INTERPOLATOR.getInterpolation(pct);
mClipRect
.set(cx - clearRadius, 0, cx + clearRadius, height);
canvas.saveLayerAlpha(mClipRect, 0, 0);
// Only draw the trigger if there is a space in the center
// of
// this refreshing view that needs to be filled in by the
// trigger. If the progress view is just still animating,
// let it
// continue animating.
drawTriggerWhileFinishing = true;
}
// First fill in with the last color that would have finished
// drawing.
if (iterations == 0) {
canvas.drawColor(mColor1);
} else {
if (rawProgress >= 0 && rawProgress < 25) {
canvas.drawColor(mColor4);
} else if (rawProgress >= 25 && rawProgress < 50) {
canvas.drawColor(mColor1);
} else if (rawProgress >= 50 && rawProgress < 75) {
canvas.drawColor(mColor2);
} else {
canvas.drawColor(mColor3);
}
}
// Then draw up to 4 overlapping concentric circles of varying
// radii, based on how far
// along we are in the cycle.
// progress 0-50 draw mColor2
// progress 25-75 draw mColor3
// progress 50-100 draw mColor4
// progress 75 (wrap to 25) draw mColor1
if ((rawProgress >= 0 && rawProgress <= 25)) {
float pct = (((rawProgress + 25) * 2) / 100f);
drawCircle(canvas, cx, cy, mColor1, pct);
}
if (rawProgress >= 0 && rawProgress <= 50) {
float pct = ((rawProgress * 2) / 100f);
drawCircle(canvas, cx, cy, mColor2, pct);
}
if (rawProgress >= 25 && rawProgress <= 75) {
float pct = (((rawProgress - 25) * 2) / 100f);
drawCircle(canvas, cx, cy, mColor3, pct);
}
if (rawProgress >= 50 && rawProgress <= 100) {
float pct = (((rawProgress - 50) * 2) / 100f);
drawCircle(canvas, cx, cy, mColor4, pct);
}
if ((rawProgress >= 75 && rawProgress <= 100)) {
float pct = (((rawProgress - 75) * 2) / 100f);
drawCircle(canvas, cx, cy, mColor1, pct);
}
if (mTriggerPercentage > 0 && drawTriggerWhileFinishing) {
// There is some portion of trigger to draw. Restore the
// canvas,
// then draw the trigger. Otherwise, the trigger does not
// appear
// until after the bar has finished animating and appears to
// just jump in at a larger width than expected.
canvas.restoreToCount(restoreCount);
restoreCount = canvas.save();
canvas.clipRect(mBounds);
drawTrigger(canvas, cx, cy);
}
// Keep running until we finish out the last cycle.
ViewCompat.postInvalidateOnAnimation(mParent);
} else {
// Otherwise if we're in the middle of a trigger, draw that.
if (mTriggerPercentage > 0 && mTriggerPercentage <= 1.0) {
drawTrigger(canvas, cx, cy);
}
}
canvas.restoreToCount(restoreCount);
}
private void drawTrigger(Canvas canvas, int cx, int cy) {
mPaint.setColor(mColor1);
canvas.drawCircle(cx, cy, cx * mTriggerPercentage, mPaint);
}
/**
* Draws a circle centered in the view.
*
* @param canvas
* the canvas to draw on
* @param cx
* the center x coordinate
* @param cy
* the center y coordinate
* @param color
* the color to draw
* @param pct
* the percentage of the view that the circle should cover
*/
private void drawCircle(Canvas canvas, float cx, float cy, int color,
float pct) {
mPaint.setColor(color);
canvas.save();
canvas.translate(cx, cy);
float radiusScale = INTERPOLATOR.getInterpolation(pct);
canvas.scale(radiusScale, radiusScale);
canvas.drawCircle(0, 0, cx, mPaint);
canvas.restore();
}
/**
* Set the drawing bounds of this SwipeProgressBar.
*/
void setBounds(int left, int top, int right, int bottom) {
mBounds.left = left;
mBounds.top = top;
mBounds.right = right;
mBounds.bottom = bottom;
}
}
}
这是我的堆栈跟踪,我不知道发生此错误的原因。
06-18 10:50:59.231: E/AndroidRuntime(322): FATAL EXCEPTION: main
06-18 10:50:59.231: E/AndroidRuntime(322): java.lang.NoClassDefFoundError: android.support.v4.view.ViewCompat
06-18 10:50:59.231: E/AndroidRuntime(322): at com.dd.processbutton.iml.ActionProcessButton$ProgressBar.draw(ActionProcessButton.java:321)
06-18 10:50:59.231: E/AndroidRuntime(322): at com.dd.processbutton.iml.ActionProcessButton.drawEndlessProgress(ActionProcessButton.java:136)
06-18 10:50:59.231: E/AndroidRuntime(322): at com.dd.processbutton.iml.ActionProcessButton.drawProgress(ActionProcessButton.java:103)
06-18 10:50:59.231: E/AndroidRuntime(322): at com.dd.processbutton.ProcessButton.onDraw(ProcessButton.java:137)
06-18 10:50:59.231: E/AndroidRuntime(322): at android.view.View.draw(View.java:6880)
06-18 10:50:59.231: E/AndroidRuntime(322): at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
06-18 10:50:59.231: E/AndroidRuntime(322): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
06-18 10:50:59.231: E/AndroidRuntime(322): at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
06-18 10:50:59.231: E/AndroidRuntime(322): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
06-18 10:50:59.231: E/AndroidRuntime(322): at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
06-18 10:50:59.231: E/AndroidRuntime(322): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
06-18 10:50:59.231: E/AndroidRuntime(322): at android.view.View.draw(View.java:6883)
06-18 10:50:59.231: E/AndroidRuntime(322): at android.widget.FrameLayout.draw(FrameLayout.java:357)
06-18 10:50:59.231: E/AndroidRuntime(322): at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
06-18 10:50:59.231: E/AndroidRuntime(322): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
06-18 10:50:59.231: E/AndroidRuntime(322): at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
06-18 10:50:59.231: E/AndroidRuntime(322): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
06-18 10:50:59.231: E/AndroidRuntime(322): at android.view.View.draw(View.java:6883)
06-18 10:50:59.231: E/AndroidRuntime(322): at android.widget.FrameLayout.draw(FrameLayout.java:357)
06-18 10:50:59.231: E/AndroidRuntime(322): at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1862)
06-18 10:50:59.231: E/AndroidRuntime(322): at android.view.ViewRoot.draw(ViewRoot.java:1522)
06-18 10:50:59.231: E/AndroidRuntime(322): at android.view.ViewRoot.performTraversals(ViewRoot.java:1258)
06-18 10:50:59.231: E/AndroidRuntime(322): at android.view.ViewRoot.handleMessage(ViewRoot.java:1859)
06-18 10:50:59.231: E/AndroidRuntime(322): at android.os.Handler.dispatchMessage(Handler.java:99)
06-18 10:50:59.231: E/AndroidRuntime(322): at android.os.Looper.loop(Looper.java:123)
06-18 10:50:59.231: E/AndroidRuntime(322): at android.app.ActivityThread.main(ActivityThread.java:3683)
06-18 10:50:59.231: E/AndroidRuntime(322): at java.lang.reflect.Method.invokeNative(Native Method)
06-18 10:50:59.231: E/AndroidRuntime(322): at java.lang.reflect.Method.invoke(Method.java:507)
06-18 10:50:59.231: E/AndroidRuntime(322): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
06-18 10:50:59.231: E/AndroidRuntime(322): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
06-18 10:50:59.231: E/AndroidRuntime(322): at dalvik.system.NativeStart.main(Native Method)
以下是图书馆的Link
答案 0 :(得分:2)
我找到了解决方案,我必须有一个项目库,即appcompact
v7添加到我的项目中,这解决了我的问题。
来源:Google
答案 1 :(得分:0)
这对我来说,构建apk时出现了问题,该类似乎没有在apk中打包,也试图避免将proguard作为第一个。