倒计时器FATAL EXCEPTION

时间:2015-11-29 22:10:25

标签: java android android-studio countdowntimer

所以我正在尝试在自定义视图类中实现一个计时器,这是我从一个活动调用的子类,但它给我这个错误

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" />

1 个答案:

答案 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()