Android simple game. ImageButton not clicking. Bitmap - java

I have created a custom ImageButton that will be used to change direction of objects in a simple game. The button is not responding when I click/touch it.
I have tried setOnTouchListener and setOnClickListener but nothing happens.
CustomButton:
public class CustomButton extends ImageButton {
private Bitmap bitmap;
public CustomButton(Context context, int resource) {
super(context);
setClickable(true);
bitmap = BitmapFactory.decodeResource(context.getResources(), resource);
}
public Bitmap getBitmap() {
return bitmap;
}
GameView:
public class GameView extends SurfaceView implements Runnable {
volatile boolean playing;
private Thread gameThread = null;
private CustomButton mLeftButton;
private Player player;
private Paint paint;
private Canvas canvas;
private Bitmap bitmap;
private SurfaceHolder surfaceHolder;
public GameView(Context context, int screenX, int screenY) {
super(context);
mLeftButton = new CustomButton(context, R.drawable.boom);
mLeftButton.setImageBitmap(mLeftButton.getBitmap());
mLeftButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getContext(),"It worked",Toast.LENGTH_LONG).show();
}
});
player = new Player(context, screenX, screenY);
surfaceHolder = getHolder();
paint = new Paint();
}
#Override
public void run() {
while (playing) {
update();
draw();
control();
}
}
private void update() {
player.update();
}
private void draw() {
if (surfaceHolder.getSurface().isValid()) {
canvas = surfaceHolder.lockCanvas();
canvas.drawColor(Color.BLACK);
canvas.drawBitmap(player.getBitmap(), player.getX(), player.getY(), paint);
canvas.drawBitmap(mLeftButton.getBitmap(), 20, 20, paint);
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}

You create your button but not link it to the current layout.
In the draw method you simply draw it's image without adding its functionality to the SurfaceView, that way your button functionality is not used.
I'd suggest to create your base xml layout in a way where the button is over your surfaceview (with a RelativeLayout or a FrameLayout e.g.), then where you setup your Activity you'd setup up the onclicklistener for the button and wire it to the containing view.

Related

How to convert a canvas drawing to an image then Drag it around screen?

I'm trying to draw on a canvas then onClick change it to bitmap image then I would like to make it draggable. I can draw on canvas successfully
but how do I convert this drawing to an image then make it draggable? I don't mind If it's possible to drag the drawing without converting to an image. Can someone please help.
public class MainActivity extends AppCompatActivity implements ColorPickerDialog.OnColorChangedListener {
protected DrawView canvasView;
private ImageButton blackCircle;
private Button pens,select;
private Paint mPaint;
Bitmap viewCapture = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPaint = new Paint();
canvasView = (DrawView) findViewById(R.id.canvas_view);//The drawing mechanism
colorChanged(mPaint.getColor());
blackCircle = (ImageButton) findViewById(R.id.black_circle);
blackCircle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
canvasView.setPathColor(Color.BLACK));
blackCircle.setPressed(true);
}
});
select = (Button) findViewById(R.id.ic_select);
select.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
canvasView.setVisibility(View.VISIBLE);
canvasView.setPathColor(0);
//Drag the drawn image
setContentView(R.layout.activity_main);
relativeLayout = (RelativeLayout) findViewById(R.id.main);
drawingView = new DrawingView(MainActivity.this);
relativeLayout.addView(drawingView);
//Create a bitmap image of current drawing
canvasView.setDrawingCacheEnabled(true);
viewCapture = Bitmap.createBitmap(canvasView.getDrawingCache());
canvasView.setDrawingCacheEnabled(false);
}
});
}// End of Create();
private void clearCanvas(View v) {
canvasView.clear();
}
#Override
public void colorChanged(int color) {
mPaint.setColor(color);
canvasView.setPathColor(mPaint.getColor());
}
/************** OnTouch ***************/
class DrawingView extends View{
float x,y;
public DrawingView(Context context){
super(context);
viewCapture = BitmapFactory.decodeResource(context.getResources(), R.id.main);
}
public boolean onTouchEvent(MotionEvent event){
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
x =(int)event.getX();
y =(int)event.getY();
invalidate();
break;
case MotionEvent.ACTION_UP:
x =(int)event.getX();
y =(int)event.getY();
invalidate();
break;
}
return true;
}
#Override
public void onDraw(Canvas canvas) {
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.CYAN);
canvas.drawBitmap(viewCapture, x, y, paint);
}
}
}//End of Class
public class DrawView extends View {
private Paint drawPaint, canvasPaint;
private Canvas drawCanvas;
private Bitmap canvasBitmap;
private SparseArray<Path> paths;
public DrawView(Context context) {
super(context);
setupDrawing();
}
public DrawView(Context context, AttributeSet attrs) {
super(context, attrs);
setupDrawing();
}
public DrawView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setupDrawing();
}
private void setupDrawing() {
paths = new SparseArray<>();
drawPaint = new Paint();
drawPaint.setColor(Color.BLACK);
drawPaint.setAntiAlias(true);
drawPaint.setStrokeWidth(9);
drawPaint.setStyle(Paint.Style.STROKE);
drawPaint.setStrokeJoin(Paint.Join.ROUND);
drawPaint.setStrokeCap(Paint.Cap.ROUND);
canvasPaint = new Paint(Paint.DITHER_FLAG);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
drawCanvas = new Canvas(canvasBitmap);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
for (int i=0; i<paths.size(); i++) {
canvas.drawPath(paths.valueAt(i), drawPaint);
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
int index = event.getActionIndex();
int id = event.getPointerId(index);
Path path;
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
path = new Path();
path.moveTo(event.getX(index), event.getY(index));
paths.put(id, path);
break;
case MotionEvent.ACTION_MOVE:
for (int i=0; i<event.getPointerCount(); i++) {
id = event.getPointerId(i);
path = paths.get(id);
if (path != null) path.lineTo(event.getX(i), event.getY(i));
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
path = paths.get(id);
if (path != null) {
drawCanvas.drawPath(path, drawPaint);
paths.remove(id);
}
break;
default:
return false;
}
invalidate();
return true;
}
public void setPathColor(int color) {
drawPaint.setColor(color);
}
public void clear() {
canvasBitmap.eraseColor(Color.TRANSPARENT);
paths.clear();
invalidate();
System.gc();
}
}
For the next steps I assume you'd like to let the users drag the picture which they just created with the DrawView. So I'd introduce another View which can display the bitmap and set its position and dimensions exactly like those of the DrawView. (The best way to achieve this depends on the type of ViewGroup you are using)
Create a bitmap from the canvas as shown in converting a canvas into bitmap image in android
Set the bitmap as the new View's background with setBackground(Drawable), toggle the visibility of both Views as needed.
To make the new View draggable, use a View.OnTouchListener and change the position according to the MotionEvents
Another option: just drag the DrawView by using a flag to indicate whether the users can drag it or draw on it. You override onTouchEvent() already, now check the flag first and if it is set to "drag" then evaluate the delta between two MOVEs and adjust the position accordingly.

