简体   繁体   English

使用倒数计时器时应用程式停止

[英]App Stops when using countdown timer

I'm working on an a Quiz App which has five fragments and every fragment has one Question in it. 我正在开发一个有五个片段的测验应用程序,每个片段中都有一个问题。 Fragments move in two ways. 碎片以两种方式移动。

  1. When user clicks on an option then the next fragment appears Immediately. 当用户单击一个选项时,下一个片段将立即显示。
  2. I've a countdown timer that if user does not click on any option then after 10 seconds the fragment is moved to new fragment. 我有一个倒数计时器,如果用户未单击任何选项,则10秒钟后该片段将移至新片段。

I've implemented the click functions. 我已经实现了点击功能。 when user clicks on the option app takes it to the next fragment but if in that next fragment user clicks no option then app stops Immediately. 当用户单击选项应用程序时,它将带到下一个片段,但是如果在该下一个片段中,用户未单击任何选项,则应用程序将立即停止。 Kindly have a look on this, I'm sharing code. 请看一下,我正在共享代码。

Question.java (Fragment1) Question.java(片段1)

 package com.example.sheikhspc.testapp;


import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.ShapeDrawable;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;


public class Question1 extends Fragment implements View.OnClickListener {


public Question1() {
    // Required empty public constructor
}
int counter = 0;
View view;
Fragment frag = null;
TextView tv;
ImageView imageView1, imageViewR, imageView2;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    view = inflater.inflate(R.layout.fragment_question1, container, false);
    imageView1 = (ImageView) view.findViewById(R.id.wrong1);
    imageViewR = (ImageView) view.findViewById(R.id.right);
    imageView2 = (ImageView) view.findViewById(R.id.wrong2);
    tv = (TextView) view.findViewById(R.id.timer1);

    imageView1.setOnClickListener(this);
    imageViewR.setOnClickListener(this);
    imageView2.setOnClickListener(this);
    new CountDownTimer(10000, 1000) {

        public void onTick(long millisUntilFinished) {
            tv.setText("Remaining Time: " + millisUntilFinished / 1000);
            //here you can have your logic to set text to edittext
        }

        public void onFinish() {
            frag = new Question2();
            FragmentManager fmm = getFragmentManager();
            FragmentTransaction fragmentTransactionn =  fmm.beginTransaction();
            fragmentTransactionn.addToBackStack(null);

            fragmentTransactionn.replace(R.id.container, frag);

            fragmentTransactionn.commit();

        }


    }.start();


    return view;
}


@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.wrong1:
            frag = new Question2();
            FragmentManager fm = getFragmentManager();
            FragmentTransaction fragmentTransaction = fm.beginTransaction();

            fragmentTransaction.replace(R.id.container,frag);

            fragmentTransaction.commit();

            break;
        case R.id.right:
            frag = new Question2();
            FragmentManager fm1 = getFragmentManager();
            FragmentTransaction fragmentTransaction1 = fm1.beginTransaction();

            fragmentTransaction1.replace(R.id.container,frag);

            fragmentTransaction1.commit();





            break;
        case R.id.wrong2:
            frag = new Question2();
            FragmentManager fm2 = getFragmentManager();
            FragmentTransaction fragmentTransaction2 = fm2.beginTransaction();

            fragmentTransaction2.replace(R.id.container,frag);

            fragmentTransaction2.commit();

            break;
        default:
            new CountDownTimer(10000, 1000) {

                public void onTick(long millisUntilFinished) {
                    tv.setText("Remaining Time: " + millisUntilFinished / 1000);
                    //here you can have your logic to set text to edittext
                }

                public void onFinish() {
                    frag = new Question2();
                    FragmentManager fmm = getFragmentManager();
                    FragmentTransaction fragmentTransactionn = fmm.beginTransaction();
                    fragmentTransactionn.addToBackStack(null);

                    fragmentTransactionn.replace(R.id.container, frag);

                    fragmentTransactionn.commit();

                }


            }.start();
            break;

    }
}
}

Question2.java (Fragment2) Question2.java(Fragment2)

package com.example.sheikhspc.testapp;


import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.app.Fragment;
import android.os.CountDownTimer;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;


public class Question2 extends Fragment implements View.OnClickListener {


public Question2() {
    // Required empty public constructor
}


Fragment frag = null;
TextView tv;
View view;
ImageView imageView1, imageViewR, imageView2;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    view = inflater.inflate(R.layout.fragment_question2, container, false);

