InflateException (Error inflating class) when using custom widget in xml - android

I created a custom imageview. But I get an InflateException when I try to run this. Can someone help me solve this?
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/herinnering_background">
<be.test.ArrowImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/kompas_arrow_car"
/>
</FrameLayout>
package be.test;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.widget.ImageView;
public class ArrowImageView extends ImageView{
public ArrowImageView(Context context) {
super(context);
}
#Override
public void draw(Canvas canvas) {
super.draw(canvas);
Paint paint = new Paint(Paint.LINEAR_TEXT_FLAG);
paint.setColor(Color.GREEN);
paint.setTextSize(12.0F);
canvas.drawText("Hello World in custom view", 100, 100, paint);
}
}

I think the problem is that you need to implement a constructor with the AttributeSet because this is the one used by the LayoutInflator:
ImageView(Context context, AttributeSet attrs)

Related

Drawing a circle in android

I've been learning android for a week.i'm writing a simple program which draws a circle.but when i run it it tells me that the program has stopped. i read the code again and again but couldn't find the error. can you please help me.
package org.example.viewwithlines;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
static public class GraphicsView extends View
{
Paint p;
public GraphicsView(Context context) {
super(context);
p=new Paint();
p.setColor(Color.MAGENTA);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawCircle(30, 40, 10, p);
}
}
}
and this is the xml file
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<org.example.viewwithlines.MainActivity.GraphicsView
android:id="#+id/graphics" android:layout_width="fill_parent" android:layout_height="fill_parent"/>
</LinearLayout>
What are you trying to do?
For backgrounds, and general uses, you can do it simply creating a drawable resource and setting it to a square view:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" >
<solid android:color="#FF0000"/>
</shape>
It's hard to say the exact reason why it doesn't work. I see at least two reasons.
Class name in the layout is wrong. Since GraphicsView is a nested class, it should be org.example.viewwithlines.MainActivity$GraphicsView
<view
class="org.example.viewwithlines.MainActivity$GraphicsView"
android:id="#+id/graphics"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
You have to provide a constuctor that takes Context and AttributeSet as arguments
public GraphicsView(Context context, AttributeSet attrs) {
super(context, attrs);
p=new Paint();
p.setColor(Color.MAGENTA);
}
When you extend a view, you need to add different constructors to it to make it work in different circumstances. When you use a View in xml, it uses the constructor with AttributeSet included.
Try adding one that looks like this:
public GraphicsView(Context context, AttributeSet attribs) {
super(context, attribs);
p=new Paint();
p.setColor(Color.MAGENTA);
}
See this post, also, for a more detailed explanation.
Also, you're trying to reference an inner class in xml. When you do that, you have to use a $ instead of a .. The problem with this is that $ is an illegal character in xml tag names, so you have to do something like this instead:
<view class="org.example.viewwithlines.MainActivity$GraphicsView"
...
attribs here
... />

Redraw canvas in Android

