onDraw not firing when created - android

My custom view's onDraw() is not being fired. Why? I am using 2.3.3. Shouldn't the view automatically draw when it gets created? The onMeasure() method is being fired and I get the correct screen width and height.
package com.example.assignment2b;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.Log;
import android.view.Display;
import android.view.Menu;
import android.view.View;
import android.view.WindowManager;
public class AcesActivity extends Activity {
private static final String TAG = "DEBUG";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
HeartView heartView = new HeartView(this);
setContentView(heartView);
heartView.invalidate();
}
class HeartView extends View {
private int screenWidth;
private int screenHeight;
private Context context;
public HeartView(Context context) {
super(context);
this.context = context;
}
#Override
public void onDraw(Canvas canvas) {
Log.println(Log.DEBUG, TAG, "onDraw fired");
int cardWidth = screenWidth - 10;
int cardHeight = (int) (cardWidth * 1.4);
canvas.drawColor(Color.DKGRAY);
Paint paint = new Paint();
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.FILL);
canvas.drawRect(5, (screenHeight/2) - (cardHeight/2), screenWidth - 5, (screenHeight/2) + (cardHeight/2), paint);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.STROKE);
canvas.drawRect(5, (screenHeight/2) - (cardHeight/2), screenWidth - 5, (screenHeight/2) + (cardHeight/2), paint);
}
#Override
public void onMeasure(int width, int height) {
Log.println(Log.DEBUG, TAG, "onMeasure fired");
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
screenWidth = display.getWidth();
screenHeight = display.getHeight();
setMeasuredDimension(screenWidth, screenHeight);
Log.println(Log.DEBUG, TAG, "screenWidth = " + screenWidth);
Log.println(Log.DEBUG, TAG, "scrrenHeight = " + screenHeight);
super.onMeasure(screenWidth, screenHeight);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
}

A few different issues going on. First as #dragonwrenn suggested, without a ViewGroup and layout params, your view has no intrinsic bounds. The call to invalidate() is unnecessary, but not problematic.
public class AcesActivity extends Activity {
private static final String TAG = "DEBUG";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RelativeLayout rl = new RelativeLayout(this);
RelativeLayout.LayoutParams params = new
RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
setContentView(rl);
HeartView heartView = new HeartView(this);
heartView.setLayoutParams(params);
rl.addView(heartView);
}
class HeartView extends View {
private int screenWidth;
private int screenHeight;
private Context context;
// Moved a couple of variable declarations out of the onDraw method
Paint paint;
int cardWidth;
int cardHeight;
public HeartView(Context context) {
super(context);
this.context = context;
paint = new Paint();
}
Second, your math for the rects drew them beyond the borders of the screen. I put in some hard numbers just as a test. You will want to rework your numbers to get what you really want. Also, your stroke had no width, so note
#Override
public void onDraw(Canvas canvas) {
Log.println(Log.DEBUG, TAG, "onDraw fired");
canvas.drawColor(Color.DKGRAY);
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.FILL);
canvas.drawRect(10, 10, 50, 50, paint);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(3);
canvas.drawRect(10, 10, 50, 50, paint);
}
Third, I'm not sure what everything in onMeasure was trying to achieve, but it was causing issues for the view. You shouldn't need more than what's below:
#Override
public void onMeasure(int width, int height) {
Log.println(Log.DEBUG, TAG, "onMeasure fired");
screenWidth = width;
screenHeight = height;
Log.println(Log.DEBUG, TAG, "screenWidth = " + screenWidth);
Log.println(Log.DEBUG, TAG, "scrrenHeight = " + screenHeight);
super.onMeasure(screenWidth, screenHeight);
cardWidth = screenWidth - 10;
cardHeight = (int) (cardWidth * 1.4);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
}
Edit: note to original poster, the above is functional code tested in Eclipse. If each section is copied and pasted exactly, it will work.

Do the below changes in your onMeasure() method:
Declare the display metrics in your class.
private DisplayMetrics m_metrics;
#Override
public void onMeasure(int width, int height) {
Log.println(Log.DEBUG, TAG, "onMeasure fired");
Display m_display = getWindowManager().getDefaultDisplay();
m_metrics = context.getResources().getDisplayMetrics();
m_display.getMetrics(m_metrics);
screenWidth = m_display.getWidth();
screenHeight = m_display.getHeight();
super.onMeasure(screenWidth, screenHeight);
}