    tv = (TextView)view.findViewById(R.id.timer2);
    imageView1 = (ImageView) view.findViewById(R.id.wrong1);
    imageViewR = (ImageView) view.findViewById(R.id.right);
    imageView2 = (ImageView) view.findViewById(R.id.wrong2);
    imageView1.setOnClickListener(this);
    imageViewR.setOnClickListener(this);
    imageView2.setOnClickListener(this);
    new CountDownTimer(10000, 1000) {

        public void onTick(long millisUntilFinished) {
            tv.setText("seconds remaining: " + millisUntilFinished / 1000);
            //here you can have your logic to set text to edittext
        }

        public void onFinish() {
            tv.setText("done!");
            frag = new Question3();
            FragmentManager fm = getFragmentManager();
            FragmentTransaction fragmentTransaction = fm.beginTransaction();

            fragmentTransaction.replace(R.id.container,frag);

            fragmentTransaction.commit();

        }

    }.start();


    return view;
}


@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.wrong1:
            frag = new Question3();
            FragmentManager fm = getFragmentManager();
            FragmentTransaction fragmentTransaction = fm.beginTransaction();

            fragmentTransaction.replace(R.id.container,frag);

            fragmentTransaction.commit();

            break;
        case R.id.right:
            frag = new Question3();
            FragmentManager fm1 = getFragmentManager();
            FragmentTransaction fragmentTransaction1 = fm1.beginTransaction();

            fragmentTransaction1.replace(R.id.container,frag);

            fragmentTransaction1.commit();





            break;
        case R.id.wrong2:
            frag = new Question3();
            FragmentManager fm2 = getFragmentManager();
            FragmentTransaction fragmentTransaction2 = fm2.beginTransaction();

            fragmentTransaction2.replace(R.id.container,frag);

            fragmentTransaction2.commit();

            break;
        default:
            new CountDownTimer(10000, 1000) {

                public void onTick(long millisUntilFinished) {
                    tv.setText("seconds remaining: " + millisUntilFinished / 1000);
                    //here you can have your logic to set text to edittext
                }

                public void onFinish() {
                    tv.setText("done!");
                    frag = new Question3();
                    FragmentManager fm = getFragmentManager();
                    FragmentTransaction fragmentTransaction = fm.beginTransaction();

                    fragmentTransaction.replace(R.id.container,frag);

                    fragmentTransaction.commit();

                }

            }.start();

            break;

    }
}
}

Error Log 错误记录

E/AndroidRuntime: FATAL EXCEPTION: main
              Process: com.example.sheikhspc.testapp, PID: 32330
              java.lang.NullPointerException: Attempt to invoke virtual  method 'android.app.FragmentTransaction  android.app.FragmentManager.beginTransaction()' on a null object reference
                  at com.example.sheikhspc.testapp.Question1$1.onFinish(Question1.java:58)
                  at android.os.CountDownTimer$1.handleMessage(CountDownTimer.java:127)
                  at android.os.Handler.dispatchMessage(Handler.java:102)
                  at android.os.Looper.loop(Looper.java:135)
                  at android.app.ActivityThread.main(ActivityThread.java:5343)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at java.lang.reflect.Method.invoke(Method.java:372)
                  at  com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
                  at  com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)
I/Process: Sending signal. PID: 32330 SIG: 9
Application terminated.

Second.java (Activity where all the fragments are displayed) Second.java(显示所有片段的活动)

package com.example.sheikhspc.testapp;

import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.app.Fragment;
import android.os.CountDownTimer;
import android.provider.DocumentsContract;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

public class Second extends AppCompatActivity {

Fragment frag;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_second);

    FragmentManager fm = getFragmentManager();
    FragmentTransaction fragmentTransaction = fm.beginTransaction();

    frag = new Question1();
    fragmentTransaction.replace(R.id.container,frag);

    fragmentTransaction.commit();

}
}

You will need to cancel the timer before you replace the fragment on click. 您需要先取消计时器,然后再替换片段。

When you create a new instance of CountDownTimer in onCreate method assign it to a variable for eg 当您在onCreate方法中创建CountDownTimer的新实例时,将其分配给变量,例如

CountDownTimer timer = new CountDownTimer(10000, 1000) {...};
timer.start();

And then in onClick method ie when user clicks any option stop the timer for eg 然后在onClick方法中,即当用户单击任何选项时,停止计时器,例如

@Override
public void onClick(View v) {
switch (v.getId()) {
    case R.id.btnNext:

        // Add this line to avoid crash
        timer.cancel();

        frag = new FragmentQuestion2();
        FragmentManager fm = getFragmentManager();
        FragmentTransaction fragmentTransaction = fm.beginTransaction();

        fragmentTransaction.replace(R.id.container,frag);

        fragmentTransaction.commit();

        break;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM