androidandroid-fragmentstimerstopwatchchronometer

Where to put code when it works in MainActivity but you want it in a fragment?


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.


Solution

  • 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.