Search code examples
androidandroid-studioandroid-recyclerviewtogglebutton

How can I check if an individual toggleButton in my recyclerView is selected?


I am creating an app that allows the user to create alarms and if the alarm is toggled on, then it will use broadcast receiver to wake the user up. The issue I am currently having is checking if a toggleButton from the recyclerView is checked. I need to check if each one is on and if it is, wake the user up at the set time. Any help is greatly appreciated!

Main activity:

package com.example.routineclock_alarmclockhabitbuilder;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TimePicker;
import android.widget.Toast;
import android.widget.ToggleButton;


import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.google.android.material.floatingactionbutton.FloatingActionButton;

import java.util.ArrayList;
import java.util.Calendar;

public class MainActivity extends AppCompatActivity {
    private RecyclerView mRecyclerView;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;
    ToggleButton toggleButton;
    FloatingActionButton addButton;
    AlarmManager alarmManager;
    PendingIntent pendingIntent;
    ArrayList<Item> myList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        addButton = findViewById(R.id.fab);

        addButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getApplicationContext(), CreateAlarmObject.class);
                startActivity(intent);
            }
        });

        myList = new ArrayList<>();

        for(int i = 0; i < myList.size(); i++) {
            myList.get(i).setText1("Alarm " + (i + 1));
        }

        mRecyclerView = findViewById(R.id.recyclerView);
        mRecyclerView.setHasFixedSize(true);
        mLayoutManager = new LinearLayoutManager(this);
        mAdapter = new Adapter(myList, false);
        mRecyclerView.setLayoutManager(mLayoutManager);
        new ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(mRecyclerView);
        mRecyclerView.setAdapter(mAdapter);
    }



    @Override
    protected void onResume() {
        super.onResume();
        if (getIntent().hasExtra("addedObject")) {
            Item newItem = getIntent().getParcelableExtra("addedObject");
            myList.add(newItem);
            Log.d("Resume", "Item added");
        }
        else {
            Log.d("Resume", "Does not have extra");
        }

        for(int i = 0; i < myList.size(); i++) {
            myList.get(i).setText1("Alarm " + (i + 1));
        }
    }

    public void OnToggleClicked(View view) {

        Log.d("Toggled", "Successfully toggled.");
        alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);

        long time;
        if ((mAdapter.) {
            Toast.makeText(MainActivity.this, "ALARM ON", Toast.LENGTH_SHORT).show();
            Calendar calendar = Calendar.getInstance();
            //Log.d("Toggle on", "Current hour: " + String.valueOf(cur);

            // calender is called to get current time in hour and minute

            //calendar.set(Calendar.HOUR_OF_DAY, extras.getInt("currentHour"));
            //calendar.set(Calendar.MINUTE, extras.getInt("currentMinute"));
            // using intent i have class AlarmReceiver class which inherits
            // BroadcastReceiver
            Intent intent = new Intent(this, AlarmReceiver.class);

            // we call broadcast using pendingIntent
            pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

            time = (calendar.getTimeInMillis() - (calendar.getTimeInMillis() % 60000));

            if (System.currentTimeMillis() > time) {
                // setting time as AM and PM
                if (calendar.AM_PM == 0)
                    time = time + (1000 * 60 * 60 * 12);
                else
                    time = time + (1000 * 60 * 60 * 24);
            }
            // Alarm rings continuously until toggle button is turned off

            alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, time, 10000, pendingIntent);
            //alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (time * 1000), pendingIntent);

        } else {
            Intent intent = new Intent(this, AlarmReceiver.class);
            pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
            alarmManager.cancel(pendingIntent);
            Toast.makeText(MainActivity.this, "ALARM OFF", Toast.LENGTH_SHORT).show();
        }
    }

    ItemTouchHelper.SimpleCallback itemTouchHelperCallback = new ItemTouchHelper.SimpleCallback(0 , ItemTouchHelper.RIGHT) {
        @Override
        public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
            return false;
        }

        @Override
        public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
            myList.remove(viewHolder.getAdapterPosition());
            mAdapter.notifyDataSetChanged();
        }
    };
}

Adapter

package com.example.routineclock_alarmclockhabitbuilder;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.ToggleButton;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;

public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {

    private ArrayList<Item> mList;


        public static class ViewHolder extends RecyclerView.ViewHolder {

            public ImageView mImageView;
            public TextView mTextView1;
            public TextView mTextView2;
            public ToggleButton mToggleButton;

            public ViewHolder(@NonNull View itemView) {
                super(itemView);
                mImageView = itemView.findViewById(R.id.imageView);
                mTextView1 = itemView.findViewById(R.id.textView);
                mTextView2 = itemView.findViewById(R.id.textView2);
                mToggleButton = itemView.findViewById(R.id.toggleButton);
            }
        }

        public Adapter(ArrayList<Item> exampleList, boolean toggleOn) {

            mList = exampleList;
        }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.example_item, parent, false);
        ViewHolder evh = new ViewHolder(v);
        return evh;
    }

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

            holder.mToggleButton.setChecked(mList.get(position).getToggleOn());
        Item currentItem = mList.get(position);

        holder.mImageView.setImageResource(currentItem.getImageResource());
        holder.mTextView1.setText(currentItem.getText1());
        holder.mTextView2.setText(currentItem.getText2());

    }

    @Override
    public int getItemCount() {
        return mList.size();
    }

    public void toggleItemOn(int position){
        mList.get(position).setToggleOn(true);
        notifyDataSetChanged();
    }
}

