3

I down know if made it right. I have a RecyclerView with 2 ViewHolders. ProgramHolder and CountDownTimerHolder. In the CountDownTimerHolder is the time where the countdown starts predifined. If you click on the Settings Button, I start a new Activity where I set Minutes and Seconds for the Timer.

My question is: Can I pass the data that I get from the Activity to change the predifined starting time in the CountDownTimerHolder?

Sry but I am still a noob at Programming. If there are any questions let me know.

CountDownTimerHolder

public class CountdownTimerHolder extends RecyclerView.ViewHolder {
    private static final String TAG = "CountdownTimerHolder";

    Context context;

    private TextView mTextViewCountdown;
    private Button btnStartPauseTimer, btnStopTimer, btnSetTimerSettings;

    private CountDownTimer countDownTimer;

    private boolean timerRunning;

    //THIS ARE THE VARIABLES TO BE UPDATED
    public long START_TIME_IN_MILLI_SEC = 1000000;
    private long timeLeftInMilliSec = START_TIME_IN_MILLI_SEC;

    public CountdownTimerHolder(@NonNull View itemView) {
        super(itemView);

        Log.d(TAG, "CountdownTimerHolder: IT IS CALLED");

        context = itemView.getContext();

        mTextViewCountdown = itemView.findViewById(R.id.timer);

        btnStartPauseTimer = itemView.findViewById(R.id.playBtn);
        btnStopTimer = itemView.findViewById(R.id.stopBtn);
        btnSetTimerSettings = itemView.findViewById(R.id.btnSetTimerSettings);

        btnStartPauseTimer.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (timerRunning) {
                    pauseTimer();
                }else {
                    startTimer();
                }
            }
        });

        btnStopTimer.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                resetTimer();
            }
        });

        btnSetTimerSettings.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(context, SettingCountdownTimer.class);
                context.startActivity(intent);
            }
        });

        updateCountDownText();
    }

    private void startTimer() {
        countDownTimer = new CountDownTimer(timeLeftInMilliSec, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {
                timeLeftInMilliSec = millisUntilFinished;
                updateCountDownText();
            }

            @Override
            public void onFinish() {
                timerRunning = false;
                btnStartPauseTimer.setBackgroundResource(R.drawable.ic_play_arrow_black_24dp);
            }
        }.start();
        timerRunning = true;
        btnStartPauseTimer.setBackgroundResource(R.drawable.ic_pause_black_24dp);
    }

    private void pauseTimer() {
        countDownTimer.cancel();
        timerRunning = false;
        btnStartPauseTimer.setBackgroundResource(R.drawable.ic_play_arrow_black_24dp);
    }

    private void resetTimer() {
        countDownTimer.cancel();
        timeLeftInMilliSec = START_TIME_IN_MILLI_SEC;
        updateCountDownText();
        btnStartPauseTimer.setBackgroundResource(R.drawable.ic_play_arrow_black_24dp);
    }

    private void updateCountDownText() {
        int minutes = (int) (timeLeftInMilliSec / 1000) /60;
        int seconds = (int) (timeLeftInMilliSec /1000) % 60;

        String timeLeftFormatted = String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds);
        mTextViewCountdown.setText(timeLeftFormatted);
    }


}

SettingCountdownTimerActivity

public class SettingCountdownTimer extends AppCompatActivity {

    EditText editTextMinutes, editTextSeconds;
    Button btnSetTimer;

    public long minutesToMillisInput;
    public long secondsToMillisInput;

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

        editTextMinutes = findViewById(R.id.editTextMinutes);
        editTextSeconds = findViewById(R.id.editTextSeconds);
        btnSetTimer = findViewById(R.id.btnSetTimer);

        btnSetTimer.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String inputMinutes = editTextMinutes.getText().toString();
                String inputSeconds = editTextSeconds.getText().toString();