Camera API. Not saving image [duplicate]

I'm creating camera app. I'm doing that in fragment. I have FrameLayout where I add the camera, and one button for capture. There are 2 problems.
Camera not saves the image.
When I click second time on capture image, drops exception java.lang.RuntimeException: takePicture failed
I don't know where's the problem, I'm using camera API first time.
Camera I'm using only in portrait mode. And in manifests I added the permissions for camera and write external storage.
I have one class where I'm extending SurfaceView. Let me show you the code.
public class ShowCamera extends SurfaceView implements SurfaceHolder.Callback{
Camera camera;
SurfaceHolder holder;
public ShowCamera(Context context, Camera camera) {
super(context);
this.camera = camera;
holder = getHolder();
holder.addCallback(this);
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
Camera.Parameters params = camera.getParameters();
List<Camera.Size> sizes = params.getSupportedPictureSizes();
Camera.Size mSize = null;
for (Camera.Size size : sizes){
mSize = size;
}
camera.setDisplayOrientation(90);
params.setRotation(90);
params.setPictureSize(mSize.width, mSize.height);
camera.setParameters(params);
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
camera.stopPreview();
camera.release();
}
}
Ok and here's the fragment for camera.
public class CameraActivity extends BaseFragment{
View mainView;
FrameLayout cameraLayout;
Camera camera;
ShowCamera showCamera;
ImageButton captureImage;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mainView = inflater.inflate(R.layout.camera_fragment, container, false);
cameraLayout = (FrameLayout) mainView.findViewById(R.id.cameraContainer);
captureImage = (ImageButton) mainView.findViewById(R.id.imageButton);
camera = Camera.open();
showCamera = new ShowCamera(getActivity(), camera);
cameraLayout.addView(showCamera);
capture();
return mainView;
}
Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] bytes, Camera camera) {
if(bytes != null){
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
if(bitmap != null){
File file = new File(String.valueOf(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)));
if(!file.isDirectory()){
file.mkdir();
}
file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM),
System.currentTimeMillis() + ".jpg");
try {
FileOutputStream fileOutputStream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
} catch (Exception e){
e.printStackTrace();
}
}
}
}
};
public void capture(){
captureImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(camera != null){
camera.takePicture(null, null, mPictureCallback);
}
}
});
}
}

Cannot draw a circle with loading of the fragment

