ClassCastException with no debuggable errors - java

I am trying to create an object of fingerline(class) in drawline(activity).The fingerline takes the context of MainActivity(activity).I get ClassCastException showing that
Process: com.example.caddrawingtool, PID: 11405
java.lang.RuntimeException: Unable to instantiate application
com.example.caddrawingtool.MainActivity: java.lang.ClassCastException:
com.example.caddrawingtool.MainActivity cannot be cast to android.app.Application
at android.app.LoadedApk.makeApplication(LoadedApk.java:1226)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6504)
at android.app.ActivityThread.access$1400(ActivityThread.java:229)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1892)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7436)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:980)
I have changed getApplicationContext() in drawline where the fingerline object was created to Activity context by using
this
I am not able to use
MainActivity.this
though.
Is there a way to simplify all this?
My MainActivity code:
public class MainActivity extends AppCompatActivity {
fingerline dv;
private Paint mpaint;
private Context context;
MainActivity MainActivity(){
return MainActivity.this;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dv = new fingerline(this);
setContentView(dv);
dv.setBackgroundColor(Color.BLACK);
mpaint = new Paint();
mpaint.setAntiAlias(true);
mpaint.setDither(true);
mpaint.setColor(Color.WHITE);
mpaint.setStyle(Paint.Style.STROKE);
mpaint.setStrokeJoin(Paint.Join.MITER);
mpaint.setStrokeCap(Paint.Cap.ROUND);
mpaint.setStrokeWidth(12);
getSupportActionBar().setTitle("3D TOOL");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.my_menu, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
int id = item.getItemId();
switch (id) {
case R.id.line:
Intent intent = new Intent(this, drawline2.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
this.startActivity(intent);
break;
case R.id.circle:
Intent intent1=new Intent(this,drawcircle.class);
intent1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
this.startActivity(intent1);
break;
case R.id.rectangle:
Intent intent2=new Intent(this,drawrectangle.class);
intent2.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
this.startActivity(intent2);
break;
case R.id.offset:
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
My fingerline code:
public class fingerline extends View {
public int width, height;
private Bitmap mbitmap;
private Canvas mcanvas;
private Paint mpaint, mbitmappaint, circlepaint;
private float startx;
private float starty;
private float endx;
private float endy;
private Path path, circlepath;
Context c;
public fingerline(Context context) {
super(context);
// c = context;
path = new Path();
mpaint = new Paint();
mbitmappaint = new Paint(Paint.DITHER_FLAG);
circlepaint = new Paint();
circlepath = new Path();
circlepaint.setAntiAlias(true);
circlepaint.setColor(Color.WHITE);
circlepaint.setStyle(Paint.Style.STROKE);
circlepaint.setStrokeJoin(Paint.Join.MITER);
circlepaint.setStrokeWidth(4f);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mbitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mcanvas = new Canvas(mbitmap);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mpaint.setStyle(Paint.Style.STROKE);
mpaint.setColor(Color.WHITE);
mpaint.setStrokeWidth(12);
mpaint.setAntiAlias(true);
mpaint.setDither(true);
mpaint.setStrokeJoin(Paint.Join.MITER);
mpaint.setStrokeCap(Paint.Cap.ROUND);
canvas.drawBitmap(mbitmap, 0, 0, mbitmappaint);
canvas.drawPath(path, mpaint);
canvas.drawPath(circlepath, circlepaint);
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
private void touch_start(float x, float y) {
path.reset();
path.moveTo(x, y);
mX = x;
mY = y;
}
private void touch_move(float x, float y) {
float dX = Math.abs(x - mX);
float dY = Math.abs(y - mY);
if (dX >= TOUCH_TOLERANCE) {
path.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
mX = x;
mY = y;
}
}
private void touch_up() {
path.lineTo(mX, mY);
circlepath.reset();
mcanvas.drawPath(path, mpaint);
path.reset();
}
#SuppressLint("ClickableViewAccessibility")
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startx = event.getX();
starty = event.getY();
touch_start(startx, starty);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
startx = event.getX();
starty = event.getY();
touch_move(startx, starty);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
break;
}
return true;
}
}
My drawline code:
public class drawline2 extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drawline2);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
EditText editText, editText1;
editText = (EditText) findViewById(R.id.length);
editText1 = (EditText) findViewById(R.id.angle);
Canvas canvas;
Paint paint = new Paint();
Paint circlepaint = new Paint();
Path path = new Path();
Path cpath = new Path();
circlepaint.setAntiAlias(true);
circlepaint.setStrokeWidth(4f);
circlepaint.setColor(Color.WHITE);
circlepaint.setStyle(Paint.Style.STROKE);
circlepaint.setStrokeJoin(Paint.Join.MITER);
fingerline dv;
dv = new fingerline(this);
dv.setBackgroundColor(Color.BLACK);
setContentView(dv);
circlepaint.setAntiAlias(true);
circlepaint.setDither(true);
String value = editText.getText().toString();
int length =0;
double angle=0;
if(value!=null && value.length()>0){
try{
length = Integer.parseInt(value);
}
catch (NullPointerException e){
length=0;
}
}
String value1 = editText1.getText().toString();
if(value1!=null && value1.length()>0){
try{
angle = Double.parseDouble(value1);
}
catch (NullPointerException e){
angle=0;
}
}
int startX, startY, endX, endY, x, y;
x= 0;
y=0;
path.reset();
path.moveTo(x, y);
startX = (int) x;
startY = (int) y;
endY = (int) (x + length * Math.cos(angle));
endX = (int) (x + length * Math.sin(angle));
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
}
Thanks in advance.

In short:
MainActivity cannot be cast to android.app.Application
You could make this an awful lot more readable by calling it DrawlineActivity and FingerlineActivity. Then just use this or DrawlineActivity.this as the Context.

Related

Combining two onTouch events

For my app I need to combine two onTouch events. With the first I want to get the color of a clicked pixel of an imageView and the other event should make the picture zoomable. I tried it separate and it seemed to work on its own, but when I try to combine these two things it doesn’t work anymore. Why won‘t they work together?
My code:
public class MainActivity extends AppCompatActivity {
private ImageView imageView;
private Bitmap bitmap;
private ScaleGestureDetector mScaleGestureDetector;
private float mScaleFactor = 1.0f;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ImageView imageView = (ImageView) findViewById(R.id.imageView);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setDrawingCacheEnabled(true);
imageView.buildDrawingCache(true);
mScaleGestureDetector = new ScaleGestureDetector(this, new ScaleListener());
imageView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
mScaleGestureDetector.onTouchEvent(event);
bitmap = imageView.getDrawingCache();
int pixel = bitmap.getPixel((int) event.getX(), (int) event.getY());
String text = "x = " + event.getX() + ", y = " + event.getY();
Log.d("Position", text);
int redValue = Color.red(pixel);
int greenValue = Color.green(pixel);
int blueValue = Color.blue(pixel);
return true;
}
});
}
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
#Override
public boolean onScale(ScaleGestureDetector scaleGestureDetector){
mScaleFactor *= scaleGestureDetector.getScaleFactor();
mScaleFactor = Math.max(1.0f,
Math.min(mScaleFactor, 1.7f));
imageView.setScaleX(mScaleFactor);
imageView.setScaleY(mScaleFactor);
return true;
}
}
}
imageView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
mScaleGestureDetector.onTouchEvent(event);
bitmap = imageView.getDrawingCache();
int pixel = bitmap.getPixel((int) event.getX(), (int) event.getY());
String text = "x = " + event.getX() + ", y = " + event.getY();
Log.d("Position", text);
int redValue = Color.red(pixel);
int greenValue = Color.green(pixel);
int blueValue = Color.blue(pixel);
return false;
}
});
I guess its because you are consuming the touch here. Try returning false.