Related

How do I properly add a custom view to an activity

I'm trying to build a custom view but for some reason it's not displaying at all.
To save you reading both constructors, I am calling the View constructor without the attr parameter because these should be fetched from the Layout file. Any values that are not fetched from here are set in the view class itself.
My view class:
package mrl233.campustour.AugmentedReality;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.hardware.SensorManager;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;
import org.w3c.dom.Text;
import java.util.ArrayList;
import java.util.List;
import mrl233.campustour.R;
/**
* TODO: document your custom view class.
*/
public class CameraOverlay extends View {
private float mAzimuth;
private float mPitch;
private float mRoll;
private String mTextString;
private int mTextColor = Color.RED;
private float mTextDimension = 80;
private Drawable mTextDrawable;
private float mTextSize = 29;
private TextPaint mTextPaint;
private float mTextHeight = 0;
private float mTextWidth;
public CameraOverlay(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.CameraOverlay,
0, 0);
try {
mTextString = a.getString(R.styleable.CameraOverlay_exampleString);
mAzimuth = a.getFloat(R.styleable.CameraOverlay_exampleFloat_X, 0);
mPitch = a.getFloat(R.styleable.CameraOverlay_exampleFloat_Y, 0);
mRoll = a.getFloat(R.styleable.CameraOverlay_exampleFloat_Z, 0);
} finally {
a.recycle();
}
init();
}
public CameraOverlay(Context con, float azimuth, float pitch, float roll) {
this(con,null);
this.mAzimuth = azimuth;
this.mPitch = pitch;
this.mRoll = roll;
TypedArray a = con.getTheme().obtainStyledAttributes(
null,
R.styleable.CameraOverlay,
0, 0);
try {
mTextString = a.getString(R.styleable.CameraOverlay_exampleString);
mAzimuth = a.getFloat(R.styleable.CameraOverlay_exampleFloat_X, 0);
mPitch = a.getFloat(R.styleable.CameraOverlay_exampleFloat_Y, 0);
mRoll = a.getFloat(R.styleable.CameraOverlay_exampleFloat_Z, 0);
} finally {
a.recycle();
}
init();
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
invalidate();
int paddingLeft = getPaddingLeft();
int paddingTop = getPaddingTop();
int paddingRight = getPaddingRight();
int paddingBottom = getPaddingBottom();
int contentWidth = getWidth() - paddingLeft - paddingRight;
int contentHeight = getHeight() - paddingTop - paddingBottom;
canvas.drawText("wsfsefseefsfsef",
paddingLeft + (contentWidth - mTextWidth),
paddingTop + (contentHeight + mTextHeight)
,mTextPaint);
}
}
This is my view layout:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:id="#+id/overlay" >
<mrl233.campustour.AugmentedReality.CameraOverlay
android:background="#ccc"
android:layout_width="300dp" android:layout_height="300dp" android:paddingLeft="20dp"
android:paddingBottom="40dp" custom:exampleDimension="24sp" custom:exampleColor="#33b5e5"
custom:exampleString="Hello, CameraOverlay"
custom:exampleFloat_X="0.1"
custom:exampleFloat_Y="0.5"
custom:exampleFloat_Z="1"/>
</FrameLayout>
I am adding this view to to an activity which has it's own view. This is the Activity class's onCreate method which is where I try to add the view.
#Override
#SuppressWarnings("deprecation")
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_augment);
preview = (FrameLayout) findViewById(R.id.camera_preview);
mPreview = new CameraPreview(this, camera);
mCameraOverlay = new CameraOverlay(this, 0, 0, 0);
preview.addView(mPreview);
preview.addView(mCameraOverlay);
preview.bringChildToFront(mCameraOverlay);
}
The layout of this activity class:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" tools:showIn="#layout/augment"
tools:context="mrl233.campustour.Activities.Augment">
<FrameLayout
android:id="#+id/camera_preview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
<!--<SurfaceView-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="match_parent"-->
<!--android:id="#+id/surfaceView"/>-->
<mrl233.campustour.AugmentedReality.CameraOverlay
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</FrameLayout>
</RelativeLayout>
I see two problems here. You shouldn't be calling invalidate() in onDraw method cause it causes view to redraw itself(infinite loop). Secondly getWidth() might be 0 there. You might want to get canvas width from onSizeChanged method
private int width;
private int height;
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
width = w;
height = h;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
...
int contentWidth = width - paddingLeft - paddingRight;
...
}
try playing with hardcoded sizes cause currently you might be drawing that text offscreen or giving it too little space(it might help you find the problem).
Smallest customView I can Think of would be:
public class CustomView extends View {
private TextPaint paint;
public CustomView(Context context) {
super(context);
paint = new TextPaint(Paint.LINEAR_TEXT_FLAG | Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.RED);
paint.setTextSize(20);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawText("Hello", 20, 20, paint);
}
}
and init it:
preview.addView(new CustomView(this));
There are few more smaller problems but it might get you going

Issue on TextView width when creating my own TextView

I created my own TextView by extending the TextView class in order to improve its display. I created various Paint and stuff to add a kind of margin. Then text has to be displayed right after the margin. If I set
android:layout_width="fill_parent"
the display is ok and my line is fully filled with a white background (as defined in my layout).
BUT if I set
android:layout_width="wrap_content"
the display goes wrong and the end of the text of my TextView is cropped. I guess this is due to the fact that I made a Translate in the onDraw method of my TextView but I don't know how to fix it.
Please note that I need the set wrap_content because I want to add another TextBox right after, and a LinearLayout around both, but for the moment the other TextBox erase a part of the content of the first one.
The code of my new TextBox is the following one :
package com.flo.ui;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.widget.TextView;
import com.flo.musicalnotes.R;
public class NoteItemTextView extends TextView {
// Properties
private Paint marginPaint;
private Paint linePaint;
private Paint circlePaint;
private int paperColor;
private float margin;
private float marginEnd;
private float textStart;
// Initialization
public NoteItemTextView(Context context) {
super(context);
this.Init(context);
}
public NoteItemTextView(Context context, AttributeSet attrs)
{
super(context, attrs);
this.Init(context);
}
private void Init(Context context)
{
// Resources retrieval
Resources myResources = getResources();
// Brush definition
this.marginPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
this.marginPaint.setColor(myResources.getColor(R.color.marginColor));
this.marginPaint.setStrokeWidth((float) 1.8);
this.linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
this.linePaint.setColor(myResources.getColor(R.color.underlineColor));
this.circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
this.circlePaint.setColor(myResources.getColor(R.color.marginColor));
this.circlePaint.setStyle(Paint.Style.FILL_AND_STROKE);
// various resources
this.paperColor = myResources.getColor(R.color.bgColor);
this.margin = myResources.getDimension(R.dimen.marginSize);
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
int ot = getResources().getConfiguration().orientation;
switch(ot)
{
case Configuration.ORIENTATION_LANDSCAPE:
this.marginEnd = this.margin + metrics.widthPixels / 100;
this.textStart = this.marginEnd + metrics.widthPixels / 100;
case Configuration.ORIENTATION_PORTRAIT:
this.marginEnd = this.margin + metrics.heightPixels / 100;
this.textStart = this.marginEnd + metrics.heightPixels / 100;
default:
this.marginEnd = this.margin + 5;
this.textStart = this.marginEnd + 10;
}
}
//#Override
protected void onDraw(Canvas canvas) {
// paper color
canvas.drawColor(this.paperColor);
// lines drawing
canvas.drawLine(0, getMeasuredHeight(), getMeasuredWidth(), getMeasuredHeight(), this.linePaint);
// marge drawing
canvas.drawLine(this.margin, 0, this.margin, getMeasuredHeight(), this.marginPaint);
canvas.drawLine(this.marginEnd, 0, this.marginEnd, getMeasuredHeight(), this.marginPaint);
double x = (this.textStart + this.marginEnd) / 1.8;
float y1 = getMeasuredHeight() / 3;
float y2 = getMeasuredHeight() * 2 / 3;
float radius = (float) 2.5;
canvas.drawCircle((float) x, y1, radius, this.circlePaint);
canvas.drawCircle((float) x, y2, radius, this.circlePaint);
canvas.save();
canvas.translate(this.textStart, 0);
super.onDraw(canvas);
canvas.restore();
}
}
Thanks for your help !
Try to add this code to your custom textview class
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int height = getMeasuredHeight();
int width = getMeasuredWidth();
Log.e(getClass().getSimpleName() , String.format("height x %s ::: width x %s ",height , width));
float density = getResources().getDisplayMetrics().density;
//Extra space after last letter.
float px = 2 * density;
int adjustedWidth = (int) (width + textStart + px);
setMeasuredDimension(adjustedWidth, height);
}
add this to your textview
android:paddingRight="25dp"

Android Progressbar with circle radius changes Dynamically

I want to change the circle radius dependent on the slider position
I created both individually.
while apply the circle method to the the Progress bar.
facing error.
Actually I call the Progress-Bar(Seek Bar) with
setContentView(R.layout.main);
and for drawing circle as you know I have to used setContentView(demoview);
Query: I want to merge both layout as display into image.
I didn't have idea will it possible or not?
Any guidance,tutorial appreciable.
Thanks for give your valuable time for my query.
Hope you have solution.
Check this out..
I am not using android seekbar, instead i am drawing a similar seekbar on canvas..
Check if this code can help u..
package com.test;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
public class SampleComp extends View implements OnTouchListener {
private Paint paint = null;
private int width = 0;
private int height = 0;
private int barStartX = 20;
private int barStartY = 20;
private int barEndX;
private int barEndY = 30;
private int radius;
private int heightAvailableForCircle;
private int widthAvailableForCircle;
private int maxRadius;
private int totalSeekBarLength;
private int currentSeekBarLength = 10;
private int whatPercentOfSeekBarIsSelected = 50;
public SampleComp(Context context) {
super(context);
paint = new Paint();
paint.setAntiAlias(true);
setOnTouchListener(this);
}
public SampleComp(Context context, AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
paint.setAntiAlias(true);
}
public SampleComp(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
paint = new Paint();
paint.setAntiAlias(true);
}
#Override
public void onDraw(Canvas canvas){
barEndX = getWidth() - 20;
paint.setColor(Color.WHITE);
setWidth(canvas.getWidth());
setHeight(canvas.getHeight());
setHeightAvailableForCircle(getViewHeight() - barEndY);
setWidthAvailableForCircle(getViewWidth() - 40);
System.out.println("heightAvailableForCircle: "+getAvailableHeightForCircle());
System.out.println("widthAvailableForCircle: "+getWidthAvailableForCircle());
totalSeekBarLength = barEndX - barStartX;
System.out.println("SEEK LEN: "+totalSeekBarLength);
canvas.drawRect(barStartX, barStartY, barEndX, barEndY, paint);
paint.setColor(Color.BLUE);
setMaxRadius(heightAvailableForCircle, widthAvailableForCircle);
whatPercentOfSeekBarIsSelected = getSelectedSeekBarPercentage(totalSeekBarLength,getCurrentSeekBarLenghtSelected());
System.out.println("whatPercentOfSeekBarIsSelected: "+whatPercentOfSeekBarIsSelected);
System.out.println("!!!!!: "+canvas.getWidth());
System.out.println("####: "+getViewWidth());
System.out.println("^^^^^^^^^************: "+ (whatPercentOfSeekBarIsSelected * (getViewWidth() - 40)) / 100);
canvas.drawRect(barStartX, barStartY, ( (whatPercentOfSeekBarIsSelected * (getViewWidth() - 40)) / 100) + 20,
barEndY, paint);
paint.setColor(Color.GRAY);
setRadius(whatPercentOfSeekBarIsSelected);
canvas.drawCircle( (canvas.getWidth())/2, (canvas.getHeight() - 30)/2, radius, paint);
}
private void setRadius(int per){
this.radius = (getMaxRadius() * per)/100;
}
private int getSelectedSeekBarPercentage(int total, int current){
int per = 0;
per = ( (current * 100) / total);
return per;
}
private void setRadius(int total, int current){
System.out.println("total: "+total);
System.out.println("current: "+current);
this.radius = ( ( (getMaxRadius()/2) * current) / 100);
System.out.println("radius: "+this.radius);
}
private void setMaxRadius(int h, int w){
this.maxRadius = h < w ? h/2 : w/2 ;
}
private int getMaxRadius(){
return this.maxRadius;
}
private void setWidth(int w){
this.width = w;
}
private void setHeight(int h){
this.height = h;
}
private int getViewWidth(){
return this.width;
}
private int getViewHeight() {
return this.height;
}
private void setHeightAvailableForCircle(int availableHeightForCircle){
this.heightAvailableForCircle = availableHeightForCircle;
}
private int getAvailableHeightForCircle(){
return this.heightAvailableForCircle;
}
private void setWidthAvailableForCircle(int wid){
this.widthAvailableForCircle = wid;
}
private int getWidthAvailableForCircle(){
return this.widthAvailableForCircle;
}
private void setCurrentSeekBarLength(int x){
this.currentSeekBarLength = x;
}
private int getCurrentSeekBarLenghtSelected(){
return this.currentSeekBarLength;
}
#Override
public boolean onTouch(View v, MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
System.out.println("x: "+x);
System.out.println("y: "+y);
if(x >= 10 && x<= barEndX && y >= 10 && y <= 30){
System.out.println("TRUE");
setCurrentSeekBarLength(x - 20);
invalidate();
}
return false;
}
}
And this is my Activity class:
package com.test;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.widget.ImageView;
public class SampleActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SampleComp(this));
}
}
Can u be little more specific regarding what u want to achieve. Ur question isn't that clear. What i can make out is, u want to increase/decrease the radius of the circle based on the progress bar value.
Have a look at the android custom component guide. You basically have to derive your circle component from android.view.View. Then you can add it to your layout like every other component.

