在android中使用CircularCountdown自定义视图时获取异常
在android中使用CircularCountdown自定义视图时出现异常,在下面添加了代码 MainActivity.java activity_main.xml 添加了自定义视图循环计数在android中使用CircularCountdown自定义视图时获取异常,android,android-custom-view,Android,Android Custom View,在android中使用CircularCountdown自定义视图时出现异常,在下面添加了代码 MainActivity.java activity_main.xml 添加了自定义视图循环计数 CircularCountdown.java 循环计数自定义视图 package com.example.jayakarthik.sampleanim; 导入android.content.Context; 导入android.graphics.Canvas; 导入android.graphics.C
CircularCountdown.java
循环计数自定义视图
package com.example.jayakarthik.sampleanim;
导入android.content.Context;
导入android.graphics.Canvas;
导入android.graphics.Color;
导入android.graphics.Paint;
导入android.graphics.RectF;
导入android.os.Handler;
导入android.text.TextPaint;
导入android.view.view;
公共类循环计数扩展视图{
私人最终油漆背景漆;
私人最终油漆;
私人最终油漆;
私人长启动时间;
私人长时间;
私人长时间;
私有长进程毫秒;
私人双重进步;
私有矩形边界;
私有浮动半径;
私家车;
私人浮动高度;
私有浮动文本偏移;
私有最终处理程序viewHandler;
私有最终可运行更新视图;
公共循环计数(上下文){
超级(上下文);
//用于将圆拟合到
circleBounds=新的RectF();
//圆和手柄的尺寸
半径=200;
抗手足口病=10;
//将计数器限制为最大时间毫秒
最大时间=5000;
//开始和当前时间
startTime=System.currentTimeMillis();
当前时间=开始时间;
//背景的风格
backgroundPaint=新油漆();
背景绘画.设置风格(绘画.风格.笔划);
backgroundPaint.setAntiAlias(真);
背景漆。设定行程宽度(10);
背景漆.固定行程盖(漆.盖.方形);
backgroundPaint.setColor(Color.parseColor(#4d”);//深灰色
//“进步”的风格
progressPaint=新油漆();
progressPaint.setStyle(Paint.Style.STROKE);
progressPaint.setAntiAlias(真);
前进。设置行程宽度(10);
progressPaint.setStrokeCap(油漆盖方形);
progressPaint.setColor(Color.parseColor(#00A9FF”);
//中间文本的样式
textPaint=新的textPaint();
textPaint.setTextSize(半径/2);
textPaint.setColor(Color.BLACK);
textPaint.setTextAlign(Paint.Align.CENTER);
//文本属性
textHeight=textPaint.descent()-textPaint.ascent();
textOffset=(textHeight/2)-textPaint.descent();
//这将确保动画将定期运行
viewHandler=新处理程序();
updateView=new Runnable(){
@凌驾
公开募捐{
//更新当前时间
currentTime=System.currentTimeMillis();
//获取以毫秒为单位的运行时间,并在
Progress毫秒=最大时间-(currentTime-startTime)%maxTime;
//获取范围的当前进度
进度=(双)进度毫秒/最大时间;
CircularCountdown.this.invalidate();
viewHandler.postDelayed(updateView,1000/60);
}
};
viewHandler.post(updateView);
}
@凌驾
受保护的void onDraw(画布){
super.onDraw(帆布);
//获取视图的中心
float centerWidth=canvas.getWidth()/2;
float centerHeight=canvas.getHeight()/2;
在视野中间设置我们的圈子
圆边界设置(中心宽度-半径,
中心高度-半径,
中心宽度+半径,
中心高度+半径);
//画背景圈
画布.画圈(中心宽度、中心高度、半径、背景漆);
//我们想从-90°开始,0°指向右边
画布绘制弧(圆形边界,-90,(浮动)(进度*360),假,进度绘制);
//在圆圈内显示文本
canvas.drawText((双精度)(进程毫秒/100)/10+“s”,
中心宽度、中心高度+文本偏移,
(油漆);
//画把手或圆圈
canvas.drawCircle((浮动)(中心宽度+(数学sin(进度*2*数学PI)*半径)),
(浮动)(中心高度-(数学cos(进度*2*数学PI)*半径)),
手淫,
油漆);
}
}
日志
08-19 13:03:13.662 3700-3700/com.example.jayakarthik.sampleanim E/AndroidRuntime﹕ 致命异常:主
进程:com.example.jayakarthik.sampleanim,PID:3700
java.lang.RuntimeException:无法启动活动组件信息{com.example.jayakarthik.sampleanim/com.example.jayakarthik.sampleanim.MainActivity}:android.view.InflateException:二进制XML文件行#8:膨胀类com.example.jayakarthik.sampleanim.circountdown时出错
在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2252)上
位于android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2301)
在android.app.ActivityThread.access$800(ActivityThread.java:144)
在android.app.ActivityThread$H.handleMessage(ActivityThread.java:1246)
位于android.os.Handler.dispatchMessage(Handler.java:106)
位于android.os.Looper.loop(Looper.java:136)
位于android.app.ActivityThread.main(ActivityThread.java:5212)
位于java.lang.reflect.Method.Invokenactive(本机方法)
位于java.lang.reflect.Method.invoke(Method.java:515)
在com.android.internal.os.zyteinit$MethodAndArgsCaller.run(Zy)上
package com.example.jayakarthik.sampleanim;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
<RelativeLayout 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:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<com.example.jayakarthik.sampleanim.CircularCountdown
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"/>
</RelativeLayout>
package com.example.jayakarthik.sampleanim;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Handler;
import android.text.TextPaint;
import android.view.View;
public class CircularCountdown extends View {
private final Paint backgroundPaint;
private final Paint progressPaint;
private final Paint textPaint;
private long startTime;
private long currentTime;
private long maxTime;
private long progressMillisecond;
private double progress;
private RectF circleBounds;
private float radius;
private float handleRadius;
private float textHeight;
private float textOffset;
private final Handler viewHandler;
private final Runnable updateView;
public CircularCountdown(Context context) {
super(context);
// used to fit the circle into
circleBounds = new RectF();
// size of circle and handle
radius = 200;
handleRadius = 10;
// limit the counter to go up to maxTime ms
maxTime = 5000;
// start and current time
startTime = System.currentTimeMillis();
currentTime = startTime;
// the style of the background
backgroundPaint = new Paint();
backgroundPaint.setStyle(Paint.Style.STROKE);
backgroundPaint.setAntiAlias(true);
backgroundPaint.setStrokeWidth(10);
backgroundPaint.setStrokeCap(Paint.Cap.SQUARE);
backgroundPaint.setColor(Color.parseColor("#4D4D4D")); // dark gray
// the style of the 'progress'
progressPaint = new Paint();
progressPaint.setStyle(Paint.Style.STROKE);
progressPaint.setAntiAlias(true);
progressPaint.setStrokeWidth(10);
progressPaint.setStrokeCap(Paint.Cap.SQUARE);
progressPaint.setColor(Color.parseColor("#00A9FF"));
// the style for the text in the middle
textPaint = new TextPaint();
textPaint.setTextSize(radius / 2);
textPaint.setColor(Color.BLACK);
textPaint.setTextAlign(Paint.Align.CENTER);
// text attributes
textHeight = textPaint.descent() - textPaint.ascent();
textOffset = (textHeight / 2) - textPaint.descent();
// This will ensure the animation will run periodically
viewHandler = new Handler();
updateView = new Runnable(){
@Override
public void run(){
// update current time
currentTime = System.currentTimeMillis();
// get elapsed time in milliseconds and clamp between <0, maxTime>
progressMillisecond = maxTime - (currentTime - startTime) % maxTime;
// get current progress on a range <0, 1>
progress = (double) progressMillisecond / maxTime;
CircularCountdown.this.invalidate();
viewHandler.postDelayed(updateView, 1000/60);
}
};
viewHandler.post(updateView);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// get the center of the view
float centerWidth = canvas.getWidth() / 2;
float centerHeight = canvas.getHeight() / 2;
// set bound of our circle in the middle of the view
circleBounds.set(centerWidth - radius,
centerHeight - radius,
centerWidth + radius,
centerHeight + radius);
// draw background circle
canvas.drawCircle(centerWidth, centerHeight, radius, backgroundPaint);
// we want to start at -90°, 0° is pointing to the right
canvas.drawArc(circleBounds, -90, (float)(progress*360), false, progressPaint);
// display text inside the circle
canvas.drawText((double)(progressMillisecond/100)/10 + "s",
centerWidth, centerHeight + textOffset,
textPaint);
// draw handle or the circle
canvas.drawCircle((float)(centerWidth + (Math.sin(progress * 2 * Math.PI) * radius)),
(float)(centerHeight - (Math.cos(progress * 2 * Math.PI) * radius)),
handleRadius,
progressPaint);
}
}
08-19 13:03:13.662 3700-3700/com.example.jayakarthik.sampleanim E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.jayakarthik.sampleanim, PID: 3700
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.jayakarthik.sampleanim/com.example.jayakarthik.sampleanim.MainActivity}: android.view.InflateException: Binary XML file line #8: Error inflating class com.example.jayakarthik.sampleanim.CircularCountdown
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2252)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2301)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1246)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5212)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.view.InflateException: Binary XML file line #8: Error inflating class com.example.jayakarthik.sampleanim.CircularCountdown
at android.view.LayoutInflater.createView(LayoutInflater.java:603)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:696)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:294)
at android.app.Activity.setContentView(Activity.java:1929)
at com.example.jayakarthik.sampleanim.MainActivity.onCreate(MainActivity.java:12)
at android.app.Activity.performCreate(Activity.java:5240)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1088)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2216)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2301)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1246)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5212)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NoSuchMethodException: <init> [class android.content.Context, interface android.util.AttributeSet]
at java.lang.Class.getConstructorOrMethod(Class.java:472)
at java.lang.Class.getConstructor(Class.java:446)
at android.view.LayoutInflater.createView(LayoutInflater.java:568)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:696)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:294)
at android.app.Activity.setContentView(Activity.java:1929)
at com.example.jayakarthik.sampleanim.MainActivity.onCreate(MainActivity.java:12)
at android.app.Activity.performCreate(Activity.java:5240)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1088)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2216)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2301)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1246)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5212)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
at dalvik.system.NativeStart.main(Native Method)
public View (Context context, AttributeSet attrs)
public CircularCountdown (Context context, AttributeSet attrs) {
super(context, attrs);
}