                if (inputMinutes.length() == 0 && inputSeconds.length() == 0) {
                    Toast.makeText(SettingCountdownTimer.this, "Minuten und Sekunden koennen nicht leer sein",
                            Toast.LENGTH_SHORT).show();
                    return;
                }

                minutesToMillisInput = Long.parseLong(inputMinutes) * 60000;
                secondsToMillisInput = Long.parseLong(inputSeconds) * 1000;

                if (minutesToMillisInput == 0 && secondsToMillisInput == 0) {
                    Toast.makeText(SettingCountdownTimer.this, "Minuten und Sekunden koennen nicht 0 sein",
                            Toast.LENGTH_SHORT).show();
                    return;
                }
                //HERE I WANT TO PASS THE NEW VARIABLES TO VIEWHOLDER
                finish();
            }
        });

    }

}

Adapter

public class PickedExercisesAdapter extends RecyclerView.Adapter {

    OnItemClickListener mlistener;

    private static final String TAG = "PickedExercisesRecycler started";

    private ArrayList<ExerciseModel> mlist;

    private static int EXERCISE_CARD_TYPE = 0;
    private static int COUNTDOWN_TIMER_TYPE = 1;

    public PickedExercisesAdapter(ArrayList<ExerciseModel> list) {
        this.mlist = list;
    }


    @Override
    public int getItemViewType(int position) {

        if (position % 2 == 0) {
            return EXERCISE_CARD_TYPE;
        }
        return COUNTDOWN_TIMER_TYPE;
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());

        View view;

        if (viewType == EXERCISE_CARD_TYPE) {
            view = layoutInflater.inflate(R.layout.exercise_card_view, parent, false);
            return new ProgramHolder(view);
        } else {
            view = layoutInflater.inflate(R.layout.countdown_timer, parent, false);
            return new CountdownTimerHolder(view);
        }
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {

        ExerciseModel exerciseModel = null;

        if (position % 2 == EXERCISE_CARD_TYPE) {
            if (position == 0) {
                exerciseModel = mlist.get(0);
            } else {
                int listposition = position / 2;
                exerciseModel = mlist.get(listposition);
            }

            ProgramHolder programHolder = (ProgramHolder) holder;
            Glide.with(programHolder.itemView.getContext())
                    .load(exerciseModel.getExerciseImage())
                    .placeholder(R.drawable.ic_launcher_foreground)
                    .into(programHolder.exerciseImage);

            programHolder.exerciseTitle.setText(exerciseModel.getExerciseTitle());
            programHolder.exerciseTitle.setText(exerciseModel.getExerciseTitle());
            programHolder.exerciseBodyPart.setText(exerciseModel.getExerciseBodyPart());
            programHolder.exerciseDifficulty.setText(String.valueOf(exerciseModel.getDifficulty()));
            programHolder.exerciseDescription.setText(exerciseModel.getExerciseDescription());

        } else {
            CountdownTimerHolder countDownTimerHolder = (CountdownTimerHolder) holder;
        }
    }

    @Override
    public int getItemCount() {
        int listsizedouble = mlist.size() * 2;

        return listsizedouble;
    }


    class ProgramHolder extends RecyclerView.ViewHolder {

        OnItemClickListener mlistener;

        TextView exerciseTitle, exerciseDifficulty, exerciseBodyPart, exerciseDescription;

        ConstraintLayout expandableLayout;

        Button arrowBtn;

        ImageView exerciseImage;

        CardView cardView;