Highlight/select a region in a bitmap

I am trying to be able to select/highlight a specific grid position onTouch.
Basically, I have an image, with a canvas/bitmap over layering the top of the image, I want to be able to click on a point of the image, and have that box become highlighted(first step is highlighting the grid, I will perform other algorithms on this later on)..
Here is the code for what I have now.. I am able to grab the x y coordinates, but I do not know how to associate the x y coordinates with the grid position.
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.MeasureSpec;
public class ImageWithGridView extends View {
private int rows = 12;
private int columns = 12;
private float width;
private float height;
public static final String TAG="ImageWithGridView";
private static final String SELX = "selX";
private static final String SELY = "selY";
private static final String VIEW_STATE = "viewState";
//private static final int ID = 92;
private int selX; //X index of selection
private int selY; //Y index of selection
private final Bitmap bitmap;
public ImageWithGridView(Context context) {
super(context);
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.sample);
//use your own image file name, instead of mobot_spring
}
public ImageWithGridView(Context context, AttributeSet attrs){
super(context, attrs);
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.sample);
//TODO Auto-generated constructor sub
}
public ImageWithGridView(Context context, AttributeSet attrs, int defStyle) {
super (context, attrs, defStyle);
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.sample);
//TODO Auto-generated constructor stub
}
#Override
protected Parcelable onSaveInstanceState() {
Parcelable p = super.onSaveInstanceState();
Log.d(TAG, "onSaveInstanceState");
Bundle bundle = new Bundle();
bundle.putInt(SELX, selY);
bundle.putInt(SELY, selY);
bundle.putParcelable(VIEW_STATE, p);
return bundle;
}
#Override
protected void onRestoreInstanceState(Parcelable state) {
Log.d(TAG, "onRestoreInstanceState");
Bundle bundle = (Bundle) state;
selX = bundle.getInt(SELX);
selY = bundle.getInt(SELY);
super.onRestoreInstanceState(bundle.getParcelable(VIEW_STATE));
return;
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
//adjust the ratio for width and height here:
this.setMeasuredDimension(parentWidth, parentHeight*2/3);
}
#Override
protected void onSizeChanged(int newWidth, int newHeight, int oldw, int oldh) {
width = newWidth / (float) columns;
height = newHeight / (float)rows;
Log.d(TAG, "~~~~~~~~~~~onSizeChanged: width " + width + ", height " + height);
super.onSizeChanged(newWidth, newWidth, oldw, oldh);
}
#Override
protected void onDraw(Canvas canvas) {
RectF dst = new RectF(width, height, (columns-1) * width, (rows - 1) * height);
//Draw the background...
Paint background = new Paint();
background.setColor(getResources().getColor(R.color.background));
Log.d(TAG, "~~~~~~~~~10 ");
canvas.drawRect(0, 0, getWidth(), getHeight(), background);
Log.d(TAG, "~~~~~~~~~20 ");
canvas.drawBitmap(bitmap, null, dst, null);
Log.d(TAG, "~~~~~~~~~30 ");
//Define colors for the grid lines
Paint dark = new Paint();
dark.setColor(getResources().getColor(R.color.dark));
Paint hilite = new Paint();
hilite.setColor(getResources().getColor(R.color.hilite));
Paint light = new Paint();
light.setColor(getResources().getColor(R.color.light));
//Draw the minor grid lines
for (int i = 0; i < rows; i++) {
canvas.drawLine(0, i * height-1, getWidth(), i * height-1, dark);
canvas.drawLine(0, i * height, getWidth(), i * height, light);
canvas.drawLine(0, i * height + 1, getWidth(), i * height + 1, hilite);
}
for (int i=0; i<columns; i++) {
canvas.drawLine(i * width-1, 0, i* width-1, getHeight(), dark);
canvas.drawLine(i * width, 0, i * width, getHeight(), light);
canvas.drawLine(i * width + 1, 0, i* width + 1, getHeight(), hilite);
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() != MotionEvent.ACTION_DOWN){
return super.onTouchEvent(event);
}
selX = (int) event.getX();
selY = (int) event.getY();
Log.d(TAG, "onTouchEvent: x " + selX + ", y " + selY);
return true;
}
public int getClickedX() {return selX;}
public int getClickedY() {return selY;}
}
This is my other class
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class CustomizeImageViewActivity extends Activity{
/** Called when the activity is first created. */
private Button btnShow;
private TextView label;
private ImageWithGridView imgView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//setContentView(R.layout.relative_layout);
//setContentView(R.layout.table_layout);
btnShow = (Button) findViewById(R.id.btnShow);
label = (TextView) findViewById(R.id.label);
imgView = (ImageWithGridView)findViewById(R.id.imageView1);
btnShow.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View arg0) {
label.setText("("+imgView.getClickedX() + "," + imgView.getClickedY() + ")");
}
});
}
}
Please advise with any guides/tutorials I should look at.. I have tried doing some research but I have not been able to find anything on this.