android how to recycle image before loading a new one

I have a out of memory problem here in which i have full screen images being displayed. I want to show images in full screen and I have two buttons to cycle through them to the left or to the right. How can i have the past images be recycled before showing the next to prevent the out of memory exception? or is there an even better way to do so?
here is my class in which i view the image.
public class ImageViewActivity extends Activity
{
private Button btnHome;
private Button btnBack;
private ImageButton btnLeft;
private ImageButton btnRight;
ImageView imageView;
RelativeLayout layout;
int height;
int width;
Bitmap bitmap;
String[] imagesPath;
int position;
// These matrices will be used to move and zoom image
Matrix matrix = new Matrix();
Matrix savedMatrix = new Matrix();
// We can be in one of these 3 states
static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;
int mode = NONE;
// Remember some things for zooming
PointF start = new PointF();
PointF mid = new PointF();
float oldDist = 1f;
String savedItemClicked;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.imageview_activity);
btnHome = (Button) findViewById(R.id.btnHome);
btnBack = (Button) findViewById(R.id.btnBack);
btnLeft = (ImageButton) findViewById(R.id.leftArrow);
btnRight = (ImageButton) findViewById(R.id.rightArrow);
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
height = displayMetrics.heightPixels;
width = displayMetrics.widthPixels;
imagesPath = getIntent().getStringExtra("IMAGES").split("\\|");
position = getIntent().getIntExtra("POSITION", 0);
bitmap = BitmapFactory.decodeFile(imagesPath[position]);
imageView = (ImageView)findViewById(R.id.displayImage);
imageView.setImageBitmap(Bitmap.createScaledBitmap(bitmap, width, height, false));
btnLeft.setOnClickListener(new View.OnClickListener()
{
public void onClick(View arg0)
{
if (position == 0)
position = 5;
else
position--;
RectF imageRectF = new RectF(0, 0, width, height);
RectF viewRectF = new RectF(0, 0, width, height);
matrix.setRectToRect(imageRectF, viewRectF, Matrix.ScaleToFit.CENTER);
bitmap = BitmapFactory.decodeFile(imagesPath[position]);
ImageView imageView = (ImageView)findViewById(R.id.displayImage);
imageView.setImageBitmap(Bitmap.createScaledBitmap(bitmap, width, height, false));
imageView.setImageMatrix(matrix);
}
});
btnRight.setOnClickListener(new View.OnClickListener()
{
public void onClick(View arg0)
{
if (position == 5)
position = 0;
else
position++;
RectF imageRectF = new RectF(0, 0, width, height);
RectF viewRectF = new RectF(0, 0, width, height);
matrix.setRectToRect(imageRectF, viewRectF, Matrix.ScaleToFit.CENTER);
bitmap = BitmapFactory.decodeFile(imagesPath[position]);
ImageView imageView = (ImageView)findViewById(R.id.displayImage);
imageView.setImageBitmap(Bitmap.createScaledBitmap(bitmap, width, height, false));
imageView.setImageMatrix(matrix);
}
});
btnHome.setOnClickListener(new View.OnClickListener()
{
public void onClick(View arg0)
{
Intent ActivitySwitch = new Intent(getApplicationContext(), MainMenuActivity.class);
startActivity(ActivitySwitch);
}
});
btnBack.setOnClickListener(new View.OnClickListener()
{
public void onClick(View arg0)
{
Intent ActivitySwitch = new Intent(getApplicationContext(), AddClientActivity.class);
startActivity(ActivitySwitch);
}
});
imageView.setOnTouchListener(new View.OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent event)
{
ImageView view = (ImageView) v;
dumpEvent(event);
// Handle touch events here...
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
mode = DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(event);
if (oldDist > 10f) {
savedMatrix.set(matrix);
midPoint(mid, event);
mode = ZOOM;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
// ...
matrix.set(savedMatrix);
matrix.postTranslate(event.getX() - start.x, event.getY()
- start.y);
} else if (mode == ZOOM) {
float newDist = spacing(event);
if (newDist > 10f) {
matrix.set(savedMatrix);
float scale = newDist / oldDist;
matrix.postScale(scale, scale, mid.x, mid.y);
}
}
break;
}
view.setImageMatrix(matrix);
return true;
}
});
}
private void dumpEvent(MotionEvent event) {
String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE",
"POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };
StringBuilder sb = new StringBuilder();
int action = event.getAction();
int actionCode = action & MotionEvent.ACTION_MASK;
sb.append("event ACTION_").append(names[actionCode]);
if (actionCode == MotionEvent.ACTION_POINTER_DOWN
|| actionCode == MotionEvent.ACTION_POINTER_UP) {
sb.append("(pid ").append(
action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
sb.append(")");
}
sb.append("[");
for (int i = 0; i < event.getPointerCount(); i++) {
sb.append("#").append(i);
sb.append("(pid ").append(event.getPointerId(i));
sb.append(")=").append((int) event.getX(i));
sb.append(",").append((int) event.getY(i));
if (i + 1 < event.getPointerCount())
sb.append(";");
}
sb.append("]");
}
/** Determine the space between the first two fingers */
private float spacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return (float)Math.sqrt(x * x + y * y);
}
/** Calculate the mid point of the first two fingers */
private void midPoint(PointF point, MotionEvent event) {
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
point.set(x / 2, y / 2);
}
thank you for any input and if you need any additional information please feel free to ask!
I would either scale down the image or consider using the Picasso image loading library: http://square.github.io/picasso/
It is also really simply to use and prevents a lot Out of Memory Exceptions.
Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);
it was a lot simpler then i first imagined. i simply added this
bitmap.recycle();
before i declared my bitmap to the new image.