        public ProgramHolder(final View itemView) {
            super(itemView);

            arrowBtn = itemView.findViewById(R.id.arrowBtn);
            expandableLayout = itemView.findViewById(R.id.constraintExpendable);
            exerciseTitle = itemView.findViewById(R.id.exerciseTitle);
            exerciseDifficulty = itemView.findViewById(R.id.exerciseDifficulty);
            exerciseBodyPart = itemView.findViewById(R.id.exerciseBodyPart);
            exerciseImage = itemView.findViewById(R.id.exerciseImage);
            exerciseDescription = itemView.findViewById(R.id.exerciseDescription);
            cardView = itemView.findViewById(R.id.cardView);

            arrowBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int position = getAdapterPosition();
                    if (position != RecyclerView.NO_POSITION && mlistener != null) {
                        mlistener.onItemClick(position);
                    }
                }
            });
        }

        private void setExerciseDetails(ExerciseModel exerciseModel) {
            exerciseTitle.setText(exerciseModel.getExerciseTitle());
        }
    }

    public interface OnItemClickListener {
        void onItemClick(int position);
    }

    public void setOnItemClickListener(OnItemClickListener listener) {
        this.mlistener = listener;
    }

}

RecyclerViewFragment

public class PickedExerciseRecyclerViewFragment extends Fragment {

    private static final String TAG = "PickedExerciseRecyclerV";

    RecyclerView recyclerView;
    PickedExercisesAdapter adapter;
    RecyclerView.LayoutManager manager;
    View view;

    private ArrayList<ExerciseModel> list;


    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        view = inflater.inflate(R.layout.picked_exercise_recycler_view, container, false);

        list = getArguments().getParcelableArrayList("exerciseProgram");
        recyclerView = view.findViewById(R.id.pickedExerciseRecyclerView);

        manager = new LinearLayoutManager(getContext());
        adapter = new PickedExercisesAdapter(list);

        recyclerView.setLayoutManager(manager);
        recyclerView.setHasFixedSize(true);
        recyclerView.setAdapter(adapter);


        adapter.setOnItemClickListener(new PickedExercisesAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(int position) {
                Log.d(TAG, "onItemClick: clicked " + position);

                View view1 = recyclerView.getLayoutManager().findViewByPosition(position);
                ConstraintLayout constraintLayout = view1.findViewById(R.id.constraintExpendable);
                Button arrowBtn = view1.findViewById(R.id.arrowBtn);
                CardView cardView = view1.findViewById(R.id.cardView);
                if (constraintLayout.getVisibility() == View.GONE) {
                    cardView.getMaxCardElevation();
                    TransitionManager.beginDelayedTransition(cardView, new AutoTransition());
                    constraintLayout.setVisibility(View.VISIBLE);
                    arrowBtn.setBackgroundResource(R.drawable.ic_keyboard_arrow_up_black_24dp);
                } else {
                    TransitionManager.beginDelayedTransition(cardView, new AutoTransition());
                    constraintLayout.setVisibility(View.GONE);
                    arrowBtn.setBackgroundResource(R.drawable.ic_keyboard_arrow_down_black_24dp);
                }
            }
        });

        return view;
    }
}
panhr
  • 31
  • 2
  • Yes, you can. My recommendation is two fold. Create custom view classes instead of inflating in your adapter, and then to modify the underlying ArrayList of data to store a container interface that ExerciseModel and a custom 'flag' class both implement. This 'flag' class can then be dynamically configured to determine (anything really) but time remaining in your case. Then in the custom view class for the countdown, just have a public setter of that value called before the view is wrapped by the viewholder. (hope that makes sense). – mawalker Mar 28 '20 at 03:56
  • Emmm I dont quite got what you mean I should do... Do you have time to write me a bit of code or pseudocode? And another question: does it update my recyclerview automatically if i change the time? – panhr Mar 28 '20 at 11:51
  • Simpler answer first: If you update your underlying data (such as: list.get(0).setTime(XXXXX), or whatever), you should call adapter.notifyDataSetChanged(); and that will make it automatically update the views inside the recyclerview. I'll look into making a full answer for you, but might take a little while. – mawalker Mar 29 '20 at 04:40
  • Firstly thank you for your answer... Second just that you know... In the list are just exercise model objects... They arent connected with the countdown viewholder... If you want to see the full code, just tell me... I can show you how this list is passed to the adapter... And again thank you – panhr Mar 29 '20 at 12:35

0 Answers0