所以我正在尝试在自定义视图类中实现一个计时器,这是我从一个活动调用的子类,但它给我这个错误
FATAL EXCEPTION: main java.lang.NullPointerException
at com.alfredochapa.crazymaze.Nivel$1.onTick(Nivel.java:133)
这是我目前的代码,我无法得到什么实施错误,任何建议如何让它工作,我真的需要倒数计时器在这个类
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.CountDownTimer;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.widget.ProgressBar;
import android.widget.TextView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;
import java.util.concurrent.TimeUnit;
import java.util.logging.Handler;
/**
* Created by alfredochapa on 27/11/15.
*/
public class Nivel extends View{
TextView text1;
private static final String FORMAT = "%02d:%02d:%02d";
int seconds , minutes;
int width, height;
int tiempo;
private Ball ball;
private Vector<Rect> listaRects;
private Display mDisplay;
public Nivel(Context context, AttributeSet attrs) throws IOException, JSONException {
super(context, attrs);
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
mDisplay = wm.getDefaultDisplay();
width = mDisplay.getWidth();
height = mDisplay.getHeight();
//Obtenemos el valor del atributo level que esta en el layout
int level = Integer.parseInt(attrs.getAttributeValue(null, "level"));
//Se lee el archivo con el JSON
InputStream is = getResources().openRawResource(R.raw.levels);
Writer writer = new StringWriter();
char[] buffer = new char[1024];
try {
Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
int n;
while ((n = reader.read(buffer)) != -1) {
writer.write(buffer, 0, n);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
is.close();
}
String jsonString = writer.toString();
//Obtenemos los valores dependiendo del nivel
JSONArray myListsAll= new JSONArray(jsonString);
for(int i=0;i<myListsAll.length();i++){
JSONObject jsonobject= (JSONObject) myListsAll.get(i);
int id= Integer.parseInt(jsonobject.optString("level"));
if(id == level){
//Tiempo que tarda el nivel
tiempo = Integer.parseInt(jsonobject.optString("time"));
//Obtener coordenadas para la bola
JSONObject jsonobjectBall = jsonobject.getJSONObject("ball");
double bx = Integer.parseInt(jsonobjectBall.optString("x")) /100.0;
double by = Integer.parseInt(jsonobjectBall.optString("y")) /100.0;
//Se crea la bola con las coordenadas
Drawable drawableBall = context.getResources().getDrawable(R.drawable.ball);
ball = new Ball(this, drawableBall, (int)(width*bx), (int)(height*by), (int)(width*.1), (int)(width*.1));
listaRects = new Vector<Rect>();
JSONArray wallList = jsonobject.getJSONArray("wall");
for(int j=0; j<wallList.length();j++){
JSONObject jsonobjectwall= (JSONObject) wallList.get(j);
double x1 = Integer.parseInt(jsonobjectwall.optString("x1")) / 100.0;
double y1 = Integer.parseInt(jsonobjectwall.optString("y1")) / 100.0;
double x2 = Integer.parseInt(jsonobjectwall.optString("x2")) / 100.0;
double y2 = Integer.parseInt(jsonobjectwall.optString("y2")) / 100.0;
Rect r = new Rect((int) (width*x1), (int) (height*y1), (int) (width*x2), (int) (height*y2));
listaRects.add(r);
}
}
}
text1=(TextView)findViewById(R.id.timer);
new CountDownTimer(16069000, 1000) { // adjust the milli seconds here
public void onTick(long millisUntilFinished) {
text1.setText("" + String.format(FORMAT,
TimeUnit.MILLISECONDS.toHours(millisUntilFinished),
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) - TimeUnit.HOURS.toMinutes(
TimeUnit.MILLISECONDS.toHours(millisUntilFinished)),
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) - TimeUnit.MINUTES.toSeconds(
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished))));
}
public void onFinish() {
text1.setText("done!");
}
}.start();
}
@Override
synchronized protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
ball.dibujaFigura(canvas);
Paint pincel = new Paint();
pincel.setColor(Color.argb(255, 164, 199, 57));
pincel.setStrokeWidth(5);
pincel.setStyle(Paint.Style.FILL);
for (Rect rec: listaRects) {
canvas.drawRect(rec, pincel);
}
}
public class Ball {
private Drawable drawable;
private int width, height;
private View view;
private int x, y;
public Ball(View view, Drawable drawable,int x, int y, int w, int h) {
this.view = view;
this.drawable = drawable;
this.width = w;
this.height = h;
this.x = x;
this.y = y;
}
public void dibujaFigura(Canvas canvas){
canvas.save();
drawable.setBounds(x - width/2, y - height/2, x + width/2, y + height/2);
drawable.draw(canvas);
canvas.restore();
}
}
}
这是我希望计时器继续的文本视图
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/timer"
android:text="Timer"
android:layout_gravity="right|top" />
答案 0 :(得分:1)
它是null
,因为它上面没有layout
,我认为您应inflate
提供如下视图:
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.Your_view, null);
text1=(TextView)v.findViewById(R.id.timer);
或者,由于您使用的是View
View
,您可以使用text1=(TextView)View.findViewById(R.id.timer);
进行操作。
context
您可以测试的另一种方法是使用构造函数传递的Context
创建一个Context mContext;
对象并调用它来查找视图,如下所示:
this.context = mContext;
在你的构造函数上:
TextView
查找text1=(TextView)mContext.findViewById(R.id.timer);
Collections.sort()