How to rotate imageview in your positions using Matrix in Android?

I have created simple app with pinch zoom, panning and rotation. They are working very well but not the rotation in your position.
I have used Matrix class.
My Activity code
public class MainActivity extends AppCompatActivity implements View.OnTouchListener {
Matrix saveMatrix = new Matrix();
private ImageView viewImage;
private Button btnCapture;
private static final int RESULT_LOAD_IMAGE = 1;
private static final int REQUEST_IMAGE_CAPTURE = 2;
Matrix matrix = new Matrix();
private Uri mCapturedImageURI;
static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;
int mode = NONE;
PointF start = new PointF();
PointF mid = new PointF();
float oldDist = 1f;
private float d = 0f;
private float newRot = 0f;
private float[] lastEvent = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnCapture = (Button) findViewById(R.id.btnCapture);
viewImage = (ImageView) findViewById(R.id.viewImage);
viewImage.setOnTouchListener(MainActivity.this);
initListerner();
}
public void initListerner() {
btnCapture.setVisibility(View.VISIBLE);
btnCapture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
btnCapture.setVisibility(View.GONE);
final Dialog dialog = new Dialog(MainActivity.this);
dialog.setContentView(R.layout.custom_dialog_box);
dialog.setTitle("Title...");
Button dialogButton = (Button) dialog.findViewById(R.id.btnExit);
dialogButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
Button btnChoosePath = (Button) dialog.findViewById(R.id.btnChoosePath);
btnChoosePath.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
activeGallery();
dialog.dismiss();
}
});
Button btnTakePhoto = (Button) dialog.findViewById(R.id.btnTakePhoto);
btnTakePhoto.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
activeTakePhoto();
dialog.dismiss();
}
});
dialog.show();
}
});
}
#Override
public void onBackPressed() {
super.onBackPressed();
btnCapture.setVisibility(View.VISIBLE);
}
private void activeTakePhoto() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
String fileName = "temp.jpg";
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, fileName);
mCapturedImageURI = getContentResolver()
.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
values);
takePictureIntent
.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedImageURI);
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
private void activeGallery() {
Intent intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, RESULT_LOAD_IMAGE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case RESULT_LOAD_IMAGE:
if (requestCode == RESULT_LOAD_IMAGE &&
resultCode == RESULT_OK && null != data) {
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver()
.query(selectedImage, filePathColumn, null, null,
null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
viewImage.setImageBitmap(BitmapFactory.decodeFile(picturePath));
}
case REQUEST_IMAGE_CAPTURE:
if (requestCode == REQUEST_IMAGE_CAPTURE &&
resultCode == RESULT_OK) {
String[] projection = {MediaStore.Images.Media.DATA};
Cursor cursor =
getContentResolver().query(mCapturedImageURI, projection, null,
null, null);
int column_index_data = cursor.getColumnIndexOrThrow(
MediaStore.Images.Media.DATA);
cursor.moveToFirst();
String picturePath = cursor.getString(column_index_data);
cursor.close();
viewImage.setImageBitmap(BitmapFactory.decodeFile(picturePath));
}
}
}
#Override
public boolean onTouch(View v, MotionEvent motionEvent) {
ImageView view = (ImageView) v;
switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
saveMatrix.set(matrix);
start.set(motionEvent.getX(), motionEvent.getY());
mode = DRAG;
lastEvent = null;
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(motionEvent);
if (oldDist > 10f) {
saveMatrix.set(matrix);
midPoint(mid, motionEvent);
mode = ZOOM;
}
lastEvent = new float[4];
lastEvent[0] = motionEvent.getX(0);
lastEvent[1] = motionEvent.getX(1);
lastEvent[2] = motionEvent.getY(0);
lastEvent[3] = motionEvent.getY(1);
d = rotation(motionEvent);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
lastEvent = null;
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
matrix.set(saveMatrix);
float dx = motionEvent.getX() - start.x;
float dy = motionEvent.getY() - start.y;
matrix.postTranslate(dx, dy);
} else if (mode == ZOOM) {
float newDist = spacing(motionEvent);
if (newDist > 10f) {
matrix.set(saveMatrix);
float scale = (newDist / oldDist);
matrix.postScale(scale, scale, mid.x, mid.y);
}
if (lastEvent != null && motionEvent.getPointerCount() == 2) {
newRot = rotation(motionEvent);
float r = newRot - d;
float[] values = new float[9];
matrix.getValues(values);
float tx = values[2];
float ty = values[5];
float sx = values[0];
float xc = (view.getWidth() / 2) * sx;
float yc = (view.getHeight() / 2) * sx;
matrix.postRotate(r, tx + xc, ty + yc);
}
}
break;
}
view.setImageMatrix(matrix);
return true;
}
private float spacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return (float) Math.sqrt(x * x + y * y);
}
private void midPoint(PointF point, MotionEvent event) {
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
point.set(x / 2, y / 2);
}
private float rotation(MotionEvent event) {
double delta_x = (event.getX(0) - event.getX(1));
double delta_y = (event.getY(0) - event.getY(1));
double radians = Math.atan2(delta_y, delta_x);
return (float) Math.toDegrees(radians);
}
}

Why won't my undo button work in android java?

I have an image which a user can paint on in my android application. I decided to add an undo button to it so the user can cancel mistakes. I made it so that when the user draws on the screen, it saves the bitmap to an array. Then when the undo button is pressed, it changes the image to the last bitmap in the array. However, this just keeps setting the image to whatever the current image is (i.e. it doesn't change it at all).
public class edit extends AppCompatActivity implements View.OnClickListener {
float MoveX,MoveY,DownY,DownX,UpY=0,UpX ;
List<Bitmap> undos = new ArrayList<Bitmap>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit);
final ImageButton btn2 = (ImageButton) findViewById(R.id.imageButton2);
btn2.setOnClickListener(this);
final Button buttonchoose = (Button) findViewById(R.id.buttonchoose);
buttonchoose.setOnClickListener(this);
final RelativeLayout ViewX = (RelativeLayout) findViewById(R.id.RLXV);
ViewTreeObserver vto = ViewX.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
ViewX.getViewTreeObserver().removeOnGlobalLayoutListener(this);
Intent intent7 = getIntent();
String bitmapXY = (String) intent7.getExtras().get("BitmapImage");
GraphRequest request = GraphRequest.newGraphPathRequest(
AccessToken.getCurrentAccessToken(),
"/" + bitmapXY,
new GraphRequest.Callback() {
#Override
public void onCompleted(GraphResponse response) {
HttpURLConnection connection = null;
try {
int ViewWidth = ViewX.getMeasuredWidth();
JSONObject photos = response.getJSONObject();
JSONArray linkY = photos.optJSONArray("images");
final JSONObject linkO = linkY.optJSONObject(0);
final String link2 = linkO.optString("source");
URL LINKF = new URL(link2);
connection = (HttpURLConnection) LINKF.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(input);
float HH = (float) bitmap.getHeight();
float WW = (float) bitmap.getWidth();
float ViewWidthX = (float) ViewWidth;
float height = (HH / WW) * ViewWidthX;
Bitmap bitmapF = Bitmap.createScaledBitmap(bitmap, ViewWidth, Math.round(height), false);
final ImageView image1 = (ImageView) findViewById(R.id.image1);
image1.setImageBitmap(bitmapF);
undos.add(bitmapF);
image1.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Display d = getWindowManager().getDefaultDisplay();
float dw = d.getWidth();
float dh = d.getHeight();
float x = event.getX();
float y = event.getY();
float r = 2;
Bitmap BTX = ((BitmapDrawable)image1.getDrawable()).getBitmap();
Canvas canvas = new Canvas(BTX);
canvas.drawBitmap(BTX,0,0,null);
Paint paint1 = new Paint();
int bg1 = buttonchoose.getDrawingCacheBackgroundColor();
ColorDrawable buttonColor = (ColorDrawable) buttonchoose.getBackground();
int bg2 =buttonColor.getColor();
paint1.setColor(bg2);
paint1.setShadowLayer(5, 2, 2, bg2);
paint1.setStrokeWidth(20);
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
DownY = event.getY();
DownX = event.getX();
break;
case MotionEvent.ACTION_MOVE:
MoveY = event.getY();
MoveX = event.getX();
canvas.drawLine(DownX, DownY, MoveX, MoveY, paint1);
image1.invalidate();
DownX = MoveX;
DownY=MoveY;
break;
case MotionEvent.ACTION_UP:
UpY = event.getY();
UpX = event.getX();
canvas.drawLine(DownX, DownY, UpX, UpY, paint1);
image1.invalidate();
Bitmap BTXYZ = ((BitmapDrawable)image1.getDrawable()).getBitmap();
break;
}
return true;
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "images");
request.setParameters(parameters);
request.executeAsync();
}
});
}
#Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.buttonchoose:
final ColorPicker cp = new ColorPicker(edit.this, 0, 0, 0);
/* Show color picker dialog */
cp.show();
/* On Click listener for the dialog, when the user select the color */
Button okColor = (Button) cp.findViewById(R.id.okColorButton);
okColor.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
/* You can get single channel (value 0-255) */
int selectedColorR = cp.getRed();
int selectedColorG = cp.getGreen();
int selectedColorB = cp.getBlue();
/* Or the android RGB Color (see the android Color class reference) */
int selectedColorRGB = cp.getColor();
Button buttonchoose = (Button) findViewById(R.id.buttonchoose);
buttonchoose.setText("");
buttonchoose.setBackgroundColor(selectedColorRGB);
cp.dismiss();
}
});
break;
case R.id.imageButton2:
int newImage = undos.size();
Log.e("Lenght of Array",""+newImage);
if(newImage >=1) {
Bitmap newImage2 = undos.get(newImage-2);
ImageView IMGXV = (ImageView) findViewById(R.id.image1);
IMGXV.setImageBitmap(newImage2);
undos.remove(newImage-1);
}
break;
}
}
}
Try this exact code -
case R.id.imageButton2:
if(undos.size() > 0) {
Bitmap newImage2 = undos.remove(undos.size() - 1);
ImageView IMGXV = (ImageView) findViewById(R.id.image1);
IMGXV.setImageBitmap(newImage2);
}
break;
EDIT Added an extra line in onGlobalLayout(), try this -
Bitmap bitmapF = Bitmap.createScaledBitmap(bitmap, ViewWidth, Math.round(height), false);
final ImageView image1 = (ImageView) findViewById(R.id.image1);
image1.setImageBitmap(bitmapF);
//The extra line before adding bitmap to arraylist.
Bitmap bitmapFcopy = bitmapFcopy.copy(bitmapFcopy.getConfig(), true);
undos.add(bitmapFcopy);
EDIT 2
public class edit extends AppCompatActivity implements View.OnClickListener {
//Declare the imageview here and access this everywhere.
ImageView image1;
float MoveX,MoveY,DownY,DownX,UpY=0,UpX ;
List<Bitmap> undos = new ArrayList<Bitmap>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit);
//Get the reference here
image1 = (ImageView) findViewById(R.id.image1);
final ImageButton btn2 = (ImageButton) findViewById(R.id.imageButton2);
btn2.setOnClickListener(this);
final Button buttonchoose = (Button) findViewById(R.id.buttonchoose);
buttonchoose.setOnClickListener(this);
final RelativeLayout ViewX = (RelativeLayout) findViewById(R.id.RLXV);
ViewTreeObserver vto = ViewX.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
ViewX.getViewTreeObserver().removeOnGlobalLayoutListener(this);
Intent intent7 = getIntent();
String bitmapXY = (String) intent7.getExtras().get("BitmapImage");
GraphRequest request = GraphRequest.newGraphPathRequest(
AccessToken.getCurrentAccessToken(),
"/" + bitmapXY,
new GraphRequest.Callback() {
#Override
public void onCompleted(GraphResponse response) {
HttpURLConnection connection = null;
try {
int ViewWidth = ViewX.getMeasuredWidth();
JSONObject photos = response.getJSONObject();
JSONArray linkY = photos.optJSONArray("images");
final JSONObject linkO = linkY.optJSONObject(0);
final String link2 = linkO.optString("source");
URL LINKF = new URL(link2);
connection = (HttpURLConnection) LINKF.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(input);
float HH = (float) bitmap.getHeight();
float WW = (float) bitmap.getWidth();
float ViewWidthX = (float) ViewWidth;
float height = (HH / WW) * ViewWidthX;
Bitmap bitmapF = Bitmap.createScaledBitmap(bitmap, ViewWidth, Math.round(height), false);
//Remove from here and declare this in onCreate() and don't make it final
//final ImageView image1 = (ImageView) findViewById(R.id.image1);
image1.setImageBitmap(bitmapF);
undos.add(bitmapF);
image1.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Display d = getWindowManager().getDefaultDisplay();
float dw = d.getWidth();
float dh = d.getHeight();
float x = event.getX();
float y = event.getY();
float r = 2;
Bitmap BTX = ((BitmapDrawable)image1.getDrawable()).getBitmap();
Canvas canvas = new Canvas(BTX);
canvas.drawBitmap(BTX,0,0,null);
Paint paint1 = new Paint();
int bg1 = buttonchoose.getDrawingCacheBackgroundColor();
ColorDrawable buttonColor = (ColorDrawable) buttonchoose.getBackground();
int bg2 =buttonColor.getColor();
paint1.setColor(bg2);
paint1.setShadowLayer(5, 2, 2, bg2);
paint1.setStrokeWidth(20);
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
DownY = event.getY();
DownX = event.getX();
break;
case MotionEvent.ACTION_MOVE:
MoveY = event.getY();
MoveX = event.getX();
canvas.drawLine(DownX, DownY, MoveX, MoveY, paint1);
image1.invalidate();
DownX = MoveX;
DownY=MoveY;
break;
case MotionEvent.ACTION_UP:
UpY = event.getY();
UpX = event.getX();
canvas.drawLine(DownX, DownY, UpX, UpY, paint1);
image1.invalidate();
Bitmap BTXYZ = ((BitmapDrawable)image1.getDrawable()).getBitmap();
break;
}
return true;
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "images");
request.setParameters(parameters);
request.executeAsync();
}
});
}
#Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.buttonchoose:
final ColorPicker cp = new ColorPicker(edit.this, 0, 0, 0);
/* Show color picker dialog */
cp.show();
/* On Click listener for the dialog, when the user select the color */
Button okColor = (Button) cp.findViewById(R.id.okColorButton);
okColor.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
/* You can get single channel (value 0-255) */
int selectedColorR = cp.getRed();
int selectedColorG = cp.getGreen();
int selectedColorB = cp.getBlue();
/* Or the android RGB Color (see the android Color class reference) */
int selectedColorRGB = cp.getColor();
Button buttonchoose = (Button) findViewById(R.id.buttonchoose);
buttonchoose.setText("");
buttonchoose.setBackgroundColor(selectedColorRGB);
cp.dismiss();
}
});
break;
case R.id.imageButton2:
int newImage = undos.size();
Log.e("Lenght of Array",""+newImage);
if(newImage >=1) {
Bitmap newImage2 = undos.get(newImage-2);
//Don't take reference again here
//ImageView IMGXV = (ImageView) findViewById(R.id.image1);
image1.setImageBitmap(newImage2);
undos.remove(newImage-1);
}
break;
}
}
}