Activity that allows user to create the alarm object

package com.example.routineclock_alarmclockhabitbuilder;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;

import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TimePicker;

import com.google.android.material.floatingactionbutton.FloatingActionButton;

import java.util.Calendar;

public class CreateAlarmObject extends AppCompatActivity {

    FloatingActionButton backButton;
    Button addButton;
    EditText name, time;
    Item newItem = new Item(R.drawable.ic_clock, "Line 1", "Line 2", false, 0, 0);
    int currentHour, currentMinute;
    TimePicker alarmTimePicker;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_create_alarm_object);
        alarmTimePicker = findViewById(R.id.timePicker);

        backButton = findViewById(R.id.returnIcon);
        addButton = findViewById(R.id.addButton);
        name = findViewById(R.id.activityName);
        time = findViewById(R.id.activityTime);

        backButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(getApplicationContext(), MainActivity.class);
                newItem.setText1("Object name");
                newItem.setText2(String.valueOf(newItem.numActivities()) + " activities");
                currentHour = alarmTimePicker.getCurrentHour();
                currentMinute = alarmTimePicker.getChildCount();
                newItem.setCurrentHour(currentHour);
                newItem.setCurrentMinute(currentMinute);
                i.putExtra("addedObject", newItem);
                Log.d("ItemPassed", String.valueOf(newItem.getCurrentHour()) + ", " + String.valueOf(newItem.getCurrentMinute()));

                startActivity(i);
            }
        });

        addButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                newItem.addActivity(Integer.parseInt(time.getText().toString()), name.getText().toString());

                for(int i = 0; i < newItem.numActivities(); i++) {
                    Log.d("Item added", (i + 1) + ": " + newItem.getName(i) + ", " + newItem.getTime(i));
                }

            }
        });
    }
}

And the item class itself

package com.example.routineclock_alarmclockhabitbuilder;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.View;
import android.widget.TimePicker;
import android.widget.Toast;
import android.widget.ToggleButton;

import java.util.ArrayList;
import java.util.Calendar;

import static android.content.Context.ALARM_SERVICE;

public class Item implements Parcelable {

    private int mImageResource;
    private String mText1, mText2;
    private ArrayList<Activities> myActivities = new ArrayList<Activities>();
    private boolean toggleOn;
    private int currentHour, currentMinute;


    public Item(int imageResource, String text1, String text2, boolean toggle, int newHour, int newMinute) {
        mImageResource = imageResource;
        mText1 = text1;
        mText2 = text2;
        toggleOn = toggle;
        currentHour = newHour;
        currentMinute = newMinute;

    }

    protected Item(Parcel in) {
        mImageResource = in.readInt();
        mText1 = in.readString();
        mText2 = in.readString();
    }

    public static final Creator<Item> CREATOR = new Creator<Item>() {
        @Override
        public Item createFromParcel(Parcel in) {
            return new Item(in);
        }

        @Override
        public Item[] newArray(int size) {
            return new Item[size];
        }
    };

    public int getImageResource () {
        return mImageResource;
    }

    public String getText1 () {
        return mText1;
    }

    public String getText2 () {
        return mText2;
    }

    public void setText1 (String newString) {
        mText1 = newString;
    }

    public void setText2 (String newString) {
        mText2 = newString;
    }

    public void addActivity (int time, String name) {
        Activities newActivity = new Activities(time, name);
        myActivities.add(newActivity);
    }

    public int numActivities () {
        return myActivities.size();
    }

    public int getTime (int i) {
        return myActivities.get(i).getTime();
    }

    public String getName (int i) {
        return myActivities.get(i).getName();
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(mImageResource);
        dest.writeString(mText1);
        dest.writeString(mText2);
    }

    public boolean getToggleOn(){ return toggleOn; }

    public void setToggleOn(boolean toggleOn) { this.toggleOn = toggleOn; }

    public int getCurrentHour () {
        return currentHour;
    }

    public int getCurrentMinute () {
        return currentMinute;
    }

    void setCurrentHour (int newHour) {
        currentHour = newHour;
    }

    void setCurrentMinute (int newMinute) {
        currentMinute = newMinute;
    }
}

Solution

  • if I get you Right I think you can do it this way
    1 Disable the Recyclable by this.setIsRecyclable(false) this line of code in the constructor of the viewholder class
    only if you have limited items in your list
    2. Add The toggle event on the Toggle Button

        mToggleButton = itemView.findViewById(R.id.toggleButton);
        mToggleButton.setOnCheckedChangeListener(
        new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) 
            {
              currentItem.setToggleOn(isChecked);
                
            }
          }
        });
    

    Also effect the changes to the source eg database.
    3. check the toggle property of your current item in the onBindViewHolder method like

           if (currentItem.getToggleOn())
              holder.mToggleButton.setChecked(true);
            
           else
               holder.mToggleButton.setChecked(false);
            }