2

I have an activity, say A, which has a fragment with a textview called TotalTimerFragment which contains a countdowntimer. There are 2 other fragments called F1 and F2. Activity A adds F1 and the countdowntimer in fragment TotalTimerFragment starts. After a few seconds F1 is replaced by F2. And here the countdowntimer should continue for few more seconds. But it crashes and gives a NullPointerException for the findViewById in the OnTick method in the class.

Here is the code for the FT fragment: getActivity().findViewById(R.id.total_timer_textview) in onTick method gives NullPointerException

public class TotalTimerFragment extends Fragment{
    TextView totalWorkoutTimer;
    TotalTimeCounter timeCounter;
    static long total_millis;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_totaltimer, container, false);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        totalWorkoutTimer = (TextView) getActivity().findViewById(R.id.total_timer_textview);
    }

    public class TotalTimeCounter extends CountDownTimer {
        TextView totalWorkoutTimer;

        public TotalTimeCounter(long millisInFuture, long countDownInterval) {
            super(millisInFuture, countDownInterval);
        }

        @Override
        public void onTick(long millisUntilFinished) {
            total_millis = millisUntilFinished;
            String total_hms = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(total_millis),
                    TimeUnit.MILLISECONDS.toMinutes(total_millis) - TimeUnit.HOURS.toMinutes(TimeUnit.
                        MILLISECONDS.toHours(total_millis)), TimeUnit.MILLISECONDS.toSeconds(total_millis) -
                        TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(total_millis)));
            totalWorkoutTimer = (TextView)getActivity().findViewById(R.id.total_timer_textview);
            totalWorkoutTimer.setText(total_hms);
        }

        @Override
        public void onFinish() {

        }
    }
}
peak
  • 105,803
  • 17
  • 152
  • 177
suku
  • 10,507
  • 16
  • 75
  • 120

3 Answers3

4

Here:

totalWorkoutTimer = (TextView) getActivity().findViewById(R.id.total_timer_textview);

Causing issue because total_timer_textview TextView is inside Fragment layout but accessing it getActivity() method which return context of Activity.

Use view first parameter of onViewCreated method like:

totalWorkoutTimer = (TextView)view.findViewById(R.id.total_timer_textview);
ρяσѕρєя K
  • 132,198
  • 53
  • 198
  • 213
  • 1
    Thanks! Your suggestion solved the problem. I would have never thought of using the view in onViewCreated. – suku Jan 08 '16 at 05:36
  • Although now the views of my other fragments are getting merged for some reason. I had tried using getView() on the fragment and then using it. But that didn't work. Can you elaborate a bit on how your suggestion works? I can learn something valuable. Thanks – suku Jan 08 '16 at 05:38
  • `other fragments are getting merged` means? – ρяσѕρєя K Jan 08 '16 at 05:48
  • When fragment A is replaced by fragment B, Fragment B is overlapping A but not replacing. Looks like both are simultaneously attached. During my previous trials (before using countdowntimer) the replacing was occurring properly – suku Jan 08 '16 at 06:22
1

If you are using fragment and your textview inside your layout than you should use view instead of getActivity()

totalWorkoutTimer = (TextView) view.findViewById(R.id.total_timer_textview);

And seems to you are not calling timer class, you can try this

     public class TotalTimerFragment extends Fragment{
    TextView totalWorkoutTimer;
    TotalTimeCounter timeCounter;
    static long total_millis;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_totaltimer, container, false);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        totalWorkoutTimer = (TextView) view.findViewById(R.id.total_timer_textview);
//Call your count down timer class///
    }

    public class TotalTimeCounter extends CountDownTimer {

        public TotalTimeCounter(long millisInFuture, long countDownInterval) {
            super(millisInFuture, countDownInterval);
        }

        @Override
        public void onTick(long millisUntilFinished) {
            total_millis = millisUntilFinished;
            String total_hms = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(total_millis),
                    TimeUnit.MILLISECONDS.toMinutes(total_millis) - TimeUnit.HOURS.toMinutes(TimeUnit.
                            MILLISECONDS.toHours(total_millis)), TimeUnit.MILLISECONDS.toSeconds(total_millis) -
                            TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(total_millis)));
            totalWorkoutTimer.setText(total_hms);
        }

        @Override
        public void onFinish() {

        }
    }
Mohit Suthar
  • 8,725
  • 10
  • 37
  • 67
  • I am calling the TotalTimerClass through the Fragments using an interface – suku Jan 08 '16 at 05:19
  • What way do you suggest I use the view? Where and how should I declare it? I have tried one method using view, it solves the problem, but some other issues arise. Hence, I am asking for your suggestions. Methods used: 1) using the view in the onCreatedView and 2) declaring a view = TotalTimerFragment.super.getView() inside the TotalTimeCounter class – suku Jan 08 '16 at 06:28
1

You must need textview with id of total_timer_textview in your fragment xml file as well

Kedar
  • 11
  • 5