how to use Double Tap event in android canvas to save current Image

I have Class which Extends View I'm able To Move one Image Over another For This I use Two Bitmap Image one Over Another now i want to save image's using Double Tap event but i dnt know how to do this....can anyone have some idea or code for this ......
`public class ShowCanvas extends View {
Bitmap CanvasBitmap;
Bitmap ScaledBitmap;
Bitmap smallbitmap;
private static final int INVALID_POINTER_ID = -1;
private Drawable mImage;
private float mPosX;
private float mPosY;
private float mLastTouchX;
private float mLastTouchY;
private int mActivePointerId = INVALID_POINTER_ID;
private ScaleGestureDetector mScaleDetector;
private float mScaleFactor = 1.f;
public ShowCanvas(Context context) {
this(context, null, 0);
// TODO Auto-generated constructor stub
ScaledBitmap = DrawView.scaled;
mImage = new BitmapDrawable(getResources(), Dress.bitmap);
System.out.println("MImage" +mImage);
mImage.setBounds(0, 0, mImage.getIntrinsicWidth(),
mImage.getIntrinsicHeight());
}
public ShowCanvas(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ShowCanvas(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
}
public void setBitmap(Bitmap bitmap) {
// TODO Auto-generated method stub
CanvasBitmap = bitmap;
System.out.println("CanvasBitmap" + CanvasBitmap);
int X = CanvasBitmap.getHeight();
int Y = CanvasBitmap.getWidth();
System.out.println("CanvasBitmap " + X + "\t" + Y);
}
#Override
public boolean isLongClickable() {
// TODO Auto-generated method stub
System.out.println("ISLongClickable");
return super.isLongClickable();
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
// Let the ScaleGestureDetector inspect all events.
mScaleDetector.onTouchEvent(ev);
final int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
final float x = ev.getX();
final float y = ev.getY();
mLastTouchX = x;
mLastTouchY = y;
mActivePointerId = ev.getPointerId(0);
break;
}
case MotionEvent.ACTION_MOVE: {
final int pointerIndex = ev.findPointerIndex(mActivePointerId);
final float x = ev.getX(pointerIndex);
final float y = ev.getY(pointerIndex);
// Only move if the ScaleGestureDetector isn't processing a
// gesture.
if (!mScaleDetector.isInProgress()) {
final float dx = x - mLastTouchX;
final float dy = y - mLastTouchY;
mPosX += dx;
mPosY += dy;
invalidate();
}
mLastTouchX = x;
mLastTouchY = y;
break;
}
case MotionEvent.ACTION_UP: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_CANCEL: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_POINTER_UP: {
final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
final int pointerId = ev.getPointerId(pointerIndex);
if (pointerId == mActivePointerId) {
// This was our active pointer going up. Choose a new
// active pointer and adjust accordingly.
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mLastTouchX = ev.getX(newPointerIndex);
mLastTouchY = ev.getY(newPointerIndex);
mActivePointerId = ev.getPointerId(newPointerIndex);
}
break;
}
}
return true;
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
Paint mpaint = new Paint();
canvas.save();
canvas.drawBitmap(ScaledBitmap, 0, 0, mpaint);
Log.d("DEBUG", "X: " + mPosX + " Y: " + mPosY);
canvas.translate(mPosX, mPosY);
canvas.scale(mScaleFactor, mScaleFactor);
mImage.draw(canvas);
canvas.restore();
}
private class ScaleListener extends
ScaleGestureDetector.SimpleOnScaleGestureListener {
#Override
public boolean onScale(ScaleGestureDetector detector) {
mScaleFactor *= detector.getScaleFactor();
// Don't let the object get too small or too large.
mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 10.0f));
invalidate();
return true;
}
}
}`
If you mean double tap you have to use GestureDetector.OnDoubleTapListener. check this link
try this
public class MyView extends View {
GestureDetector gestureDetector;
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
// creating new gesture detector
gestureDetector = new GestureDetector(context, new GestureListener());
}
// skipping measure calculation and drawing
// delegate the event to the gesture detector
#Override
public boolean onTouchEvent(MotionEvent e) {
return gestureDetector.onTouchEvent(e);
}
private class GestureListener extends GestureDetector.SimpleOnGestureListener {
#Override
public boolean onDown(MotionEvent e) {
return true;
}
// event when double tap occurs
#Override
public boolean onDoubleTap(MotionEvent e) {
float x = e.getX();
float y = e.getY();
Log.d("Double Tap", "Tapped at: (" + x + "," + y + ")");
return true;
}
}
}

Categories