Reputation: 444
I created a Custom View class that takes a path, then fills it white and colors its edge red:
StrokeFill.java:
package com.kf.pathshape;
...
public class StrokeFill extends View{
private Path shapePath;
public StrokeFill(Context context, Path path) {
super(context);
this.shapePath = path;
// TODO Auto-generated constructor stub
}
public StrokeFill(Context context, AttributeSet attrs, Path shapePath) {
super(context, attrs);
this.shapePath = shapePath;
}
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
//canvas.drawColor(Color.BLACK);
super.onDraw(canvas);
//Sets paints and draws the shapes
Paint fillPaint = new Paint();
fillPaint.setColor(android.graphics.Color.WHITE);
fillPaint.setStyle(Paint.Style.FILL);
fillPaint.setStrokeWidth(0);
Paint strokePaint = new Paint();
strokePaint.setColor(android.graphics.Color.RED);
strokePaint.setStyle(Paint.Style.STROKE);
strokePaint.setStrokeWidth(2);
canvas.drawPath(shapePath, fillPaint);
canvas.drawPath(shapePath, strokePaint);
}
}
My layout XML (main.xml) is very simple:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<com.kf.pathshape.StrokeFill
android:id="@+id/pathshape"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Activity:
setContentView(R.layout.main);
shapeView = (StrokeFill) findViewById(R.id.pathshape);
shapeView = new StrokeFill(this, testpath);
testpath is a valid path. It's giving me errors even if I comment out the lines defining "shapeView". Logcat:
07-11 01:50:17.150: E/AndroidRuntime(24321): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.kf.pathshape/com.kf.pathshape.PathshapeActivity}: android.view.InflateException: Binary XML file line #6: Error inflating class com.kf.pathshape.StrokeFill
07-11 01:50:17.150: E/AndroidRuntime(24321): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1651)
07-11 01:50:17.150: E/AndroidRuntime(24321): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667)
07-11 01:50:17.150: E/AndroidRuntime(24321): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
07-11 01:50:17.150: E/AndroidRuntime(24321): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
07-11 01:50:17.150: E/AndroidRuntime(24321): at android.os.Handler.dispatchMessage(Handler.java:99)
07-11 01:50:17.150: E/AndroidRuntime(24321): at android.os.Looper.loop(Looper.java:130)
07-11 01:50:17.150: E/AndroidRuntime(24321): at android.app.ActivityThread.main(ActivityThread.java:3691)
07-11 01:50:17.150: E/AndroidRuntime(24321): at java.lang.reflect.Method.invokeNative(Native Method)
07-11 01:50:17.150: E/AndroidRuntime(24321): at java.lang.reflect.Method.invoke(Method.java:507)
07-11 01:50:17.150: E/AndroidRuntime(24321): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
07-11 01:50:17.150: E/AndroidRuntime(24321): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:670)
07-11 01:50:17.150: E/AndroidRuntime(24321): at dalvik.system.NativeStart.main(Native Method)
07-11 01:50:17.150: E/AndroidRuntime(24321): Caused by: android.view.InflateException: Binary XML file line #6: Error inflating class com.kf.pathshape.StrokeFill
07-11 01:50:17.150: E/AndroidRuntime(24321): at android.view.LayoutInflater.createView(LayoutInflater.java:508)
07-11 01:50:17.150: E/AndroidRuntime(24321): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:570)
07-11 01:50:17.150: E/AndroidRuntime(24321): at android.view.LayoutInflater.rInflate(LayoutInflater.java:623)
07-11 01:50:17.150: E/AndroidRuntime(24321): at android.view.LayoutInflater.inflate(LayoutInflater.java:408)
07-11 01:50:17.150: E/AndroidRuntime(24321): at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
07-11 01:50:17.150: E/AndroidRuntime(24321): at android.view.LayoutInflater.inflate(LayoutInflater.java:276)
07-11 01:50:17.150: E/AndroidRuntime(24321): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:234)
07-11 01:50:17.150: E/AndroidRuntime(24321): at android.app.Activity.setContentView(Activity.java:1679)
07-11 01:50:17.150: E/AndroidRuntime(24321): at com.kf.pathshape.PathshapeActivity.onCreate(PathshapeActivity.java:73)
07-11 01:50:17.150: E/AndroidRuntime(24321): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1050)
07-11 01:50:17.150: E/AndroidRuntime(24321): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1615)
07-11 01:50:17.150: E/AndroidRuntime(24321): ... 11 more
07-11 01:50:17.150: E/AndroidRuntime(24321): Caused by: java.lang.NoSuchMethodException: StrokeFill(Context,AttributeSet)
I searched through the forum but didn't find what I need. I already defined the constructor taking context and attrs. What am I missing here?
Upvotes: 1
Views: 1466
Reputation: 4354
As you are extending a view, you need to implements 3 constructors:
public class StrokeFill extends View{
private Path mShapePath;
public StrokeFill(Context context) {
super(context);
init();
}
public StrokeFill(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public StrokeFill(Context context, AttributeSet attrs, int defstyle) {
super(context, attrs, defstyle);
init();
}
private void init(){
//some code... or not =)
}
public void setPath(Path path){
mShapePath = path;
}
/* rest of your code */
}
Then in your activity:
shapeView = (StrokeFill) findViewById(R.id.pathshape);
shapeView.setPath(yourPath);
Hope this helps you
Upvotes: 2
Reputation: 6598
When You create your custom view from xml android calls StrokeFill(Context,AttributeSet)
constructor. You have to create that constructor if you want to inflate your view from xml. You can also create your view in code, then delete it from xml, in this case you don't need StrokeFill(Context,AttributeSet)
constructor.
For example:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/myLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
</LinearLayout>
Activity:
setContentView(R.layout.main);
LinearLayout v = (LinearLayout)findViewById(R.id.myLayout);
shapeView = new StrokeFill(this, testpath);
v.addView(shapeView);
Upvotes: 0
Reputation: 22493
no need to create it again
shapeView = new StrokeFill(this, testpath);
modify like this
setContentView(R.layout.main);
shapeView = (StrokeFill) findViewById(R.id.pathshape);
Upvotes: 0