I am making an Android 2.2 application using Eclipse. My application should draw
images by clicking on buttons.
I have two buttons at the bottom of the screen, and I need to draw the shape in the same screen that has the buttons. I used FrameLayout in which the shapes are drawn.
My problem is, the two shapes are overwriting, so I need to redraw the canvas.
My Code
package draw.tab;
import android.app.Activity;
//import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.FrameLayout;
public class DrawActivity extends Activity implements OnClickListener
{
DrawView drawview;
CircleView circleView;
FrameLayout Frame;
Button square,circle;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Frame=(FrameLayout)findViewById(R.id.MyFrame);
drawview=new DrawView(this);
circleView=new CircleView(this);
square=(Button)findViewById(R.id.buttonTest);
square.setOnClickListener(this);
circle=(Button)findViewById(R.id.circleButton);
circle.setOnClickListener(this);
}
public void onClick(View v)
{
switch (v.getId()) {
case R.id.circleButton:
Frame.addView(circleView);
/*circleView.setBackgroundColor(Color.rgb(40,100,20));
circleView.findViewById(R.id.CircleViewId);
setContentView(circleView);*/
break;
case R.id.buttonTest:
Frame.addView(drawview);
/*drawview.setBackgroundColor(Color.WHITE);
drawview.findViewById(R.id.DrawViewId);
drawview.layout(400,0,200,450);
setContentView(drawview);*/
break;
}
}
}
DrawView.java
package draw.tab;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;
public class DrawView extends View
{
Paint paint=new Paint();
Path pat=new Path();
public DrawView(Context context)
{
super(context);
paint.setColor(Color.RED);
paint.setStyle(Style.STROKE);
//context.clearRect(70,140,400,450);
//pat.addRect(50,40,250,400,Path.Direction.CW);
}
public DrawView(Context con,AttributeSet atts)
{
super(con,atts);
}
#Override
public void onDraw(Canvas canvas)
{
//canvas.drawPath(pat,paint);
canvas.drawLine(20,40,450,40,paint);//horizontal top
canvas.drawRect(70,140,400,450,paint);
canvas.drawLine(20,40,20,600,paint);//vertical left
canvas.drawLine(20,600,450,600,paint);//horizontal bottom
canvas.drawLine(450,40,450,600,paint);//vertical right
//this.invalidate();
}
}
CircleView.java
package draw.tab;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;
public class CircleView extends View
{
Paint p=new Paint();
Path path=new Path();
public CircleView(Context context)
{
super(context);
p.setColor(Color.BLUE);
p.setStyle(Style.STROKE);
//path.addCircle(250,250,50,Path.Direction.CW);
}
public CircleView(Context con,AttributeSet atts)
{
super(con,atts);
}
public void onDraw(Canvas c)
{
//c.drawPath(path,p);
//c.save();
c.drawLine(20,40,450,40, p);//horizontal top
c.drawCircle(250,350,100,p);
c.drawLine(20,40,20,600,p);//vertical left
c.drawLine(20,600,450,600,p);//horizontal bottom
c.drawLine(450,40,450,600,p);//vertical right
//c.restore();
this.invalidate();
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:visibility="visible"
android:id="#+id/MyFrame"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<draw.tab.DrawView
android:id="#+id/DrawViewId"
android:layout_width="320dp"
android:layout_height="600dp">
</draw.tab.DrawView>
<draw.tab.CircleView
android:id="#+id/CircleViewId"
android:layout_width="320dp"
android:layout_height="600dp">
</draw.tab.CircleView>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:gravity="bottom">
<Button
android:layout_height="wrap_content"
android:text="Circle"
android:id="#+id/circleButton"
android:layout_width="160dp">
</Button>
<Button
android:layout_height="wrap_content"
android:text="Square"
android:id="#+id/buttonTest"
android:layout_width="160dp">
</Button>
</LinearLayout>
</FrameLayout>
The above is all my code. The shapes are overwriting, so I want to remove and redraw the canvas or redraw without overwriting.
Try calling invalidate() on your view.
Call canvas.save() then do drawing then call canvas.restore(). Also depends on the bitmaps you are drawing. The bitmaps should have a transparent background.
Edit
Call canvas.drawColor(Color.White); //Or whichever bg color before drawing the bitmap.
Edit
In drawview try this
canvas.drawRect(getLeft(), getTop(), getright() , getBottom() ,paint);
Similarly in CircleView
canvas.drawCircle(getLeft()+getwidth()/2, getTop()+getheight()/2, 100, paint);
One last try. Set children gravity..
<draw.tab.DrawView
android:id="#+id/DrawViewId"
android:layout_width="320dp"
android:layout_height="600dp"
android:layout_gravity="left">
</draw.tab.DrawView>
<draw.tab.CircleView
android:id="#+id/CircleViewId"
android:layout_width="320dp"
android:layout_height="600dp"
android:layout_gravity="right">
</draw.tab.CircleView>

Shape Drawable View in XML

I'm using the shapedrawable example word for word (nearly) and can't seem to call a shapedrawable class in xml. The only extra step stated by the documentation was to override the View(Context, AttributeSet), which I think I did. The docs I'm referring to are here: http://developer.android.com/guide/topics/graphics/2d-graphics.html Here is my code.
AndroidTest.java
package com.android.test;
import android.app.Activity;
import android.os.Bundle;
public class AndroidTest extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
ShapeSquare.java
package com.android.test;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.util.AttributeSet;
import android.view.View;
public class ShapeSquare extends View {
private ShapeDrawable mDrawable;
public ShapeSquare(Context context, AttributeSet attrs) {
super(context, attrs);
int x = 10;
int y = 10;
int width = 300;
int height = 50;
mDrawable = new ShapeDrawable(new OvalShape());
mDrawable.getPaint().setColor(0xff74AC23);
mDrawable.setBounds(x, y, x + width, y + height);
}
protected void onDraw(Canvas canvas) {
mDrawable.draw(canvas);
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<com.android.test.shapedrawable.ShapeSquare
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
The error is a force quit error and I can't figure out where the problem lies. The shape properties will be dictated by user input (eventually), so the shape needs to be created in a class as opposed to all xml.
Figured out the problem here. I had to remove "shapedrawable" from:
<com.android.test.shapedrawable.ShapeSquare
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
Apparently, that was just the location of the demo. I thought it was referencing the class somehow.

Forced Close after adding custom ImageView

I'm trying to add a custom ImageView to my main.xml, but if I start the program it closes with a forced close.
XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/background" >
<test.testpkg.CustomImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center_vertical"
android:src="#drawable/bg"/>
</LinearLayout>
Java:
package test.testpkg;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.widget.ImageView;
public class CustomImageView extends ImageView {
public CustomImageView(Context context) {
super(context);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
}
Also if I start the program in Debugger after the FC I only get this:
link text
Debugger is useless if you haven't attached the source code of Android. Moreover... it's more useful to provide the logcat output. Anyway, I think you are missing one of the constructors. Try this:
public class CustomImageView extends ImageView {
public CustomImageView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public CustomImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
// rest of your code....

Android inflating xml layout generates RuntimeException

I'm new to Android and i'm trying to inflate a layout in xml but i get a RuntimeException. I have cut out almost everything except for my activity class and the class extending SurfaceView.
Can anyone tell me what i'm doing wrong?
main.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.hj.Panel
android:id="#+id/SurfaceView01"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
Rita.java:
package com.hj;
import android.app.Activity;
import android.os.Bundle;
public class Rita extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
Panel.java:
package com.hj;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.SurfaceView;
class Panel extends SurfaceView {
private Paint mPaint;
public Panel(Context context) {
super(context);
}
#Override
public void onDraw(Canvas canvas) {
mPaint = new Paint();
canvas.drawRect(0, 0, 322, 644, mPaint);
}
}
In order to make your code run I had to do the following:
1) change "match_parent" to "fill_parent"
2) add constructor
public Panel(Context context, AttributeSet atts) {
super(context, atts);
}
You may want to try that
You should always post a stack trace when you report an exception. (Run adb logcat on the command line, or view the logcat window in eclipse).
Without that, my best guess is that it should be fill_parent, not match_parent.

Categories

Resources