计时器任务显示为片段但不倒计时

时间:2019-07-11 21:54:50

标签: java android-fragments android-viewpager timertask

我是编程的超级新手。请原谅任何伪造的密码和/或糟糕的密码。另外,可能是问题的一部分。

我有一个与Viewpager绑定的片段。当用户点击按钮/滑动时,viewpager将显示片段的新实例。该片段中有一个计时器。计时器显示,并且当您单击到下一个视图时,它会更改时间。但是,它不能实时“倒数”。它仅显示创建片段时的时间。当您单击到下一个片段时,时间已更改。通常,该时间少于上一个片段。有时候,更多。

我最初是在“主要活动”中构建计时器的。它在那里很棒,但是不会显示在片段中。我将计时器移到片段上。那是它停止工作的时候。我已将timertask从onCreateView移至onResume,然后移至OnStart。考虑到我目前的知识水平,我已经尽可能地清理了我的代码。我搜索了过去两天的stackoverflow,试图找出答案。

这是存放计时器的片段。


public class TaskFragment extends Fragment {

  public static int done = 0;
  private static TextView clockDisplay;
  Button button1;
  private Timer activityTimer;
  private Timer clockTimer;
  private String activityTimeElapsedKey;
  private String clockFormat;
  private long activityTimerStart;
  private long activityTimeElapsed;

  private Context context;

  private int timeLimit;

  public static TaskFragment newInstance(String text) {

    TaskFragment frag1 = new TaskFragment();
    Bundle bundle = new Bundle();
    bundle.putString("msg", text);

    frag1.setArguments(bundle);

    return frag1;
  }

  @Override
  public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    context = getContext();
  }

  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
      Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_task, container, false);

    TextView tv = view.findViewById(R.id.frag_1);
    tv.setText(getArguments().getString("msg"));

    clockDisplay = view.findViewById(R.id.clock_display);
    activityTimeElapsedKey = getString(R.string.activity_time_elapsed_key);
    clockFormat = getString(R.string.clock_format);

    button1 = view.findViewById(R.id.button_1);
    button1.setOnClickListener(view1 -> {
      pager.setCurrentItem(getNextPossibleItemIndex(1), true);
      done += 1;
    });

    return view;
  }

  private int getNextPossibleItemIndex(int change) {

    int currentIndex = pager.getCurrentItem();
    int total = MainActivity.NUM_PAGES;

    if (currentIndex + change < 0) {
      return 0;
    }
    return Math.abs((currentIndex + change) % total);
  }

  @Override
  public void onStart() {
    super.onStart();
    startActivityTimer();
  }

  public void updateClock() {
    timeLimit = PreferenceManager.getDefaultSharedPreferences(context).getInt("timer", 15);
    long remaining = (timeLimit * 60000) - (System.currentTimeMillis() - activityTimerStart);
    int minutes = (int) TimeUnit.MILLISECONDS.toMinutes(remaining);
    double seconds = TimeUnit.MILLISECONDS.toSeconds(remaining % 60000);
    clockDisplay.setText(String.format(clockFormat, minutes, seconds));
  }

  //TODO create a timeout task and tie to activity timer
  private void startActivityTimer() {
    activityTimer = new Timer();
    activityTimerStart = System.currentTimeMillis();
    activityTimeElapsed = 0;
    clockTimer = new Timer();
    clockTimer.schedule(new ClockTimerTask(), 0, 100);
    updateClock();
  }

  private class ClockTimerTask extends TimerTask {

    @Override
    public void run() {
      if (isVisible()) {
        getActivity().runOnUiThread(() -> updateClock());
      }
    }
  }

}

这是片段的布局。


<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="match_parent">


  <Button
    android:id="@+id/button_1"
    style="@style/Widget.AppCompat.Button.Borderless"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:clickable="true"
    android:focusable="true"
    android:gravity="center"
    android:text="Done!"
    android:textColor="@color/colorPurple"
    android:textSize="24dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toBottomOf="@id/frag_1"/>

  <TextView
    android:id="@+id/clock_display"
    style="@style/ClockDisplay"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:visibility="visible"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintTop_toTopOf="parent"/>

  <TextView
    android:id="@+id/frag_1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_centerInParent="true"
    android:layout_centerVertical="true"
    android:padding="16dp"
    android:gravity="center"
    android:lineSpacingMultiplier="1.2"
    android:text="TextView"
    android:textColor="@color/colorDarkBlue"
    android:textSize="60dp"
    android:visibility="visible"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toBottomOf="@id/clock_display"/>

</androidx.constraintlayout.widget.ConstraintLayout>

这是pageadapter,以及它如何在片段实例之间进行切换。


private class MyPagerAdapter extends FragmentStatePagerAdapter {

    public MyPagerAdapter(FragmentManager fm) {
      super(fm);
    }


    //TODO Add Result fragment as case 5.
    @Override
    public Fragment getItem(int pos) {
      switch (pos) {
        case 0:
          return TaskFragment.newInstance("Get dressed.");
        case 1:
          return TaskFragment.newInstance("Brush your teeth.");
        case 2:
          return TaskFragment.newInstance("Make your bed.");
        case 3:
          return TaskFragment.newInstance("Put your shoes on.");
        case 4:
          return TaskFragment.newInstance("Get your backpack ready.");
        default:
          return TaskFragment.newInstance("Good morning!");
      }
    }



Expected Result: I expect my timer to countdown when the first fragment is opened. The timer should continue the countdown from where it left off when the fragment is replaced with the next version.

Actual Result: First fragment displays 19:59 (based on a preference setting of 20). No countdown. Second fragment displays 19:56 (example) also doesn't count down. Third/fourth fragment either display a few seconds countdown in the same pattern as the second fragment or a second or two are added rather than subtracted. The final fragment starts flickering between seconds back and forth.

0 个答案:

没有答案