custom View not displayed well in android

My custom view does not display entirely. Please see my screenshot:
And the source code
package com.dots;
import android.graphics.Color;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
public class Dots1Activity extends Activity
{
private static final String TAG = "DotsActivity";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
CustomDrawableView view1 = new CustomDrawableView(this, 50, 50, Constants.DOTS_RADIUS, Constants.DOTS_COLOR);
CustomDrawableView view2 = new CustomDrawableView(this, 150, 150, Constants.DOTS_RADIUS, Constants.DOTS_COLOR);
CustomDrawableView view3 = new CustomDrawableView(this, 300, 300, Constants.DOTS_RADIUS, Constants.DOTS_COLOR);
ll.addView(view1, layoutParams);
ll.addView(view2, layoutParams);
ll.addView(view3, layoutParams);
setContentView(ll);
}
}
class CustomDrawableView extends View implements View.OnClickListener{
private Context context;
private int x, y, radius, color;
public CustomDrawableView(Context context, int x, int y, int radius, int color) {
super(context);
this.context = context;
this.x = x;
this.y =y;
this.radius = radius;
this.color = color;
setOnClickListener(this);
}
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(color);
canvas.drawCircle(x, y, radius, paint);
}
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
super.onMeasure(View.MeasureSpec.makeMeasureSpec(Constants.DOTS_RADIUS*2, View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(Constants.DOTS_RADIUS*2, View.MeasureSpec.EXACTLY));
}
public void onClick(View v) {
Toast.makeText(this.context,
x+"-"+y+"-"+radius,
Toast.LENGTH_SHORT).show();
}
}
public interface Constants
{
public static final int DOTS_RADIUS = 50;
public static final int DOTS_COLOR = Color.GREEN;
public static final int NUM_DOTS_ROWS = 5;
public static final int NUM_DOTS_COLS = 5;
public static final int WIDTH_BETWEEN_DOTS = 100;
public static final int HEIGHT_BETWEEN_DOTS = 100;
}
Making the assumption that you don't want the clipping you see in your screenshot. Your problem is that the values you return in onMeasure don't account for your x, y offsets:
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
super.onMeasure(View.MeasureSpec.makeMeasureSpec(Constants.DOTS_RADIUS*2 + x, View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(Constants.DOTS_RADIUS*2 + y, View.MeasureSpec.EXACTLY));
}
What exactly do you want to Achieve? if you want to be fullscreen then use the FILL_PARENT flag instead of WRAP_CONTENT at least for the width of your view. also for the height there is a weight parameter that might help even the height of your view. but since its a custom drawing i cant help you further if there are any adjustments needed in your view code. you have to figure that out for yourself.
The radius of each of your "dots" is identical, and this directly translates into the answer you return in onMeasure(). You're changing the x and y location of the center, getting further from the actual View canvas.

Categories

Resources