I am trying to clip a path in my custom view but it appears black in color. Through searching and finding the reason for same. Found that I need to set " setLayerType(LAYER_TYPE_SOFTWARE,null)". After this it appears perfect but crashes in some deivices.
Crash Log(One of these based on devices):
java.lang.NegativeArraySizeException
Bitmap exceeds 32bit
public class CardLayout extends LinearLayout {
private View mRoot;
private ImageView mCategoryImageView;
private LinearLayout mCategoryBottomView;
private RectF mRect;
private Paint mPaint;
private View mDivider;
private Path mPath;
private int mPadding = 30;
public CardLayout(Context context) {
super(context);
}
public CardLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public CardLayout(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
mRoot = LayoutInflater.from(getContext()).inflate(R.layout.card_content, null);
addView(mRoot);
initUI();
}
private void initUI() {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
mPath = new Path();
mCategoryHeadlineTextView = (TextView) mRoot.findViewById(R.id.categoryHeadline);
mCategoryImageView = (ImageView) mRoot.findViewById(R.id.categoryImageView);
mCategoryBottomView = (LinearLayout) mRoot.findViewById(R.id.ctg_btm_view);
mDivider = mRoot.findViewById(R.id.divider);
setLayerType(LAYER_TYPE_SOFTWARE,null);
}
public void setCategoryImage(String categoryUrl) {
if (mCategoryImageView != null) {
Glide.with(mContext)
.load(categoryUrl)
.placeholder(R.drawable.two)
.into(mCategoryImageView);
}
}
public void setBottomView(String[] optionText, int[] optionResource, int tag) {
if (mCategoryBottomView != null) {
CategoryBottomOptions options = new CategoryBottomOptions(mContext, optionText, optionResource, tag, mCategoryBottomView);
}
}
#Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
mRect = new RectF(mDivider.getX() - mPadding, mDivider.getY() - mPadding, mDivider.getX() + mPadding, mDivider.getY() + mPadding);
mPath.addArc(mRect, 270, 180);
canvas.clipPath(mPath);
canvas.drawPath(mPath, mPaint);
mRect = new RectF(mDivider.getWidth() - mPadding, mDivider.getY() - mPadding, mDivider.getWidth() + mPadding, mDivider.getY() + mPadding);
mPath = new Path();
mPath.addArc(mRect, 90, 180);
canvas.clipPath(mPath);
canvas.drawPath(mPath, mPaint);
}
}
You Should do something like this to create a window withing a view.
public class ClippedImageView extends ImageView {
private Paint mPaint;
private Path mPath;
public ClippedImageView(Context context) {
this(context, null);
init();
}
public v(Context context, AttributeSet attrs) {
this(context, attrs, 0);
init();
}
public ClippedImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
mPath = new Path();
RectF rect = new RectF(0, 0, 100, 100);
mPath.addArc(rect, 270, 180);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.clipPath(mPath, Region.Op.DIFFERENCE);
super.onDraw(canvas);
}
}
Related
I am using below custom class for make text outline in my quotes application. Its working fine till device with android 9. In android 10 device, its not giving me any error as well not working.
My custom class for draw outline is like below
public class OutlineTextView extends androidx.appcompat.widget.AppCompatTextView {
private Field colorField;
private int textColor;
private int outlineColor;
public OutlineTextView(Context context) {
this(context, null);
}
public OutlineTextView(Context context, AttributeSet attrs) {
this(context, attrs, android.R.attr.textViewStyle);
}
public OutlineTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
try {
colorField = TextView.class.getDeclaredField("mCurTextColor");
colorField.setAccessible(true);
textColor = getTextColors().getDefaultColor();
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.OutlineTextView);
outlineColor = a.getColor(R.styleable.OutlineTextView_outlineColor, Color.TRANSPARENT);
setOutlineStrokeWidth(a.getDimensionPixelSize(R.styleable.OutlineTextView_outlineWidth, 0));
a.recycle();
}
catch (NoSuchFieldException e) {
e.printStackTrace();
colorField = null;
}
}
#Override
public void setTextColor(int color) {
textColor = color;
super.setTextColor(color);
}
public void setOutlineColor(int color) {
invalidate();
outlineColor = color;
}
public void setOutlineWidth(float width) {
invalidate();
setOutlineStrokeWidth(width);
}
private void setOutlineStrokeWidth(float width) {
invalidate();
getPaint().setStrokeWidth(2 * width + 1);
}
#Override
protected void onDraw(Canvas canvas) {
if (colorField != null) {
// Outline
setColorField(outlineColor);
getPaint().setStyle(Paint.Style.STROKE);
super.onDraw(canvas);
// Reset for text
setColorField(textColor);
getPaint().setStyle(Paint.Style.FILL);
}
super.onDraw(canvas);
}
private void setColorField(int color) {
// We did the null check in onDraw()
try {
colorField.setInt(this, color);
}
catch (IllegalAccessException | IllegalArgumentException e) {
// Optionally catch Exception and remove print after testing
e.printStackTrace();
}
}
}
I am calling it from my RecyclerView like this
CardMainActivity.text_quotes.setOutlineColor(Color.parseColor(CardConstant.getcolorcodearray().get(getAdapterPosition())));
My gradle build information is like below
compileSdkVersion 29
buildToolsVersion "29.0.2"
Let me know if someone can help me. Thanks!
My custom view (which is a button) seems to be reinitialized when I change tab and come back to the one where my custom view is.
Before changing tab (when I launch the app):
After changing:
Find below the code of my custom view (without custom public methods):
public class ButtonView extends RelativeLayout {
private RelativeLayout mRelativeContainer;
private TextView mTextViewButton;
private ImageView mImageViewArrow;
private DiagonalLayout mDiagonalLayout;
private RelativeLayout mRelativeLayoutDiagonalColor;
private int mDirection;
private String mText;
private float mTextSize;
private int mTextColor;
private int mButtonColor;
private int mObliqueColor;
public ButtonView(Context context) {
super(context);
customLabel(context, null);
init(context);
}
public ButtonView(Context context, AttributeSet attrs) {
super(context, attrs);
customLabel(context, attrs);
init(context);
}
public ButtonView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
customLabel(context, attrs);
init(context);
}
private void init(Context context) {
switch (mDirection) {
case DIRECTION_RIGHT:
inflate(context, R.layout.button_view_right, this);
break;
case DIRECTION_LEFT:
inflate(context, R.layout.button_view_left, this);
break;
}
mRelativeContainer = findViewById(R.id.container);
mTextViewButton = findViewById(R.id.text);
mImageViewArrow = findViewById(R.id.arrow);
mDiagonalLayout = findViewById(R.id.diagonal);
mRelativeLayoutDiagonalColor = findViewById(R.id.diagonal_color);
mRelativeContainer.setBackgroundResource(R.drawable.bg_button_view);
setText(mText);
setTextSize(mTextSize);
setTextColor(mTextColor);
setButtonColor(mButtonColor);
setObliqueColor(mObliqueColor);
}
private void customLabel(Context context, AttributeSet attrs) {
TypedArray typedArray = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.ButtonView,
0, 0);
try {
mDirection = typedArray.getInt(R.styleable.ButtonView_direction, DIRECTION_RIGHT);
mText = typedArray.getString(R.styleable.ButtonView_text);
mTextSize = typedArray.getDimensionPixelSize(R.styleable.ButtonView_text_size, 52);
mTextColor = typedArray.getColor(R.styleable.ButtonView_text_color, getResources().getColor(android.R.color.white));
mButtonColor = typedArray.getColor(R.styleable.ButtonView_button_color, getResources().getColor(R.color.blue));
mObliqueColor = typedArray.getColor(R.styleable.ButtonView_oblique_color, getResources().getColor(R.color.dark_blue));
} finally {
typedArray.recycle();
}
}
private int getPercent(int i, int percent) {
return i * percent / 100;
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int marginTopBottom = getPercent(mTextViewButton.getMeasuredHeight(), 50);
int marginStartEnd = getPercent(mTextViewButton.getMeasuredHeight(), 70);
LinearLayout.LayoutParams textViewButtonParams = (LinearLayout.LayoutParams) mTextViewButton.getLayoutParams();
textViewButtonParams.setMargins(
marginStartEnd, marginTopBottom,
marginStartEnd, marginTopBottom);
mTextViewButton.setLayoutParams(textViewButtonParams);
/***************************************************************/
((LinearLayout.LayoutParams) mImageViewArrow.getLayoutParams()).width = getPercent(mTextViewButton.getMeasuredHeight(), 60);
((LinearLayout.LayoutParams) mImageViewArrow.getLayoutParams()).height = getPercent(mTextViewButton.getMeasuredHeight(), 60);
switch (mDirection) {
case DIRECTION_RIGHT:
((LinearLayout.LayoutParams) mImageViewArrow.getLayoutParams()).setMargins(0, 0, marginStartEnd, 0);
mDiagonalLayout.getLayoutParams().width = getMeasuredWidth();
mDiagonalLayout.getLayoutParams().height = getPercent(mTextViewButton.getMeasuredHeight(), 35);
((RelativeLayout.LayoutParams) mDiagonalLayout.getLayoutParams()).setMargins(
0,
marginTopBottom * 2 + mTextViewButton.getMeasuredHeight() - mDiagonalLayout.getLayoutParams().height,
0,
0);
break;
case DIRECTION_LEFT:
((LinearLayout.LayoutParams) mImageViewArrow.getLayoutParams()).setMargins(marginStartEnd, 0, 0, 0);
mDiagonalLayout.getLayoutParams().width = getPercent(mTextViewButton.getMeasuredHeight(), 60) * 4;
mDiagonalLayout.getLayoutParams().height = getPercent(mTextViewButton.getMeasuredHeight(), 35);
((RelativeLayout.LayoutParams) mDiagonalLayout.getLayoutParams()).setMargins(
0,
marginTopBottom * 2 + mTextViewButton.getMeasuredHeight() - mDiagonalLayout.getLayoutParams().height,
0,
0);
break;
}
}
}
I have no idea of what happens and I didn't find any proper answers so far.
After creating a digram using Java, 3 areas get highlighted and return a warning for some reason. I'm not sure why this is appearing. What can be done to get rid of this warning?
Avoid object allocations during draw/layout operations (preallocate and reuse instead)
public class Diagram extends View {
private int measuredWidth, measuredHeight;
private Paint mBackgroundPaint, mYellowLinePaint, mWhiteLinePaint;
private RectF mBackgroundRect, mYellowLineRectF, mWhiteLineRectF;
public Diagram(Context context) {
super(context);
init(context, null, 0);
}
public Diagram(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
}
public Diagram(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
}
private void init(Context context, AttributeSet attributeSet, int defStyle) {
mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBackgroundPaint.setColor(0xFF3C3C3C);
mBackgroundPaint.setStyle(Paint.Style.FILL);
mYellowLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mYellowLinePaint.setColor(0xFFFFFF00);
mYellowLinePaint.setStyle(Paint.Style.FILL);
mWhiteLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mWhiteLinePaint.setColor(0xFFFFFFFF);
mWhiteLinePaint.setStyle(Paint.Style.FILL);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
measuredHeight = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
measuredWidth = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
mBackgroundRect = new RectF(0, 0, measuredWidth, measuredHeight);
mYellowLineRectF = new RectF(0, 0.2f * measuredHeight, measuredWidth, 0.3f * measuredHeight);
mWhiteLineRectF = new RectF(0, 0.0f * measuredHeight, measuredWidth, 0.1f * measuredHeight);
setMeasuredDimension(measuredWidth, measuredHeight);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (measuredHeight == 0 || measuredWidth == 0)
return;
canvas.drawRect(mBackgroundRect, mBackgroundPaint);
canvas.drawRect(mYellowLineRectF, mYellowLinePaint);
canvas.drawRect(mWhiteLineRectF, mWhiteLinePaint);
}
}
Updated code
public class Diagram extends View {
private int measuredWidth, measuredHeight;
private Paint mBackgroundPaint, mYellowLinePaint, mWhiteLinePaint;
private final RectF mBackgroundRect = new RectF();
private final RectF mYellowLineRectF = new RectF();
private final RectF mWhiteLineRectF = new RectF();
public Diagram(Context context) {
super(context);
init(context, null, 0);
}
public Diagram(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
}
public Diagram(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
}
private void init(Context context, AttributeSet attributeSet, int defStyle) {
mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBackgroundPaint.setColor(0xFF3C3C3C);
mBackgroundPaint.setStyle(Paint.Style.FILL);
mYellowLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mYellowLinePaint.setColor(0xFFFFFF00);
mYellowLinePaint.setStyle(Paint.Style.FILL);
mWhiteLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mWhiteLinePaint.setColor(0xFFFFFFFF);
mWhiteLinePaint.setStyle(Paint.Style.FILL);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
measuredHeight = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
measuredWidth = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
mBackgroundRect.set(0, 0, measuredWidth, measuredHeight);
mYellowLineRectF.set(0, 0.2f * measuredHeight, measuredWidth, 0.3f * measuredHeight);
mWhiteLineRectF.set(0, 0.0f * measuredHeight, measuredWidth, 0.1f * measuredHeight);
setMeasuredDimension(measuredWidth, measuredHeight);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (measuredHeight == 0 || measuredWidth == 0)
return;
canvas.drawRect(mBackgroundRect, mBackgroundPaint);
canvas.drawRect(mYellowLineRectF, mYellowLinePaint);
canvas.drawRect(mWhiteLineRectF, mWhiteLinePaint);
}
}
Create your 3 RectF instances once in the class constructor or field initializer instead, then use RectF.set() in onMeasure().
public class Diagram extends View {
private final RectF mBackgroundRect = new RectF();
private final RectF mYellowLineRectF = new RectF();
private final RectF mWhiteLineRectF = new RectF();
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
measuredHeight = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
measuredWidth = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
mBackgroundRect.set(0, 0, measuredWidth, measuredHeight);
mYellowLineRectF.set(0, 0.2f * measuredHeight, measuredWidth, 0.3f * measuredHeight);
mWhiteLineRectF.set(0, 0.0f * measuredHeight, measuredWidth, 0.1f * measuredHeight);
setMeasuredDimension(measuredWidth, measuredHeight);
}
}
I find myself in need of assistance.
I'm trying to develop this simple app that takes pictures (Wow, now that's original!). Everything is fine. The only thing I need is to have a CIRCULAR CAMERA PREVIEW.
I have my camerapreview class (which extends surfaceview) placed inside a frame layout, which is my camera preview basically. As you all know, this comes in a rectangular shape. Since I have bigger plans for the app, I'd need the camera preview to be circular (so, for example, someone can take a picture of someone's face and I can have some drawings around...).
Now, I don't know how to proceed. I tried different things, creating a shape with xml and set it as background for my frame layout, but that just didn't work.
After hours spent on google for solutions I decided that I had to give up and come here.
So please, if someone knows anything, let us know :) I hope I was clear enough, do not hesitate to ask for clarification if needed.
Simple way:
1) not setup surface for priview
2) catch raw data
3) convert to bitmap and make circle
4) show (for ex. on imegeview)
just for sample:
public class CameraRoundPriview extends ImageView {
private Camera camera;
private Bitmap bitmap = null;
private int mPreviewWidth, mPreviewHeight;
boolean mCameraOn = false;
public CameraRoundPriview(Context context, AttributeSet attrs) {
super(context, attrs);
}
private Bitmap getclip() {
//clip
Bitmap output = Bitmap.createBitmap(bitmap.getHeight(),
bitmap.getHeight(),
Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getHeight(),
bitmap.getHeight());
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
canvas.drawCircle(bitmap.getHeight() / 2,
bitmap.getHeight() / 2,
bitmap.getHeight() / 2, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
//rotate
android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(getCameraID(), info);
int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0:
degrees = 0;
break;
case Surface.ROTATION_90:
degrees = 90;
break;
case Surface.ROTATION_180:
degrees = 180;
break;
case Surface.ROTATION_270:
degrees = 270;
break;
}
int result = degrees;
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP){
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
}
Matrix matrix = new Matrix();
matrix.postRotate(result);
Bitmap scaledBitmap = Bitmap.createScaledBitmap(output,output.getWidth(),output.getHeight(),true);
Bitmap rotatedBitmap = Bitmap.createBitmap(scaledBitmap , 0, 0, scaledBitmap.getWidth(), scaledBitmap .getHeight(), matrix, true);
return rotatedBitmap;
}
private void showImage(){
if ((bitmap != null)){
this.setImageBitmap(getclip());
}
}
public boolean onClickCamera(){
if (mCameraOn){
mCameraOn = false;
cameraStop();
}else{
mCameraOn = true;
cameraStart();
}
return mCameraOn;
}
private void cameraStop(){
if (camera == null) return;
camera.setPreviewCallback(null);
camera.release();
camera = null;
}
private int getCameraID(){
// specify camera id
return 0;
}
private void cameraStart(){
Camera camera = Camera.open(getCameraID());
final Camera.Size previewSize = camera.getParameters().getPreviewSize();
mPreviewWidth = previewSize.width;
mPreviewHeight = previewSize.height;
try {
camera.setPreviewCallback(new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera_call) {
ByteArrayOutputStream outstr = new ByteArrayOutputStream();
Rect rect = new Rect(0, 0, mPreviewWidth, mPreviewHeight);
YuvImage yuvimage=new YuvImage(data,ImageFormat.NV21,mPreviewWidth,mPreviewHeight,null);
yuvimage.compressToJpeg(rect, 50, outstr);
bitmap = BitmapFactory.decodeByteArray(outstr.toByteArray(), 0, outstr.size());
showImage();
camera_call.addCallbackBuffer(data);
}
});
} catch (Exception e) {}
camera.startPreview();
this.camera=camera;
}
}
You can overlay an ImageView over the camera preview. put both the SurfaceView and the ImageView within a FrameLayout both match_parent and the image must be on top.
Set to an black image with transparent circle in the middle.
this is as simple as shown below:
this is for camerax or camera2 API
Note: you must have background transparent.
you must have xml file like below.
<com.RoundedCameraPreview
android:id="#+id/viewFinder"
android:background="#00000000"
app:scaleType="fillCenter"
android:layout_width="match_parent"
android:layout_height="match_parent" />
also don't forget to declare in style.xml
<declare-styleable name="PreviewView">
<attr name="isRound" format="boolean" />
</declare-styleable>
and code is written like this
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.util.AttributeSet;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.camera.view.PreviewView;
public class RoundedCameraPreview extends PreviewView {
Path clipPath;
boolean isRound;
public RoundedCameraPreview(#NonNull Context context) {
super(context);
}
public RoundedCameraPreview(#NonNull Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
}
public RoundedCameraPreview(#NonNull Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.PreviewView,
0, 0);
try {
isRound = a.getBoolean(R.styleable.PreviewView_isRound, true);
} finally {
a.recycle();
}
}
public boolean isRound() {
return isRound;
}
public void setIsRound(boolean isRound) {
this.isRound = isRound;
invalidate();
requestLayout();
}
public RoundedCameraPreview(#NonNull Context context, #Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
#Override
protected void dispatchDraw(Canvas canvas) {
if (isRound) {
clipPath = new Path();
//TODO: define the circle you actually want
clipPath.addCircle(canvas.getWidth() / 2, canvas.getWidth() / 2, canvas.getWidth() / 2, Path.Direction.CW);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.clipPath(clipPath);
canvas.drawPath(clipPath, paint);
}
super.dispatchDraw(canvas);
}
}
Hi I drew a bitmap on the canvas and I wanted to do something when the user touches it.
Bitmap backbutton = BitmapFactory.decodeResource(getResources(),
R.drawable.backbutton);
Paint paint = new Paint();
canvas.drawBitmap(backbutton, canvasWidth - 100, 0, paint);
I have tried the following to solve the problem but it isnt working. How do I check for inbounds properly?
public void onTouch(View view, MotionEvent event) {
if(backbutton.contains((int) (event.getX()), (int)(event.getY()), (int)(event.getX()+100),(int) (event.getY()+30))) {
Toast.makeText(view.getContext(), "this works", Toast.LENGTH_LONG).show();
}
}
But I seem to be doing something wrong with the contains(). Can someone help me out here please?
First get the rect of the bitmap on the canvas. then in the onTouchEvent, check the touched x, y is contained in the rect before.
Added Example:
public class MyView extends View {
Rect bitmapRect;
public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas); //To change body of overridden methods use File | Settings | File Templates.
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher);
Rect source = new Rect(0,0,bitmap.getWidth(), bitmap.getHeight());
bitmapRect = new Rect(0,0, bitmap.getWidth(), bitmap.getHeight());
canvas.drawBitmap(bitmap, source, bitmapRect, new Paint());
}
#Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int)event.getX();
int y = (int)event.getY();
if(null != bitmapRect && bitmapRect.contains(x,y)){
Toast.makeText(view.getContext(), "this works", Toast.LENGTH_LONG).show();
}
return super.onTouchEvent(event); //To change body of overridden methods use File | Settings | File Templates.
}
}