Please, i got many errors on my code really i need your help.
Errors:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: tools.myapp.app1, PID: 23986
java.lang.RuntimeException: Unable to start activity ComponentInfo{tools.myapp.app1/tools.myapp.app1.activitys.GreatingCardShowActivity}: android.view.InflateException: Binary XML file line #58 in tools.myapp.app1:layout/activity_greating_card_show: Binary XML file line #58 in tools.myapp.app1:layout/activity_greating_card_show: Error inflating class tools.myapp.app1.StickerView.StickerView
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3479)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3651)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2104)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:236)
at android.app.ActivityThread.main(ActivityThread.java:7861)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:600)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)
Caused by: android.view.InflateException: Binary XML file line #58 in tools.myapp.app1:layout/activity_greating_card_show: Binary XML file line #58 in tools.myapp.app1:layout/activity_greating_card_show: Error inflating class tools.myapp.app1.StickerView.StickerView
Caused by: android.view.InflateException: Binary XML file line #58 in tools.myapp.app1:layout/activity_greating_card_show: Error inflating class tools.myapp.app1.StickerView.StickerView
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
at android.view.LayoutInflater.createView(LayoutInflater.java:856)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:1008)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:963)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1125)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1086)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1128)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1086)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1128)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1086)
at android.view.LayoutInflater.inflate(LayoutInflater.java:684)
at android.view.LayoutInflater.inflate(LayoutInflater.java:536)
at android.view.LayoutInflater.inflate(LayoutInflater.java:479)
at `androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:706)
at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:195)
at tools.myapp.app1.activitys.GreatingCardShowActivity.onCreate(GreatingCardShowActivity.java:1001)
at android.app.Activity.performCreate(Activity.java:8109)
at android.app.Activity.performCreate(Activity.java:8083)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1310)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3452)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3651)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2104)
at android.os.Handler.dispatchMessage(Handler.java:106)
E/AndroidRuntime: at android.os.Looper.loop(Looper.java:236)
at android.app.ActivityThread.main(ActivityThread.java:7861)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:600)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.drawable.Drawable.getIntrinsicWidth()' on a null object reference
at tools.myapp.app1.StickerView.DrawableSticker.getWidth(DrawableSticker.java:38)
at tools.myapp.app1.StickerView.DrawableSticker.<init>(DrawableSticker.java:10)
at tools.myapp.app1.StickerView.BitmapStickerIcon.<init>(BitmapStickerIcon.java:16)
at tools.myapp.app1.StickerView.StickerView.<init>(StickerView.java:129)
at tools.myapp.app1.StickerView.StickerView.<init>(StickerView.java:111)
Here: layout/activity_greating_card_show
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/background_ss">
code......
**//this is a line #58 that the compiler marked**
<tools.myapp.app1.StickerView.StickerView
android:id="#+id/stickerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:layout_gravity="center"
android:layout_margin="#dimen/_8sdp"
android:visibility="visible" />
</RelativeLayout>
Here: GreatingCardShowActivity/onCreate
public void onCreate(#Nullable Bundle bundle) {
ImageView imageView;
float f;
super.onCreate(bundle);
**//the compiler select this line #1001**
setContentView(R.layout.activity_greating_card_show);
InterstitialAdHelper instance = InterstitialAdHelper.Companion.getInstance();
if (instance == null) {
Intrinsics.throwNpe();
}
instance.load(this, this);
this.activity = this;
this.assetManager = getAssets();
this.mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
if (Share.ActivityCardCreate) {
this.bgposition = getIntent().getStringExtra("bgposition");
Log.e("val", "onCreate: bg pos-->" + this.bgposition);
} else {
Intent intent = getIntent();
this.gretingcatname = intent.getStringExtra("gretingcatname");
this.pos = intent.getIntExtra("pos", 0);
}
initView();
if (Share.ActivityCardCreate || Share.ActivityGalleryCardCreate) {
ImageView imageView2 = this.iv_custom_sticker_view;
if (imageView2 == null) {
Intrinsics.throwNpe();
}
f = 1.0f;
imageView2.setAlpha(1.0f);
ImageView imageView3 = this.iv_gc_quotes;
if (imageView3 == null) {
Intrinsics.throwNpe();
}
imageView3.setAlpha(1.0f);
imageView = this.iv_ad_frame;
} else {
ImageView imageView4 = this.iv_custom_sticker_view;
if (imageView4 == null) {
Intrinsics.throwNpe();
}
f = 0.5f;
imageView4.setAlpha(0.5f);
ImageView imageView5 = this.iv_gc_quotes;
if (imageView5 == null) {
Intrinsics.throwNpe();
}
imageView5.setAlpha(0.5f);
imageView = this.iv_ad_frame;
}
imageView.setAlpha(f);
initAction();
drawables_sticker.clear();
}
Here: class DrawableSticker
public class DrawableSticker extends Sticker {
private Drawable mDrawable;
**// Below is line #10 the compiler select getWidth() in this line**
private final Rect mRealBounds = new Rect(0, 0, getWidth(), getHeight());
public DrawableSticker(Drawable drawable) {
this.mDrawable = drawable;
this.a = new Matrix();
}
#Override
public void draw(Canvas canvas) {
canvas.save();
canvas.concat(this.a);
this.mDrawable.setBounds(this.mRealBounds);
this.mDrawable.draw(canvas);
canvas.restore();
}
#Override
public Drawable getDrawable() {
return this.mDrawable;
}
#Override
public int getHeight() {
return this.mDrawable.getIntrinsicHeight();
}
#Override
public int getWidth() {
return this.mDrawable.getIntrinsicWidth(); **//here line #38**
}
#Override
public void release() {
super.release();
if (this.mDrawable != null) {
this.mDrawable = null;
}
}
#Override
public void setDrawable(Drawable drawable) {
this.mDrawable = drawable;
}
}
This is : class Sticker
"extended in class DrawableSticker"
public abstract class Sticker {
protected Matrix a;
protected boolean b;
private String tag = "";
private float[] mMatrixValues = new float[9];
private float getMatrixAngle(#NonNull Matrix matrix) {
return (float) (-(Math.atan2((double) getMatrixValue(matrix, 1), (double)
getMatrixValue(matrix, 0)) * 57.29577951308232d));
}
private float getMatrixScale(#NonNull Matrix matrix) {
return (float) Math.sqrt(Math.pow((double) getMatrixValue(matrix, 0), 2.0d) +
Math.pow((double) getMatrixValue(matrix, 3), 2.0d));
}
private float getMatrixValue(#NonNull Matrix matrix, #IntRange(from = 0, to = 9) int i) {
matrix.getValues(this.mMatrixValues);
return this.mMatrixValues[i];
}
public boolean contains(float f, float f2) {
Matrix matrix = new Matrix();
matrix.setRotate(-getCurrentAngle());
float[] fArr = new float[8];
float[] fArr2 = new float[2];
matrix.mapPoints(fArr, getMappedBoundPoints());
matrix.mapPoints(fArr2, new float[]{f, f2});
return StickerUtils.trapToRect(fArr).contains(fArr2[0], fArr2[1]);
}
public abstract void draw(Canvas canvas);
public RectF getBound() {
return new RectF(0.0f, 0.0f, (float) getWidth(), (float) getHeight());
}
public float[] getBoundPoints() {
return !this.b ? new float[]{0.0f, 0.0f, (float) getWidth(), 0.0f, 0.0f, (float)
getHeight(), (float) getWidth(), (float) getHeight()} : new float[]{(float) getWidth(), 0.0f,
0.0f, 0.0f, (float) getWidth(), (float) getHeight(), 0.0f, (float) getHeight()};
}
public PointF getCenterPoint() {
return new PointF((float) (getWidth() / 2), (float) (getHeight() / 2));
}
public float getCurrentAngle() {
return getMatrixAngle(this.a);
}
public float getCurrentHeight() {
return getMatrixScale(this.a) * ((float) getHeight());
}
public float getCurrentScale() {
return getMatrixScale(this.a);
}
public float getCurrentWidth() {
return getMatrixScale(this.a) * ((float) getWidth());
}
public abstract Drawable getDrawable();
public abstract int getHeight();
public RectF getMappedBound() {
RectF rectF = new RectF();
this.a.mapRect(rectF, getBound());
return rectF;
}
public float[] getMappedBoundPoints() {
float[] fArr = new float[8];
this.a.mapPoints(fArr, getBoundPoints());
return fArr;
}
public PointF getMappedCenterPoint() {
PointF centerPoint = getCenterPoint();
float[] mappedPoints = getMappedPoints(new float[]{centerPoint.x, centerPoint.y});
return new PointF(mappedPoints[0], mappedPoints[1]);
}
public float[] getMappedPoints(float[] fArr) {
float[] fArr2 = new float[fArr.length];
this.a.mapPoints(fArr2, fArr);
return fArr2;
}
public Matrix getMatrix() {
return this.a;
}
public abstract int getWidth();
public boolean isFlipped() {
return this.b;
}
public void release() {
}
public abstract void setDrawable(Drawable drawable);
public void setFlipped(boolean z) {
this.b = z;
}
public void setMatrix(Matrix matrix) {
this.a.set(matrix);
}
public void setTag(String str) {
this.tag = str;
}
}
And this is : class BitmapStickerIcon
public class BitmapStickerIcon extends DrawableSticker {
public static final float DEFAULT_ICON_EXTRA_RADIUS = 10.0f;
public static final float DEFAULT_ICON_RADIUS = 30.0f;
private float x;
private float y;
private float mIconRadius ;
private float mIconExtraRadius ;
public BitmapStickerIcon(Drawable drwbl) {
super(drwbl); **//this is line #16 selected by compiler**
this.mIconRadius = 30.0f;
this.mIconExtraRadius = 10.0f;
}
public void draw(Canvas canvas, Paint paint) {
canvas.drawCircle(this.x, this.y, this.mIconRadius, paint);
super.draw(canvas);
}
public float getIconExtraRadius() {
return this.mIconExtraRadius;
}
public float getIconRadius() {
return this.mIconRadius;
}
public float getX() {
return this.x;
}
public float getY() {
return this.y;
}
public void setIconExtraRadius(float f) {
this.mIconExtraRadius = f;
}
public void setIconRadius(float f) {
this.mIconRadius = f;
}
public void setX(float f) {
this.x = f;
}
public void setY(float f) {
this.y = f;
}
}
Here : class StickerView
public class StickerView extends FrameLayout {
public static final float MAX_SCALE_SIZE = 3.2f;
public static final float MIN_SCALE_SIZE = 0.1f;
private static final String TAG = "StickerView";
public static float[] bitmapPoints;
public static boolean mLocked;
public static List<Sticker> mStickers = new ArrayList();
private Paint mBorderPaint;
private ActionMode mCurrentMode;
private BitmapStickerIcon mDeleteIcon;
private Matrix mDownMatrix;
private float mDownX;
private float mDownY;
private BitmapStickerIcon mEditIcon;
private BitmapStickerIcon mFlipIcon;
private Sticker mHandlingSticker;
private PointF mMidPoint;
private Matrix mMoveMatrix;
private float mOldDistance;
private float mOldRotation;
private OnStickerOperationListener mOnStickerOperationListener;
private Matrix mSizeMatrix;
private RectF mStickerRect;
private int mTouchSlop;
private BitmapStickerIcon mZoomIcon;
public static class kcm1 {
static final int[] aaz;
static {
int[] iArr = new int[ActionMode.values().length];
aaz = iArr;
try {
iArr[ActionMode.NONE.ordinal()] = 1;
} catch (NoSuchFieldError unused) {
}
try {
aaz[ActionMode.DRAG.ordinal()] = 2;
} catch (NoSuchFieldError unused2) {
}
try {
aaz[ActionMode.ZOOM_WITH_TWO_FINGER.ordinal()] = 3;
} catch (NoSuchFieldError unused3) {
}
try {
aaz[ActionMode.ZOOM_WITH_ICON.ordinal()] = 4;
} catch (NoSuchFieldError unused4) {
}
}
}
public enum ActionMode {
NONE,
DRAG,
ZOOM_WITH_TWO_FINGER,
ZOOM_WITH_ICON,
DELETE,
FLIP_HORIZONTAL,
CLICK
}
public interface OnStickerOperationListener {
void onStickerClicked(Sticker sticker);
void onStickerDeleted(Sticker sticker);
void onStickerDragFinished(Sticker sticker);
void onStickerEdit(Sticker sticker);
void onStickerFlipped(Sticker sticker);
void onStickerZoomFinished(Sticker sticker);
}
public StickerView(Context context) {
this(context, null); **//this line #111 selected by compiler**
}
public StickerView(Context context, AttributeSet attributeSet) {
this(context, attributeSet, 0);
}
public StickerView(Context context, AttributeSet attributeSet, int i) {
super(context, attributeSet, i);
this.mOldDistance = 0.0f;
this.mOldRotation = 0.0f;
this.mCurrentMode = ActionMode.NONE;
this.mTouchSlop = 3;
Paint paint = new Paint();
this.mBorderPaint = paint;
paint.setAntiAlias(true);
this.mBorderPaint.setColor(-16777216);
this.mBorderPaint.setAlpha(128);
this.mSizeMatrix = new Matrix();
this.mDownMatrix = new Matrix();
this.mMoveMatrix = new Matrix();
this.mStickerRect = new RectF();
**//Below line #129 the compiler select BitmapStickerIcon**
this.mDeleteIcon = new BitmapStickerIcon(ContextCompat.getDrawable(getContext(), R.drawable.ic_close_white_18dp));
this.mZoomIcon = new BitmapStickerIcon(ContextCompat.getDrawable(getContext(), R.drawable.ic_scale_white_18dp));
} ...more
I have no idea how to fix the errors, I have tested many solutions but nothing changed.
I will be happy for your help.
In the StickerView file:
Remove the StickerView(Context context) constructor
Put the initialization code also in the StickerView(Context context, AttributeSet attributeSet) constructor (creating a dedicated method is a good approach) and
Change this(context, attributeSet, 0) to super(context, attributeSet)
public StickerView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
setup();
}
public StickerView(Context context, AttributeSet attributeSet, int i) {
super(context, attributeSet, i);
setup();
}
private void setup() {
this.mOldDistance = 0.0f;
this.mOldRotation = 0.0f;
this.mCurrentMode = ActionMode.NONE;
this.mTouchSlop = 3;
Paint paint = new Paint();
this.mBorderPaint = paint;
paint.setAntiAlias(true);
this.mBorderPaint.setColor(-16777216);
this.mBorderPaint.setAlpha(128);
this.mSizeMatrix = new Matrix();
this.mDownMatrix = new Matrix();
this.mMoveMatrix = new Matrix();
this.mStickerRect = new RectF();
**//Below line #129 the compiler select BitmapStickerIcon**
this.mDeleteIcon = new BitmapStickerIcon(ContextCompat.getDrawable(getContext(), R.drawable.ic_close_white_18dp));
this.mZoomIcon = new BitmapStickerIcon(ContextCompat.getDrawable(getContext(), R.drawable.ic_scale_white_18dp));
}
Related
I am trying to implement a Drawing Application in Android where the user should be able to select and move the drawn shapes.
Currently, I have statically drawn some rects and text on my Drawing Canvas.
I want to select (draw borders on the selected shape) and move the drawn shapes in onTouch events of the drawing canvas.
package com.android.graphics;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathEffect;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.List;
public class CanvasView extends View {
public enum Mode {
DRAW,
TEXT,
ERASER;
}
public enum Drawer {
PEN,
LINE,
RECTANGLE,
CIRCLE,
ELLIPSE,
QUADRATIC_BEZIER,
QUBIC_BEZIER;
}
private Canvas canvas = null;
private Bitmap bitmap = null;
private List<Path> pathLists = new ArrayList<Path>();
private List<Paint> paintLists = new ArrayList<Paint>();
private final Paint emptyPaint = new Paint();
private int baseColor = Color.WHITE;
// for Undo, Redo
private int historyPointer = 0;
// Flags
private Mode mode = Mode.DRAW;
private Drawer drawer = Drawer.PEN;
private boolean isDown = false;
// for Paint
private Paint.Style paintStyle = Paint.Style.STROKE;
private int paintStrokeColor = Color.BLACK;
private int paintFillColor = Color.BLACK;
private float paintStrokeWidth = 3F;
private int opacity = 255;
private float blur = 0F;
private Paint.Cap lineCap = Paint.Cap.ROUND;
private PathEffect drawPathEffect = null;
// for Text
private String text = "";
private Typeface fontFamily = Typeface.DEFAULT;
private float fontSize = 32F;
private Paint.Align textAlign = Paint.Align.RIGHT; // fixed
private Paint textPaint = new Paint();
private float textX = 0F;
private float textY = 0F;
// for Drawer
private float startX = 0F;
private float startY = 0F;
private float controlX = 0F;
private float controlY = 0F;
public CanvasView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.setup();
}
public CanvasView(Context context, AttributeSet attrs) {
super(context, attrs);
this.setup();
}
public CanvasView(Context context) {
super(context);
this.setup();
}
private void setup() {
this.pathLists.add(new Path());
this.paintLists.add(this.createPaint());
this.historyPointer++;
this.textPaint.setARGB(0, 255, 255, 255);
}
private Paint createPaint() {
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(this.paintStyle);
paint.setStrokeWidth(this.paintStrokeWidth);
paint.setStrokeCap(this.lineCap);
paint.setStrokeJoin(Paint.Join.MITER); // fixed
// for Text
if (this.mode == Mode.TEXT) {
paint.setTypeface(this.fontFamily);
paint.setTextSize(this.fontSize);
paint.setTextAlign(this.textAlign);
paint.setStrokeWidth(0F);
}
if (this.mode == Mode.ERASER) {
// Eraser
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
paint.setARGB(0, 0, 0, 0);
} else {
// Otherwise
paint.setColor(this.paintStrokeColor);
paint.setShadowLayer(this.blur, 0F, 0F, this.paintStrokeColor);
paint.setAlpha(this.opacity);
paint.setPathEffect(this.drawPathEffect);
}
return paint;
}
private Path createPath(MotionEvent event) {
Path path = new Path();
// Save for ACTION_MOVE
this.startX = event.getX();
this.startY = event.getY();
path.moveTo(this.startX, this.startY);
return path;
}
private void updateHistory(Path path) {
if (this.historyPointer == this.pathLists.size()) {
this.pathLists.add(path);
this.paintLists.add(this.createPaint());
this.historyPointer++;
} else {
// On the way of Undo or Redo
this.pathLists.set(this.historyPointer, path);
this.paintLists.set(this.historyPointer, this.createPaint());
this.historyPointer++;
for (int i = this.historyPointer, size = this.paintLists.size(); i < size; i++) {
this.pathLists.remove(this.historyPointer);
this.paintLists.remove(this.historyPointer);
}
}
}
private Path getCurrentPath() {
return this.pathLists.get(this.historyPointer - 1);
}
private void drawText(Canvas canvas) {
if (this.text.length() <= 0) {
return;
}
if (this.mode == Mode.TEXT) {
this.textX = this.startX;
this.textY = this.startY;
this.textPaint = this.createPaint();
}
float textX = this.textX;
float textY = this.textY;
Paint paintForMeasureText = new Paint();
// Line break automatically
float textLength = paintForMeasureText.measureText(this.text);
float lengthOfChar = textLength / (float) this.text.length();
float restWidth = this.canvas.getWidth() - textX; // text-align : right
int numChars = (lengthOfChar <= 0) ? 1 : (int) Math.floor((double) (restWidth / lengthOfChar)); // The number of characters at 1 line
int modNumChars = (numChars < 1) ? 1 : numChars;
float y = textY;
for (int i = 0, len = this.text.length(); i < len; i += modNumChars) {
String substring = "";
if ((i + modNumChars) < len) {
substring = this.text.substring(i, (i + modNumChars));
} else {
substring = this.text.substring(i, len);
}
y += this.fontSize;
canvas.drawText(substring, textX, y, this.textPaint);
}
}
private void onActionDown(MotionEvent event) {
switch (this.mode) {
case DRAW:
case ERASER:
if ((this.drawer != Drawer.QUADRATIC_BEZIER) && (this.drawer != Drawer.QUBIC_BEZIER)) {
// Oherwise
this.updateHistory(this.createPath(event));
this.isDown = true;
} else {
// Bezier
if ((this.startX == 0F) && (this.startY == 0F)) {
// The 1st tap
this.updateHistory(this.createPath(event));
} else {
// The 2nd tap
this.controlX = event.getX();
this.controlY = event.getY();
this.isDown = true;
}
}
break;
case TEXT:
this.startX = event.getX();
this.startY = event.getY();
break;
default:
break;
}
}
private void onActionMove(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (this.mode) {
case DRAW:
case ERASER:
if ((this.drawer != Drawer.QUADRATIC_BEZIER) && (this.drawer != Drawer.QUBIC_BEZIER)) {
if (!isDown) {
return;
}
Path path = this.getCurrentPath();
switch (this.drawer) {
case PEN:
path.lineTo(x, y);
break;
case LINE:
path.reset();
path.moveTo(this.startX, this.startY);
path.lineTo(x, y);
break;
case RECTANGLE:
path.reset();
float left = Math.min(this.startX, x);
float right = Math.max(this.startX, x);
float top = Math.min(this.startY, y);
float bottom = Math.max(this.startY, y);
path.addRect(left, top, right, bottom, Path.Direction.CCW);
break;
case CIRCLE:
double distanceX = Math.abs((double) (this.startX - x));
double distanceY = Math.abs((double) (this.startX - y));
double radius = Math.sqrt(Math.pow(distanceX, 2.0) + Math.pow(distanceY, 2.0));
path.reset();
path.addCircle(this.startX, this.startY, (float) radius, Path.Direction.CCW);
break;
case ELLIPSE:
RectF rect = new RectF(this.startX, this.startY, x, y);
path.reset();
path.addOval(rect, Path.Direction.CCW);
break;
default:
break;
}
} else {
if (!isDown) {
return;
}
Path path = this.getCurrentPath();
path.reset();
path.moveTo(this.startX, this.startY);
path.quadTo(this.controlX, this.controlY, x, y);
}
break;
case TEXT:
this.startX = x;
this.startY = y;
break;
default:
break;
}
}
private void onActionUp(MotionEvent event) {
if (isDown) {
this.startX = 0F;
this.startY = 0F;
this.isDown = false;
}
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// Before "drawPath"
canvas.drawColor(this.baseColor);
if (this.bitmap != null) {
canvas.drawBitmap(this.bitmap, 0F, 0F, emptyPaint);
}
for (int i = 0; i < this.historyPointer; i++) {
Path path = this.pathLists.get(i);
Paint paint = this.paintLists.get(i);
canvas.drawPath(path, paint);
}
this.drawText(canvas);
this.canvas = canvas;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
this.onActionDown(event);
break;
case MotionEvent.ACTION_MOVE:
this.onActionMove(event);
break;
case MotionEvent.ACTION_UP:
this.onActionUp(event);
break;
default:
break;
}
// Re draw
this.invalidate();
return true;
}
public Mode getMode() {
return this.mode;
}
public void setMode(Mode mode) {
this.mode = mode;
}
public Drawer getDrawer() {
return this.drawer;
}
public void setDrawer(Drawer drawer) {
this.drawer = drawer;
}
public boolean canUndo() {
return this.historyPointer > 1;
}
public boolean canRedo() {
return this.historyPointer < this.pathLists.size();
}
public boolean undo() {
if (canUndo()) {
this.historyPointer--;
this.invalidate();
return true;
} else {
return false;
}
}
public boolean redo() {
if (canRedo()) {
this.historyPointer++;
this.invalidate();
return true;
} else {
return false;
}
}
public void clear() {
Path path = new Path();
path.moveTo(0F, 0F);
path.addRect(0F, 0F, 3000F, 3000F, Path.Direction.CCW);
path.close();
Paint paint = new Paint();
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.FILL);
if (this.historyPointer == this.pathLists.size()) {
this.pathLists.add(path);
this.paintLists.add(paint);
this.historyPointer++;
} else {
// On the way of Undo or Redo
this.pathLists.set(this.historyPointer, path);
this.paintLists.set(this.historyPointer, paint);
this.historyPointer++;
for (int i = this.historyPointer, size = this.paintLists.size(); i < size; i++) {
this.pathLists.remove(this.historyPointer);
this.paintLists.remove(this.historyPointer);
}
}
this.text = "";
// Clear
this.invalidate();
}
public int getBaseColor() {
return this.baseColor;
}
public void setBaseColor(int color) {
this.baseColor = color;
}
public String getText() {
return this.text;
}
public void setText(String text) {
this.text = text;
}
public Paint.Style getPaintStyle() {
return this.paintStyle;
}
public void setPaintStyle(Paint.Style style) {
this.paintStyle = style;
}
public int getPaintStrokeColor() {
return this.paintStrokeColor;
}
public void setPaintStrokeColor(int color) {
this.paintStrokeColor = color;
}
public int getPaintFillColor() {
return this.paintFillColor;
}
public void setPaintFillColor(int color) {
this.paintFillColor = color;
}
public float getPaintStrokeWidth() {
return this.paintStrokeWidth;
}
public void setPaintStrokeWidth(float width) {
if (width >= 0) {
this.paintStrokeWidth = width;
} else {
this.paintStrokeWidth = 3F;
}
}
public int getOpacity() {
return this.opacity;
}
public void setOpacity(int opacity) {
if ((opacity >= 0) && (opacity <= 255)) {
this.opacity = opacity;
} else {
this.opacity = 255;
}
}
public float getBlur() {
return this.blur;
}
public void setBlur(float blur) {
if (blur >= 0) {
this.blur = blur;
} else {
this.blur = 0F;
}
}
public Paint.Cap getLineCap() {
return this.lineCap;
}
public void setLineCap(Paint.Cap cap) {
this.lineCap = cap;
}
public PathEffect getDrawPathEffect() {
return drawPathEffect;
}
public void setDrawPathEffect(PathEffect drawPathEffect) {
this.drawPathEffect = drawPathEffect;
}
public float getFontSize() {
return this.fontSize;
}
public void setFontSize(float size) {
if (size >= 0F) {
this.fontSize = size;
} else {
this.fontSize = 32F;
}
}
public Typeface getFontFamily() {
return this.fontFamily;
}
public void setFontFamily(Typeface face) {
this.fontFamily = face;
}
public Bitmap getBitmap() {
this.setDrawingCacheEnabled(false);
this.setDrawingCacheEnabled(true);
return Bitmap.createBitmap(this.getDrawingCache());
}
public Bitmap getScaleBitmap(int w, int h) {
this.setDrawingCacheEnabled(false);
this.setDrawingCacheEnabled(true);
return Bitmap.createScaledBitmap(this.getDrawingCache(), w, h, true);
}
public void drawBitmap(Bitmap bitmap) {
this.bitmap = bitmap;
this.invalidate();
}
public void drawBitmap(byte[] byteArray) {
this.drawBitmap(BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length));
}
public static byte[] getBitmapAsByteArray(Bitmap bitmap, CompressFormat format, int quality) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(format, quality, byteArrayOutputStream);
return byteArrayOutputStream.toByteArray();
}
public byte[] getBitmapAsByteArray(CompressFormat format, int quality) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
this.getBitmap().compress(format, quality, byteArrayOutputStream);
return byteArrayOutputStream.toByteArray();
}
public byte[] getBitmapAsByteArray() {
return this.getBitmapAsByteArray(CompressFormat.PNG, 100);
}
}
Please I need the help regarding Undo method , I tried to implement it like the code below but it is not remove the last color,
Kindly help me to resolve it.
awaiting your kind response.
Thanks in Advance.
MainActivity
public class MainActivity extends AppCompatActivity implements
View.OnTouchListener {
Button red, blue, yellow, undo;
Paint paint;
private RelativeLayout drawingLayout;
private MyView myView;
private ArrayList<Path> paths = new ArrayList<Path>();
private ArrayList<Path> undonePaths = new ArrayList<Path>();
/**
* Called when the activity is first created.
*/
/*
*
* private ImageView imageView; private Canvas cv; private Bitmap mask,
* original, colored; private int r,g,b; private int sG, sR, sB;
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myView = new MyView(this);
drawingLayout = (RelativeLayout) findViewById(R.id.relative_layout);
drawingLayout.addView(myView);
red = (Button) findViewById(R.id.btn_red);
blue = (Button) findViewById(R.id.btn_blue);
yellow = (Button) findViewById(R.id.btn_yellow);
undo = (Button) findViewById(R.id.undo);
red.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
paint.setColor(Color.RED);
}
});
yellow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
paint.setColor(Color.YELLOW);
}
});
blue.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
paint.setColor(Color.BLUE);
}
});
undo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
myView.onClickUndo();
}
});
}
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
return false;
}
// flood fill
public class MyView extends View {
final Point p1 = new Point();
Bitmap mBitmap;
ProgressDialog pd;
Canvas canvas;
private Path path;
// Bitmap mutableBitmap ;
public MyView(Context context) {
super(context);
paint = new Paint();
paint.setAntiAlias(true);
pd = new ProgressDialog(context);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(5f);
mBitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.gp1_1).copy(Bitmap.Config.ARGB_8888, true);
this.path = new Path();
}
public void onClickUndo() {
if (paths.size() > 0) {
undonePaths.add(paths.remove(paths.size() - 1));
invalidate();
} else {
Toast.makeText(getContext(), getString(R.string.nomore), Toast.LENGTH_SHORT).show();
}
}
#Override
protected void onDraw(Canvas canvas) {
this.canvas = canvas;
paint.setColor(Color.GREEN);
// int width = drawingLayout.getWidth();
// int height = drawingLayout.getHeight();
// float centerX = (width - mBitmap.getWidth()) * 0.5f;
//float centerY = (height - mBitmap.getHeight()) * 0.5f;
canvas.drawBitmap(mBitmap, 0, 0, paint);
///////////////////////////////
for (Path p : paths) {
canvas.drawPath(p, paint);
//////////////////////////
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
p1.x = (int) x;
p1.y = (int) y;
final int sourceColor = mBitmap.getPixel((int) x, (int) y);
final int targetColor = paint.getColor();
new TheTask(mBitmap, p1, sourceColor, targetColor).execute();
paths.add(path);
invalidate();
}
return true;
}
public void clear() {
path.reset();
invalidate();
}
public int getCurrentPaintColor() {
return paint.getColor();
}
class TheTask extends AsyncTask<Void, Integer, Void> {
Bitmap bmp;
Point pt;
int replacementColor, targetColor;
public TheTask(Bitmap bm, Point p, int sc, int tc) {
this.bmp = bm;
this.pt = p;
this.replacementColor = tc;
this.targetColor = sc;
pd.setMessage(getString(R.string.wait));
pd.show();
}
#Override
protected void onPreExecute() {
pd.show();
}
#Override
protected void onProgressUpdate(Integer... values) {
}
#Override
protected Void doInBackground(Void... params) {
FloodFill f = new FloodFill();
f.floodFill(bmp, pt, targetColor, replacementColor);
return null;
}
#Override
protected void onPostExecute(Void result) {
pd.dismiss();
invalidate();
}
}
}
public class FloodFill {
public void floodFill(Bitmap image, Point node, int targetColor,
int replacementColor) {
int width = image.getWidth();
int height = image.getHeight();
int target = targetColor;
int replacement = replacementColor;
if (target != replacement) {
Queue<Point> queue = new LinkedList<Point>();
do {
int x = node.x;
int y = node.y;
while (x > 0 && image.getPixel(x - 1, y) == target) {
x--;
}
boolean spanUp = false;
boolean spanDown = false;
while (x < width && image.getPixel(x, y) == target) {
image.setPixel(x, y, replacement);
if (!spanUp && y > 0
&& image.getPixel(x, y - 1) == target) {
queue.add(new Point(x, y - 1));
spanUp = true;
} else if (spanUp && y > 0
&& image.getPixel(x, y - 1) != target) {
spanUp = false;
}
if (!spanDown && y < height - 1
&& image.getPixel(x, y + 1) == target) {
queue.add(new Point(x, y + 1));
spanDown = true;
} else if (spanDown && y < height - 1
&& image.getPixel(x, y + 1) != target) {
spanDown = false;
}
x++;
}
} while ((node = queue.poll()) != null);
}
}
}
}
I guess you mean the undo method doesn't work. The possible reason is the previous drawing on the canvas is not removed. Try clearing the canvas before drawing in the onDraw() method.
#Override protected void onDraw(Canvas canvas) {
this.canvas = canvas;
canvas. drawColor(0,PorterDuff.Mode.CLEAR); //This clears the canvas.
paint.setColor(Color.GREEN);
//rest of the code
}
Seems it is impossible to return previous color it is required an array for each point to store the used color in every point.
I am using this Github Library https://github.com/lzyzsd/CircleProgress.
But i am not getting how to increse size of arc or chane its circumference means its starting and ending point .
I am unable to it ,please help in it .
Here is my xml code.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:background="#4a4a4a" xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Player Header -->
<!-- Progress Bar/Seek bar -->
<com.androidhive.musicplayer.equalizer.ArcProgress
android:id="#+id/songProgressBar"
android:background="#214193"
android:layout_marginLeft="50dp"
android:layout_width="100dp"
android:layout_height="100dp"
custom:arc_progress="55"
custom:arc_bottom_text="MEMORY"/>
</RelativeLayout>
Here is ArcProgress.java
package com.androidhive.musicplayer.equalizer;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Bundle;
import android.os.Parcelable;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import com.androidhive.musicplayer.R;
/**
* Created by bruce on 11/6/14.
*/
public class ArcProgress extends View {
private Paint paint;
protected Paint textPaint;
private RectF rectF = new RectF();
private float strokeWidth;
private float suffixTextSize;
private float bottomTextSize;
private String bottomText;
private float textSize;
private int textColor;
private int progress = 0;
private int max;
private int finishedStrokeColor;
private int unfinishedStrokeColor;
private float arcAngle;
private String suffixText = "%";
private float suffixTextPadding;
private float arcBottomHeight;
private final int default_finished_color = Color.WHITE;
private final int default_unfinished_color = Color.rgb(72, 106, 176);
private final int default_text_color = Color.rgb(66, 145, 241);
private final float default_suffix_text_size;
private final float default_suffix_padding;
private final float default_bottom_text_size;
private final float default_stroke_width;
private final String default_suffix_text;
private final int default_max = 100;
private final float default_arc_angle = 360 * 0.8f;
private float default_text_size;
private final int min_size;
private static final String INSTANCE_STATE = "saved_instance";
private static final String INSTANCE_STROKE_WIDTH = "stroke_width";
private static final String INSTANCE_SUFFIX_TEXT_SIZE = "suffix_text_size";
private static final String INSTANCE_SUFFIX_TEXT_PADDING = "suffix_text_padding";
private static final String INSTANCE_BOTTOM_TEXT_SIZE = "bottom_text_size";
private static final String INSTANCE_BOTTOM_TEXT = "bottom_text";
private static final String INSTANCE_TEXT_SIZE = "text_size";
private static final String INSTANCE_TEXT_COLOR = "text_color";
private static final String INSTANCE_PROGRESS = "progress";
private static final String INSTANCE_MAX = "max";
private static final String INSTANCE_FINISHED_STROKE_COLOR = "finished_stroke_color";
private static final String INSTANCE_UNFINISHED_STROKE_COLOR = "unfinished_stroke_color";
private static final String INSTANCE_ARC_ANGLE = "arc_angle";
private static final String INSTANCE_SUFFIX = "suffix";
public ArcProgress(Context context) {
this(context, null);
}
public ArcProgress(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ArcProgress(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
default_text_size = Utils.sp2px(getResources(), 18);
min_size = (int) Utils.dp2px(getResources(), 100);
default_text_size = Utils.sp2px(getResources(), 40);
default_suffix_text_size = Utils.sp2px(getResources(), 15);
default_suffix_padding = Utils.dp2px(getResources(), 4);
default_suffix_text = "%";
default_bottom_text_size = Utils.sp2px(getResources(), 10);
default_stroke_width = Utils.dp2px(getResources(), 4);
TypedArray attributes = context.getTheme().obtainStyledAttributes(attrs, R.styleable.ArcProgress, defStyleAttr, 0);
initByAttributes(attributes);
attributes.recycle();
initPainters();
}
protected void initByAttributes(TypedArray attributes) {
finishedStrokeColor = attributes.getColor(R.styleable.ArcProgress_arc_finished_color, default_finished_color);
unfinishedStrokeColor = attributes.getColor(R.styleable.ArcProgress_arc_unfinished_color, default_unfinished_color);
textColor = attributes.getColor(R.styleable.ArcProgress_arc_text_color, default_text_color);
textSize = attributes.getDimension(R.styleable.ArcProgress_arc_text_size, default_text_size);
arcAngle = attributes.getFloat(R.styleable.ArcProgress_arc_angle, default_arc_angle);
setMax(attributes.getInt(R.styleable.ArcProgress_arc_max, default_max));
setProgress(attributes.getInt(R.styleable.ArcProgress_arc_progress, 0));
strokeWidth = attributes.getDimension(R.styleable.ArcProgress_arc_stroke_width, default_stroke_width);
suffixTextSize = attributes.getDimension(R.styleable.ArcProgress_arc_suffix_text_size, default_suffix_text_size);
suffixText = TextUtils.isEmpty(attributes.getString(R.styleable.ArcProgress_arc_suffix_text)) ? default_suffix_text : attributes.getString(R.styleable.ArcProgress_arc_suffix_text);
suffixTextPadding = attributes.getDimension(R.styleable.ArcProgress_arc_suffix_text_padding, default_suffix_padding);
bottomTextSize = attributes.getDimension(R.styleable.ArcProgress_arc_bottom_text_size, default_bottom_text_size);
bottomText = attributes.getString(R.styleable.ArcProgress_arc_bottom_text);
}
protected void initPainters() {
textPaint = new TextPaint();
textPaint.setColor(textColor);
textPaint.setTextSize(textSize);
textPaint.setAntiAlias(true);
paint = new Paint();
paint.setColor(default_unfinished_color);
paint.setAntiAlias(true);
paint.setStrokeWidth(strokeWidth);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeCap(Paint.Cap.ROUND);
}
#Override
public void invalidate() {
initPainters();
super.invalidate();
}
public float getStrokeWidth() {
return strokeWidth;
}
public void setStrokeWidth(float strokeWidth) {
this.strokeWidth = strokeWidth;
this.invalidate();
}
public float getSuffixTextSize() {
return suffixTextSize;
}
public void setSuffixTextSize(float suffixTextSize) {
this.suffixTextSize = suffixTextSize;
this.invalidate();
}
public String getBottomText() {
return bottomText;
}
public void setBottomText(String bottomText) {
this.bottomText = bottomText;
this.invalidate();
}
public int getProgress() {
return progress;
}
public void setProgress(int progress) {
this.progress = progress;
if (this.progress > getMax()) {
this.progress %= getMax();
}
invalidate();
}
public int getMax() {
return max;
}
public void setMax(int max) {
if (max > 0) {
this.max = max;
invalidate();
}
}
public float getBottomTextSize() {
return bottomTextSize;
}
public void setBottomTextSize(float bottomTextSize) {
this.bottomTextSize = bottomTextSize;
this.invalidate();
}
public float getTextSize() {
return textSize;
}
public void setTextSize(float textSize) {
this.textSize = textSize;
this.invalidate();
}
public int getTextColor() {
return textColor;
}
public void setTextColor(int textColor) {
this.textColor = textColor;
this.invalidate();
}
public int getFinishedStrokeColor() {
return finishedStrokeColor;
}
public void setFinishedStrokeColor(int finishedStrokeColor) {
this.finishedStrokeColor = finishedStrokeColor;
this.invalidate();
}
public int getUnfinishedStrokeColor() {
return unfinishedStrokeColor;
}
public void setUnfinishedStrokeColor(int unfinishedStrokeColor) {
this.unfinishedStrokeColor = unfinishedStrokeColor;
this.invalidate();
}
public float getArcAngle() {
return arcAngle;
}
public void setArcAngle(float arcAngle) {
this.arcAngle = arcAngle;
this.invalidate();
}
public String getSuffixText() {
return suffixText;
}
public void setSuffixText(String suffixText) {
this.suffixText = suffixText;
this.invalidate();
}
public float getSuffixTextPadding() {
return suffixTextPadding;
}
public void setSuffixTextPadding(float suffixTextPadding) {
this.suffixTextPadding = suffixTextPadding;
this.invalidate();
}
#Override
protected int getSuggestedMinimumHeight() {
return min_size;
}
#Override
protected int getSuggestedMinimumWidth() {
return min_size;
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
rectF.set(strokeWidth / 2f, strokeWidth / 2f, width - strokeWidth / 2f, MeasureSpec.getSize(heightMeasureSpec) - strokeWidth / 2f);
float radius = width / 2f;
float angle = (360 - arcAngle) / 2f;
arcBottomHeight = radius * (float) (1 - Math.cos(angle / 180 * Math.PI));
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float startAngle = 270 - arcAngle / 2f;
float finishedSweepAngle = progress / (float) getMax() * arcAngle;
float finishedStartAngle = startAngle;
paint.setColor(unfinishedStrokeColor);
canvas.drawArc(rectF, startAngle, arcAngle, false, paint);
paint.setColor(finishedStrokeColor);
canvas.drawArc(rectF, finishedStartAngle, finishedSweepAngle, false, paint);
String text = String.valueOf(getProgress());
if (!TextUtils.isEmpty(text)) {
textPaint.setColor(textColor);
textPaint.setTextSize(textSize);
float textHeight = textPaint.descent() + textPaint.ascent();
float textBaseline = (getHeight() - textHeight) / 2.0f;
canvas.drawText(text, (getWidth() - textPaint.measureText(text)) / 2.0f, textBaseline, textPaint);
textPaint.setTextSize(suffixTextSize);
float suffixHeight = textPaint.descent() + textPaint.ascent();
canvas.drawText(suffixText, getWidth() / 2.0f + textPaint.measureText(text) + suffixTextPadding, textBaseline + textHeight - suffixHeight, textPaint);
}
if (!TextUtils.isEmpty(getBottomText())) {
textPaint.setTextSize(bottomTextSize);
float bottomTextBaseline = getHeight() - arcBottomHeight - (textPaint.descent() + textPaint.ascent()) / 2;
canvas.drawText(getBottomText(), (getWidth() - textPaint.measureText(getBottomText())) / 2.0f, bottomTextBaseline, textPaint);
}
}
#Override
protected Parcelable onSaveInstanceState() {
final Bundle bundle = new Bundle();
bundle.putParcelable(INSTANCE_STATE, super.onSaveInstanceState());
bundle.putFloat(INSTANCE_STROKE_WIDTH, getStrokeWidth());
bundle.putFloat(INSTANCE_SUFFIX_TEXT_SIZE, getSuffixTextSize());
bundle.putFloat(INSTANCE_SUFFIX_TEXT_PADDING, getSuffixTextPadding());
bundle.putFloat(INSTANCE_BOTTOM_TEXT_SIZE, getBottomTextSize());
bundle.putString(INSTANCE_BOTTOM_TEXT, getBottomText());
bundle.putFloat(INSTANCE_TEXT_SIZE, getTextSize());
bundle.putInt(INSTANCE_TEXT_COLOR, getTextColor());
bundle.putInt(INSTANCE_PROGRESS, getProgress());
bundle.putInt(INSTANCE_MAX, getMax());
bundle.putInt(INSTANCE_FINISHED_STROKE_COLOR, getFinishedStrokeColor());
bundle.putInt(INSTANCE_UNFINISHED_STROKE_COLOR, getUnfinishedStrokeColor());
bundle.putFloat(INSTANCE_ARC_ANGLE, getArcAngle());
bundle.putString(INSTANCE_SUFFIX, getSuffixText());
return bundle;
}
#Override
protected void onRestoreInstanceState(Parcelable state) {
if(state instanceof Bundle) {
final Bundle bundle = (Bundle) state;
strokeWidth = bundle.getFloat(INSTANCE_STROKE_WIDTH);
suffixTextSize = bundle.getFloat(INSTANCE_SUFFIX_TEXT_SIZE);
suffixTextPadding = bundle.getFloat(INSTANCE_SUFFIX_TEXT_PADDING);
bottomTextSize = bundle.getFloat(INSTANCE_BOTTOM_TEXT_SIZE);
bottomText = bundle.getString(INSTANCE_BOTTOM_TEXT);
textSize = bundle.getFloat(INSTANCE_TEXT_SIZE);
textColor = bundle.getInt(INSTANCE_TEXT_COLOR);
setMax(bundle.getInt(INSTANCE_MAX));
setProgress(bundle.getInt(INSTANCE_PROGRESS));
finishedStrokeColor = bundle.getInt(INSTANCE_FINISHED_STROKE_COLOR);
unfinishedStrokeColor = bundle.getInt(INSTANCE_UNFINISHED_STROKE_COLOR);
suffixText = bundle.getString(INSTANCE_SUFFIX);
initPainters();
super.onRestoreInstanceState(bundle.getParcelable(INSTANCE_STATE));
return;
}
super.onRestoreInstanceState(state);
}
}
I want to increase radius of arc and increase circumference of it .
Any hep wil be appreciated .
Thanx in advance :)
I want to increase radius of arc and increase circumference of it
Accordingly to the code you posted, the size is decide during onMeasure
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
rectF.set(strokeWidth / 2f, strokeWidth / 2f, width - strokeWidth / 2f, MeasureSpec.getSize(heightMeasureSpec) - strokeWidth / 2f);
float radius = width / 2f;
float angle = (360 - arcAngle) / 2f;
arcBottomHeight = radius * (float) (1 - Math.cos(angle / 180 * Math.PI));
}
So, in order to increase the radius, you have to increase width and height your provide in the layout. If you want to change the arc's color you can provide statically, in the xml
arc_finished_color and arc_unfinished_color
E.g.
<com.androidhive.musicplayer.equalizer.ArcProgress
android:id="#+id/songProgressBar"
android:background="#214193"
android:layout_marginLeft="50dp"
android:layout_width="100dp"
android:layout_height="100dp"
custom:arc_progress="55"
custom:arc_bottom_text="MEMORY"
custom:arc_finished_color="#color/finished_color"
custom:arc_unfinished_color="#color/unfinished_color"/>
I am using rajawali library to load obj model in android, for that i use this camera class which contains guesture detector and guesture listener but I need to extra panning operation in this class:
public class ArcballCamera extends Camera
{
private Context mContext;
private ScaleGestureDetector mScaleDetector;
private View.OnTouchListener mGestureListener;
private GestureDetector mDetector;
private View mView;
private boolean mIsRotating;
private boolean mIsScaling;
private Vector3 mCameraStartPos;
private Vector3 mPrevSphereCoord;
private Vector3 mCurrSphereCoord;
private Vector2 mPrevScreenCoord;
private Vector2 mCurrScreenCoord;
private Quaternion mStartOrientation;
private Quaternion mCurrentOrientation;
private Object3D mEmpty;
private Object3D mTarget;
private Matrix4 mScratchMatrix;
private Vector3 mScratchVector;
private double mStartFOV;
public ArcballCamera(Context context, View view) {
this(context, view, null);
}
public ArcballCamera(Context context, View view, Object3D target) {
super();
mContext = context;
mTarget = target;
mView = view;
initialize();
addListeners();
}
private void initialize() {
mStartFOV = mFieldOfView;
mLookAtEnabled = true;
setLookAt(0, 0, 0);
mEmpty = new Object3D();
mScratchMatrix = new Matrix4();
mScratchVector = new Vector3();
mCameraStartPos = new Vector3();
mPrevSphereCoord = new Vector3();
mCurrSphereCoord = new Vector3();
mPrevScreenCoord = new Vector2();
mCurrScreenCoord = new Vector2();
mStartOrientation = new Quaternion();
mCurrentOrientation = new Quaternion();
}
#Override
public void setProjectionMatrix(int width, int height) {
super.setProjectionMatrix(width, height);
}
private void mapToSphere(final float x, final float y, Vector3 out)
{
float lengthSquared = x * x + y * y;
if (lengthSquared > 1)
{
out.setAll(x, y, 0);
out.normalize();
}
else
{
out.setAll(x, y, Math.sqrt(1 - lengthSquared));
}
}
private void mapToScreen(final float x, final float y, Vector2 out)
{
out.setX((2 * x - mLastWidth) / mLastWidth);
out.setY(-(2 * y - mLastHeight) / mLastHeight);
}
private void startRotation(final float x, final float y)
{
mapToScreen(x, y, mPrevScreenCoord);
mCurrScreenCoord.setAll(mPrevScreenCoord.getX(), mPrevScreenCoord.getY());
mIsRotating = true;
}
private void updateRotation(final float x, final float y)
{
mapToScreen(x, y, mCurrScreenCoord);
applyRotation();
}
private void endRotation()
{
mStartOrientation.multiply(mCurrentOrientation);
}
private void applyRotation()
{
if (mIsRotating)
{
mapToSphere((float) mPrevScreenCoord.getX(), (float) mPrevScreenCoord.getY(), mPrevSphereCoord);
mapToSphere((float) mCurrScreenCoord.getX(), (float) mCurrScreenCoord.getY(), mCurrSphereCoord);
Vector3 rotationAxis = mPrevSphereCoord.clone();
rotationAxis.cross(mCurrSphereCoord);
rotationAxis.normalize();
double rotationAngle = Math.acos(Math.min(1, mPrevSphereCoord.dot(mCurrSphereCoord)));
mCurrentOrientation.fromAngleAxis(rotationAxis, MathUtil.radiansToDegrees(rotationAngle));
mCurrentOrientation.normalize();
Quaternion q = new Quaternion(mStartOrientation);
q.multiply(mCurrentOrientation);
mEmpty.setOrientation(q);
}
}
#Override
public Matrix4 getViewMatrix() {
Matrix4 m = super.getViewMatrix();
if(mTarget != null) { mScratchMatrix.identity();
mScratchMatrix.translate(mTarget.getPosition());
m.multiply(mScratchMatrix);
}
mScratchMatrix.identity();
mScratchMatrix.rotate(mEmpty.getOrientation());
m.multiply(mScratchMatrix);
if(mTarget != null) {
mScratchVector.setAll(mTarget.getPosition());
mScratchVector.inverse();
mScratchMatrix.identity();
mScratchMatrix.translate(mScratchVector);
m.multiply(mScratchMatrix);
}
return m;
}
public void setFieldOfView(double fieldOfView) {
synchronized (mFrustumLock) {
mStartFOV = fieldOfView;
super.setFieldOfView(fieldOfView);
}
}
... In this method defined guesture detector and listeners, so i need to have panning here.
so anyone tell me how to use panning here...
private void addListeners() {
((Activity) mContext).runOnUiThread(new Runnable() {
#Override
public void run() {
mDetector = new GestureDetector(mContext, new GestureListener());
mScaleDetector = new ScaleGestureDetector(mContext, new ScaleListener());
mGestureListener = new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
mScaleDetector.onTouchEvent(event);
if (!mIsScaling) {
mDetector.onTouchEvent(event);
if (event.getAction() == MotionEvent.ACTION_UP) {
if (mIsRotating) {
endRotation();
mIsRotating = false;
}
}
}
return true;
}
};
mView.setOnTouchListener(mGestureListener);
}
});
}
public void setTarget(Object3D target) {
mTarget = target;
setLookAt(mTarget.getPosition());
}
public Object3D getTarget() {
return mTarget;
}
private class GestureListener extends GestureDetector.SimpleOnGestureListener {
#Override
public boolean onScroll(MotionEvent event1, MotionEvent event2, float distanceX, float distanceY) {
if(!mIsRotating) {
startRotation(event2.getX(), event2.getY());
return false;
}
mIsRotating = true;
updateRotation(event2.getX(), event2.getY());
return false;
}
}
private class ScaleListener
extends ScaleGestureDetector.SimpleOnScaleGestureListener
{
#Override
public boolean onScale(ScaleGestureDetector detector) {
double fov = Math.max(30, Math.min(100, mStartFOV * (1.0 / detector.getScaleFactor())));
setFieldOfView(fov);
return true;
}
#Override
public boolean onScaleBegin (ScaleGestureDetector detector) {
mIsScaling = true;
mIsRotating = false;
return super.onScaleBegin(detector);
}
#Override
public void onScaleEnd (ScaleGestureDetector detector) {
mIsRotating = false;
mIsScaling = false;
}
}
}**
When trying this snippet of code from AOSP Launcher3:
void generatePressedFocusedStates(ImageView v) {
if (!mStatesUpdated && v != null) {
mStatesUpdated = true;
Bitmap original = createOriginalImage(v, mTempCanvas);
Bitmap outline = createImageWithOverlay(v, mTempCanvas, mHighlightColor);
Bitmap hotword = createImageWithOverlay(v, mTempCanvas, mHotwordColor);
FastBitmapDrawable originalD = new FastBitmapDrawable(original);
FastBitmapDrawable outlineD = new FastBitmapDrawable(outline);
FastBitmapDrawable hotwordD = new FastBitmapDrawable(hotword);
StateListDrawable states = new StateListDrawable();
states.addState(new int[] {android.R.attr.state_pressed}, outlineD);
states.addState(new int[] {android.R.attr.state_focused}, outlineD);
states.addState(new int[] {R.attr.stateHotwordOn}, hotwordD);
states.addState(new int[] {}, originalD);
v.setImageDrawable(states);
}
}
The 2 ImageView s I applied this to suddenly lose their Drawables: they're empty.
If I replace the last line with
v.setImageDrawable(originalD);
// or
v.setImageDrawable(outlineD);
// or
v.setImageDrawable(hotwordD);
then the ImageViews display the chosen drawable. So I think this proves that there's no problem with the ImageView or with the Drawables... Only with the StateListDrawable.
For completion, here are the used methods:
private Bitmap createOriginalImage(ImageView v, Canvas canvas) {
final Drawable d = v.getDrawable();
final Bitmap b = Bitmap.createBitmap(
d.getIntrinsicWidth(), d.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
canvas.setBitmap(b);
canvas.save();
d.draw(canvas);
canvas.restore();
canvas.setBitmap(null);
return b;
}
-
private Bitmap createImageWithOverlay(ImageView v, Canvas canvas, int color) {
final Drawable d = v.getDrawable();
final Bitmap b = Bitmap.createBitmap(
d.getIntrinsicWidth(), d.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
canvas.setBitmap(b);
canvas.save();
d.draw(canvas);
canvas.restore();
canvas.drawColor(color, PorterDuff.Mode.SRC_IN);
canvas.setBitmap(null);
return b;
}
-
class FastBitmapDrawable extends Drawable {
private Bitmap mBitmap;
private int mAlpha;
private final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
FastBitmapDrawable(Bitmap b) {
mAlpha = 255;
mBitmap = b;
setBounds(0, 0, b.getWidth(), b.getHeight());
}
#Override
public void draw(Canvas canvas) {
final Rect r = getBounds();
// Draw the bitmap into the bounding rect
canvas.drawBitmap(mBitmap, null, r, mPaint);
}
#Override
public void setColorFilter(ColorFilter cf) {
mPaint.setColorFilter(cf);
}
#Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
#Override
public void setAlpha(int alpha) {
mAlpha = alpha;
mPaint.setAlpha(alpha);
}
public void setFilterBitmap(boolean filterBitmap) {
mPaint.setFilterBitmap(filterBitmap);
mPaint.setAntiAlias(filterBitmap);
}
public int getAlpha() {
return mAlpha;
}
#Override
public int getIntrinsicWidth() {
return getBounds().width();
}
#Override
public int getIntrinsicHeight() {
return getBounds().height();
}
#Override
public int getMinimumWidth() {
return getBounds().width();
}
#Override
public int getMinimumHeight() {
return getBounds().height();
}
public Bitmap getBitmap() {
return mBitmap;
}
}