I am trying to draw circles in the canvas. Currently I can do it on button click, but I also need to do the same when the Fragment is loaded. Below is my Fragment code.
public class StepTwentyOneFragment extends Fragment {
private CanvasView customCanvas;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.step21_fragment, container, false);
customCanvas=(CanvasView)v.findViewById(R.id.signature_canvas);
final Button button1=(Button)v.findViewById(R.id.step18button1);
float radius=(customCanvas.getCanvasWidth()/2) - ((customCanvas.getCanvasWidth()/2)/100)*60;
customCanvas.drawCircle(radius);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(v.getId()==R.id.step18button1){
float radius=(customCanvas.getCanvasWidth()/2) - ((customCanvas.getCanvasWidth()/2)/100)*60;
customCanvas.drawCircle(radius);
Log.d("An_Width", "" + customCanvas.getCanvasWidth());
Log.d("An_Height" ,""+ customCanvas.getCanvasHeight());
v.setBackgroundResource(R.drawable.button_border_5);
button1.setTextColor(Color.WHITE);;
}
}
});
return v;
}
public static StepTwentyOneFragment newInstance() {
StepTwentyOneFragment f = new StepTwentyOneFragment();
Bundle b = new Bundle();
f.setArguments(b);
return f;
}
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if(isVisibleToUser) {
Activity a = getActivity();
if(a != null) a.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
}
Below is my Canvas code
public class CanvasView extends View {
public int width;
public int height;
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
Context context;
private Paint mPaint;
private float mX, mY;
private static final float TOLERANCE = 5;
private int canvasHeight, canvasWidth;
private float radius;
public CanvasView(Context c, AttributeSet attrs) {
super(c, attrs);
context = c;
mPath = new Path();
mPaint = new Paint();
mPaint.setStrokeWidth(3);
mPaint.setColor(Color.CYAN);
}
// override onDraw
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mCanvas=canvas;
Drawable d = getResources().getDrawable(R.drawable.circle_1);
canvasHeight= canvas.getHeight();
canvasWidth= canvas.getWidth();
Log.d("Height - "," / "+canvas.getHeight());
Log.d("Width - "," / "+canvas.getWidth());
// DisplayMetrics displaymetrics = new DisplayMetrics();
// ((Activity)context).getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
// int height = displaymetrics.heightPixels;
// int width = displaymetrics.widthPixels;
float h=canvasHeight/2;
float w=canvasWidth/2;
d.setBounds(0, 0, canvasWidth, canvasHeight);
d.draw(canvas);
canvas.drawCircle(w, h, radius, mPaint);
}
public void clear2(){
radius=0;
//important. Refreshes the view by calling onDraw function
invalidate();
}
public void drawCircle(float radius1) {
radius=radius1;
//important. Refreshes the view by calling onDraw function
invalidate();
}
public int getCanvasHeight()
{
return canvasHeight;
}
public int getCanvasWidth()
{
return canvasWidth;
}
}
Now my problem is , cannot draw a circle with loading of the fragment . It means the circle cannot draw without button action . But I want to do it when the fragment is loading .
Have any ideas ?
Thank you.

android how do I update the view to include a custom graphic?

I found this really useful code that allows me to scale and move a bitmap and I've been trying to find a way to use this code in my app. I don't really understand the way the class is being used (self taught java coder, so I may be missing some basics here). I basically want to be able to open up gallery and pick a file which can be used by this code. I can do all this with a standard ImageView but with an ImageView I'm unable to scale/move.
The main class, and it simply uses the touchexampleview class to place the image on screen, and the touchexampleview class contains a line which loads a default image.
mIcon = context.getResources().getDrawable(R.drawable.ic_launcher);
I could work out how to change this in the class but I want to be able to do this dynamically and be user driven.
Here is the main class.
public class TouchExampleActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TouchExampleView view = new TouchExampleView(this);
view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
setContentView(view);
}
}
and the touchexampleview class
public class TouchExampleView extends View {
private Drawable mIcon;
private float mPosX;
private float mPosY;
private VersionedGestureDetector mDetector;
private float mScaleFactor = 1.f;
public TouchExampleView(Context context) {
this(context, null, 0);
}
public TouchExampleView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public TouchExampleView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mIcon = context.getResources().getDrawable(R.drawable.ic_launcher);
mIcon.setBounds(0, 0, mIcon.getIntrinsicWidth(), mIcon.getIntrinsicHeight());
mDetector = VersionedGestureDetector.newInstance(context, new GestureCallback());
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
mDetector.onTouchEvent(ev);
return true;
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
canvas.translate(mPosX, mPosY);
canvas.scale(mScaleFactor, mScaleFactor);
mIcon.draw(canvas);
canvas.restore();
}
private class GestureCallback implements VersionedGestureDetector.OnGestureListener {
public void onDrag(float dx, float dy) {
mPosX += dx;
mPosY += dy;
invalidate();
}
public void onScale(float scaleFactor) {
mScaleFactor *= scaleFactor;
// Don't let the object get too small or too large.
mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 5.0f));
invalidate();
}
}
}
I am not sure, but is this what you are looking for?
imageSpot.setImageResource(R.drawable.myImage);

Can't assign type

I hame class GameManager(),
int class variable:
public GameView view;
it's class constructor:
public GameManager (GameView view)
{
this.view = view;
}
in the class GameView I create :
private GameManager gameLoopThread;
....
public GameView(Context context) {
super(context);
gameLoopThread = new GameView(this);// HERE IS ERROR ;
I dont know why it want to change gameLoopThread to GameView() type.
gameLoopThread = new GameManager(this);

Categories