0

I was able to write a simple timer that starts and resets time with a button. I was able to write it in MainActivity but now I want it only on ONE specific fragment. I have 3 navigation fragments. Home, History, and Learn.

Currently, my timer shows up on each tab.

Here's what is in MainActivity

public class MainActivity extends AppCompatActivity {
private Chronometer chronometer;
private boolean running;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    BottomNavigationView navView = findViewById(R.id.nav_view);
    AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
            R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications)
            .build();
    NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
    NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
    NavigationUI.setupWithNavController(navView, navController);


   chronometer = findViewById(R.id.chronometer);

}

public void startChronometer(View v) {
        if(!running) {
            chronometer.setBase(SystemClock.elapsedRealtime());
            chronometer.start();
            running = true;
            ((TextView)findViewById(R.id.startbutton)).setText("End");
        } else {
            if(running) {
                chronometer.setBase(SystemClock.elapsedRealtime());
                chronometer.stop();
                running = false;
                ((TextView) findViewById(R.id.startbutton)).setText("Start");
            }
        }
    } 
}

Here is the empty fragment code

public class HomeFragment extends Fragment {
    Chronometer chronometer;

public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    HomeViewModel homeViewModel = ViewModelProviders.of(this).get(HomeViewModel.class);
    View root = inflater.inflate(R.layout.fragment_home, container, false);
    final TextView textView = root.findViewById(R.id.text_home);
    homeViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
        @Override
        public void onChanged(@Nullable String s) {
            textView.setText(s);
        }
    });
    return root;
  }
}

Thank you for your help and for taking the time to read this.

Yotzin Castrejon
  • 439
  • 4
  • 16

1 Answers1

1

You can put your Code in the OnViewCreated function. Or simply use the View called 'root'. I changed the name to viewRoot for better understanding.

Of course you need to place the layout into the fragment and not in the activity.

public class HomeFragment extends Fragment {
    Chronometer chronometer;

public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    HomeViewModel homeViewModel = ViewModelProviders.of(this).get(HomeViewModel.class);

    View viewRoot = inflater.inflate(R.layout.fragment_home, container, false);


    final TextView textView = viewRoot.findViewById(R.id.text_home);
    homeViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
        @Override
        public void onChanged(@Nullable String s) {
            textView.setText(s);
        }
    });


    chronometer = viewRoot.findViewById(R.id.chronometer);

    //If you want to start the timer    
    startChronometer(viewRoot);

    return root;
  }
}

Be careful on startChronometer because you call findViewById. Do you know where these Buttons are placed? I added getView(), so you can call them from the fragment itself.

public void startChronometer(View v) {
        if(!running) {
            chronometer.setBase(SystemClock.elapsedRealtime());
            chronometer.start();
            running = true;
            ((TextView)getView().findViewById(R.id.startbutton)).setText("End");
        } else {
            if(running) {
                chronometer.setBase(SystemClock.elapsedRealtime());
                chronometer.stop();
                running = false;
                ((TextView) getView().findViewById(R.id.startbutton)).setText("Start");
            }
        }
    } 
}

Hope I could help.

BenG
  • 28
  • 7
  • 1
    it works well to start. But now my issue every time I click my button it crashes due to java.lang.IllegalStateException: Could not find method startChronometer(View) in a parent or ancestor Context for android:onClick attribute defined on view class androidx.appcompat.widget.AppCompatButton with id 'startbutton' – Yotzin Castrejon Aug 26 '20 at 18:11
  • 1
    I got it thanks for the help! What I had to do was add setonclicklistener. [This](https://stackoverflow.com/questions/4153517/how-exactly-does-the-androidonclick-xml-attribute-differ-from-setonclicklistene) helped a ton – Yotzin Castrejon Aug 26 '20 at 18:30