13:12:16.142 14848-14848/cn.eoe.handclock E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.NullPointerException
at cn.eoe.handclock.widget.HandClock.onMeasure(HandClock.java:36)
at android.view.View.measure(View.java:12723)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4698)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1369)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:660)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:553)
at android.view.View.measure(View.java:12723)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4698)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:293)
at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:141)
at android.view.View.measure(View.java:12723)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4698)
at android.support.v7.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:400)
at android.view.View.measure(View.java:12723)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4698)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:293)
at android.view.View.measure(View.java:12723)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4698)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1369)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:660)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:553)
at android.view.View.measure(View.java:12723)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4698)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:293)
at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2092)
at android.view.View.measure(View.java:12723)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1064)
at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2442)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4424)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
HandClock源代码:
package cn.eoe.handclock.widget;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.View;
import java.util.Calendar;
public class HandClock extends View implements Runnable {
private Bitmap bitmap;
private float scale;
private float handCenterWidthScale;
private float handCenterHeightScale;
private int minuteHandSize;
private int hourHandSize;
private Handler handler=new Handler();
@Override
public void run() {
//重新绘制view
invalidate();
//重新设置定时器,在60s后调用run方法
handler.postDelayed(this,60*1000);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension((int) (bitmap.getWidth() * scale),
(int) (bitmap.getHeight() * scale));]//这里:java.lang.NullPointerException
at cn.eoe.handclock.widget.HandClock.onMeasure(HandClock.java:36)
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
@SuppressLint("DrawAllocation") Paint paint=new Paint();
@SuppressLint("DrawAllocation") Rect src=new Rect();
@SuppressLint("DrawAllocation") Rect target=new Rect();
src.left=0;
src.top=0;
src.right=bitmap.getWidth();
src.bottom=bitmap.getHeight();
target.left=0;
target.top=0;
target.bottom=(int)(src.bottom*scale);
target.right=(int)(src.right*scale);
//画表盘图像
canvas.drawBitmap(bitmap,src,target,paint);
//计算表盘中心点的横纵坐标
float centerX=bitmap.getWidth()*scale*handCenterWidthScale;
float centerY=bitmap.getHeight()*scale*handCenterHeightScale;
//表盘中心点画一个半径为5的实心圆圈
canvas.drawCircle(centerX,centerY,5,paint);
//设置分针为3个像素粗
paint.setStrokeWidth(3);
Calendar calendar=Calendar.getInstance();
int currentMinute=calendar.get(Calendar.MINUTE);
int currentHour=calendar.get(Calendar.HOUR);
//计算分针和时间的弧度
double minuteRadian=Math.
toRadians((360-((currentMinute*6)-90))%360);
double hourRadian=Math.
toRadians((360-((currentHour*30)-90))%360-(30*currentMinute/60));
//在表盘上画分针
canvas.drawLine(centerX,centerY,(int)(centerX+minuteHandSize*Math.
cos(minuteRadian)),(int)(centerY-minuteHandSize*Math.sin(minuteRadian)),
paint);
//设置时针为4个像素粗
paint.setStrokeWidth(4);
//在表盘上画时针
canvas.drawLine(centerX,centerY,
(int)(centerX+hourHandSize*Math.cos(hourRadian)),
(int)(centerY-hourHandSize*Math.sin(hourRadian)),paint);
}
public HandClock(Context context,AttributeSet attrs) {
super(context, attrs);
//读取相应的属性值
int clockImageResourceId = attrs.getAttributeResourceValue(null,
"clockImageSrc", 0);
if (clockImageResourceId >0) {
bitmap = BitmapFactory.decodeResource(getResources(), clockImageResourceId);
scale = attrs.getAttributeFloatValue(null, "scale", 1);
handCenterWidthScale = attrs.getAttributeFloatValue(null,
"handCenterWidthScale", bitmap.getWidth() / 2);
handCenterHeightScale = attrs.getAttributeFloatValue(null,
"handCenterHeightScale", bitmap.getHeight() / 2);
//在读取分针和时针长度后,将其值按图像的缩放比例进行缩放
minuteHandSize = (int) (attrs.getAttributeIntValue(null,
"minuteHandSize", 0) * scale);
hourHandSize = (int) (attrs.getAttributeIntValue(null,
"hourHandSize", 0) * scale);
int currentSecond = Calendar.getInstance().get(Calendar.SECOND);
//将定时器设在0分钟时执行run方法
handler.postDelayed(this, (60 - currentSecond) * 1000);
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
//删除回调类
handler.removeCallbacks(this);
}
}
Mainactivity:
package cn.eoe.handclock;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import cn.eoe.handclock.widget.TestHandClock1;
import cn.eoe.handclock.widget.TestHandClock2;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
@Override
public void onClick(View v) {
Intent intent;
switch (v.getId()) {
case R.id.btnHandClock1:
intent = new Intent(this, TestHandClock1.class);
startActivity(intent);
break;
case R.id.btnHandClock2:
intent = new Intent(this, TestHandClock2.class);
startActivity(intent);
break;
}
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btnHandClock1=findViewById(R.id.btnHandClock1);
Button btnHandClock2=findViewById(R.id.btnHandClock2);
btnHandClock1.setOnClickListener(this);
btnHandClock2.setOnClickListener(this);
}
}
mainXML文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/text1"
android:id="@+id/btnHandClock1"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/text2"
android:id="@+id/btnHandClock2"/>
</LinearLayout>
HandClock1Xml文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/backColor"
android:gravity="center">
<cn.eoe.handclock.widget.HandClock
android:layout_width="164dp"
android:layout_height="45dp"
app:clockImageSrc="@drawable/clock1"
app:handCenterHeightScale="0.512"
app:handCenterWidthScale="0.477"
app:hourHandSize="40"
app:minuteHandSize="54"
app:scale="0.75"/>
</LinearLayout>
编译都显示没问题,运行起来就变成了这样子
那位大哥大姐能解解惑吗???