Please i have a spinner in a CustomAdapterClass which extends ArrayAdapter. I want to save the state of the spinner even when the activity is destroyed. It is only one spinner that appears in a listview. I have searched but all i see is when there are more than one spinner, each having it's own id. How do i achieve this please. Here is my code
public class CustomListAdapterForCgpa extends ArrayAdapter<String> implements AdapterView.OnItemSelectedListener {
LinearLayout colorLayout;
TextView userGpScoreUneditable;
Spinner spinnerForGradePoints;
public String mathSubject= "Mathematics";
public String chemSubject = "Chemistry";
public String physicsSubject = "Physics";
public String biologySubject = "Biology";
public String gsSubject = "General Studies";
public String cscSubject = "CSC";
SharedPreferences sharedPreferences;
SharedPreferences.Editor editor;
public CustomListAdapterForCgpa(Context context, ArrayList<String> subjects) {
super(context, R.layout.custom_list_view_cgpa, subjects);
}
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
#NonNull
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater layoutInflater = LayoutInflater.from(getContext());
View customView = layoutInflater.inflate( R.layout.custom_list_view_cgpa,parent,false);
String singleSubject = getItem(position);
TextView singleText = (TextView) customView.findViewById(R.id.listSubjectsMyCoursesCgpa);
colorLayout = (LinearLayout)customView.findViewById(R.id.colorForSubjectsCgpa);
userGpScoreUneditable = (TextView)customView.findViewById(R.id.userGpScoreUneditable);
spinnerForGradePoints = (Spinner)customView.findViewById(R.id.spinnerForGradePointCgpa);
ArrayAdapter<String> gradePointAdapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_dropdown_item, TabFirstSemesterMyCGPA.userSubjectGrade);
spinnerForGradePoints.setAdapter(gradePointAdapter);
spinnerForGradePoints.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
String selectedItem = adapterView.getItemAtPosition(i).toString();
if (selectedItem.equals("A"))
{
Toast.makeText(getContext(), "You Clicked A", Toast.LENGTH_SHORT).show();
}else if ( selectedItem.equals("B"))
{
Toast.makeText(getContext(), "You Clicked B", Toast.LENGTH_SHORT).show();
}else if ( selectedItem.equals("C"))
{
Toast.makeText(getContext(), "You Clicked C", Toast.LENGTH_SHORT).show();
}else if ( selectedItem.equals("D"))
{
Toast.makeText(getContext(), "You Clicked D", Toast.LENGTH_SHORT).show();
}else if ( selectedItem.equals("E"))
{
Toast.makeText(getContext(), "You Clicked E", Toast.LENGTH_SHORT).show();
}else if ( selectedItem.equals("F"))
{
Toast.makeText(getContext(), "You Clicked F", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
singleText.setText(singleSubject);
colorLayout.setBackgroundColor(UserCourseSelection2.userSubjectsListColor.get(position));
return customView;
}
}
In pure Java you could save the state as a static field. The value will persist after the activity is destroyed because it belongs to the Class, not an instance. It should work the same in Android.
Related
I have created a checkbox that can only select one checkbox at a time. This works fine. my app requires the checkbox to remain checked at all times even when app is closed. What i want to know is how to get the checkbox and the data that is stored using this checkbox to save even if my app is closed . I have done some digging and seen that you can use a shared preference but I cant seem to work out how to implement it in my application. here is the code I am currently using to implement the checkbox: firebase recycler adapter
adapter1 = new FirebaseRecyclerAdapter<contact, contactAdapter>(options1) {
#Override
protected void onBindViewHolder(#NonNull final contactAdapter holder, final int position, #NonNull contact model) {
holder.contactName.setText(model.getContactName());
holder.contactPhone.setText(model.getContactPhone());
if(lastCheckedPos == position){
holder.chk.setChecked(true);
}
else{
holder.chk.setChecked(false);
}
holder.chk.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (position == lastCheckedPos) {
holder.chk.setChecked(false);
lastCheckedPos = -1;
}else {
lastCheckedPos = position;
for (int i = 0; i < adapter1.getItemCount(); i++) {
if (adapter1.getItem(i).isSelected(true)) {
number = ((TextView) holder.itemView.findViewById(R.id.contactPhone)).getText().toString();
Toast.makeText(getActivity(), "Data Inserted....." + number, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getActivity(), "Error", Toast.LENGTH_LONG).show();
}
}
contactsView.post(new Runnable()
{
#Override
public void run() {
adapter1.notifyDataSetChanged();
}
});
}
}
});
}
#NonNull
#Override
public contactAdapter onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new contactAdapter(LayoutInflater.from(getActivity()).inflate(R.layout.item_contacts, parent, false));
}
};
Adapter class
public class contactAdapter extends RecyclerView.ViewHolder{
public TextView contactName, contactPhone;
CheckBox chk;
AdapterView.OnItemClickListener itemClickListener;
public contactAdapter(#NonNull View itemView) {
super(itemView);
contactName = itemView.findViewById(R.id.contactName);
contactPhone = itemView.findViewById(R.id.contactPhone);
chk = itemView.findViewById(R.id.myCheckBox);
this.setIsRecyclable(false);
}
}
Any suggestions on how to keep check boxes saved even when my app is closed?
Try to save in shared prefrences the position of the clicked item and the state:
#Override
protected void onBindViewHolder(#NonNull final contactAdapter holder, final int position, #NonNull contact model) {
//setting the views
holder.contactName.setText(model.getContactName());
holder.contactPhone.setText(model.getContactPhone());
//check prefrences for the state of the check
SharedPreferences prefs = getSharedPreferences("check", MODE_PRIVATE);
String check_state = prefs.getString( "state", "default");
if(check_state.equals("true"+String.valueOf(position))){
holder.chk.setChecked(true);
}else if (check_state.equals("false"+String.valueOf(position))){
holder.chk.setChecked(false);
}else{
holder.chk.setChecked(false);
}
//on click save the state in preference
holder.chk.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
//checked
holder.chk.setChecked(true);
//save to prefrences
SharedPreferences.Editor editor = getSharedPreferences("check", MODE_PRIVATE).edit();
editor.putString("state", "true"+String.valueOf(position));
editor.apply();
adapter1.notifyDataSetChanged();
}else {
//unchecked
holder.chk.setChecked(false);
//save to prefrences
SharedPreferences.Editor editor = getSharedPreferences("check", MODE_PRIVATE).edit();
editor.putString("state", "false"+String.valueOf(position));
editor.apply();
adapter1.notifyDataSetChanged();
}
}
});
}
I am facing problem with my RadioButton in RecyclerView item. According to the 'type' I changes the checked RadioButton. But after all data loaded, then when I click the non checked radio button it's get checked. But after scrolling the checked radio button which I just clicked that goes unchecked. I want the button which I just clicked to be checked. But it is doesn't stays checked. How do I get what I want? Can anyone please help me!!!!!!!
This is my Adapter Class:
public class AttendanceAdapterLocal extends RecyclerView.Adapter<AttendanceAdapterLocal.ViewHolder>{
private ArrayList<StudentAttendance> attendanceArrayList;
private Context context;
public AttendanceAdapterLocal(ArrayList<StudentAttendance> attendanceArrayList) {
this.attendanceArrayList = attendanceArrayList;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_item_mark_attendance, viewGroup, false);
context = viewGroup.getContext();
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder viewHolder, int i) {
final String type = attendanceArrayList.get(i).getType();
final String id = attendanceArrayList.get(i).getId();
final String name = attendanceArrayList.get(i).getName();
final String roll = attendanceArrayList.get(i).getRoll();
viewHolder.setData(name, roll, type, id);
final DatabaseHelper databaseHelper = new DatabaseHelper(context);
final User user = new AccessStorage(context).getUserDetails();
final String userId = user.getUserId();
viewHolder.radioPresent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (databaseHelper.updateStudentAttendanceData(id, userId, "P", "0") > 0) {
Toast.makeText(context, "Marked successfully.", Toast.LENGTH_LONG).show();
viewHolder.radioPresent.setChecked(true);
} else {
Toast.makeText(context, "Unable to mark attendance.", Toast.LENGTH_LONG).show();
}
}
});
viewHolder.radioAbsent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (databaseHelper.updateStudentAttendanceData(id, userId, "A", "0") > 0) {
Toast.makeText(context, "Marked successfully.", Toast.LENGTH_LONG).show();
viewHolder.radioAbsent.setChecked(true);
} else {
Toast.makeText(context, "Unable to mark attendance.", Toast.LENGTH_LONG).show();
}
}
});
viewHolder.radioNone.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (databaseHelper.updateStudentAttendanceData(id, userId, "NA", "0") > 0) {
Toast.makeText(context, "Marked successfully.", Toast.LENGTH_LONG).show();
viewHolder.radioNone.setChecked(true);
} else {
Toast.makeText(context, "Unable to mark attendance.", Toast.LENGTH_LONG).show();
}
}
});
}
#Override
public int getItemCount() {
return attendanceArrayList.size();
}
#Override
public int getItemViewType(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
public class ViewHolder extends RecyclerView.ViewHolder {
// Widgets
private TextView textName;
private RadioGroup radioGroup;
private RadioButton radioPresent, radioAbsent, radioNone;
// Vars
private View view;
public ViewHolder(#NonNull View itemView) {
super(itemView);
view = itemView;
textName = view.findViewById(R.id.textName);
radioGroup = view.findViewById(R.id.radioGroup);
radioPresent = view.findViewById(R.id.radioPresent);
radioAbsent = view.findViewById(R.id.radioAbsent);
radioNone = view.findViewById(R.id.radioNone);
}
private void setData(String name, String roll, final String type, final String id) {
textName.setText(roll + ". " + name);
if (type.equals("P")) {
radioPresent.setChecked(true);
} else if(type.equals("A")) {
radioAbsent.setChecked(true);
}else if(type.equals("NA")) {
radioNone.setChecked(true);
}
}
}
}
Just a small mistake . In your onClick method , while changing the state just notify the adapter .
#Override
public void onClick(View v) {
if (databaseHelper.updateStudentAttendanceData(id, userId, "P", "0") > 0) {
Toast.makeText(context, "Marked successfully.", Toast.LENGTH_LONG).show();
viewHolder.radioPresent.setChecked(true);
//Notify adapter
attendanceArrayList.notify();
} else {
Toast.makeText(context, "Unable to mark attendance.", Toast.LENGTH_LONG).show();
}
}
I can see , everywhere you have done the same thing .Its important to notify the adapter while changing anything in the list . You either use notifyDataSetChanged() or notifyItemChanged(selectedPosition);
If you still face the problem you should create a Model class.
Use Interface on click of the radio buttons, make necessary changes in your original list that you are passing in recycler view(Inside Activity) then use notifiDataSetChanged() method.
How to get id From JSON in spinner ?
i want get city id, if i choose item in spinner
example : https://imgur.com/shvfvnO,
if i choose "ACEH BARAT", i'll get id "512"
public void displayCities(List<CityResponse.City> cities) {
for (CityResponse.City city : cities) {
Log.d(TAG, city.getNama());
spinnerItem.add(city.getNama());
adapter.notifyDataSetChanged();
}
}
private void setSpinner(Context context){
adapter = new ArrayAdapter<>(context, R.layout.spinner_item, spinnerItem);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mainBinding.spinnerCity.setAdapter(adapter);
mainBinding.spinnerCity.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String citySelected = parent.getItemAtPosition(position).toString();
Toast.makeText(context, "City : " + citySelected, Toast.LENGTH_LONG).show();
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
Toast.makeText(context, "Not Selected", Toast.LENGTH_LONG).show();
}
});
}
You need to create another arraylist to store id
locationId.add(i, response.getData());
now you need to get Id in spinner
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
try {
selectedId = (String) locationId.get(position);
} catch (Exception e) {
}
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
You need to update mainBinding.spinnerCity.setOnItemSelectedListener() inside setSpinnner() method as I have added below:
private void setSpinner(Context context){
adapter = new ArrayAdapter<>(context, R.layout.spinner_item, spinnerItem);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mainBinding.spinnerCity.setAdapter(adapter);
mainBinding.spinnerCity.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
//Comment by Hari: You have already position available here so why you are doing this..
//String citySelected = parent.getItemAtPosition(position).toString();
/*Comment by Hari: If CityModel is the model of your cities ArrayList then it can be received inside spinner from the same index position as of the item as you are creating spinnerItemList in loop and both the list item position will be synced. */
CityModel cityModel = cities.get(position);
String citySelected = cityModel.getCity(); //Where cities is the main array in your activity class.
String cityId = cityModel.getCityId();
Toast.makeText(context, "City Name: " + citySelected + " // City Id: cityId" + , Toast.LENGTH_LONG).show();
//Do what you want to do next with the cityId here....
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
Toast.makeText(context, "Not Selected", Toast.LENGTH_LONG).show();
}
});
}
Change your onItemSelected like this
mainBinding.spinnerCity.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String citySelected = parent.getItemAtPosition(position).toString();
for (CityResponse.City city : cities) {
if(city.getNama().equalsIgnoreCase(citySelected){
String city_id = city.getCityId(); //THIS IS YOUR CITY ID
}
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
Toast.makeText(context, "Not Selected", Toast.LENGTH_LONG).show();
}
});
I'm having a problem with this. I am using cursor adaptor. What my problem is when the checkbox is checked it will get the value and then when a button is clicked the data will be deleted. By the way I am displaying the checkbox with listview.
public class ListViewAdapter extends CursorAdapter {
SparseBooleanArray sba = new SparseBooleanArray();
public ListViewAdapter (Context context, Cursor c) {
super(context, c);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
// when the view will be created for first time,
// we need to tell the adapters, how each item will look
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View retView = inflater.inflate(R.layout.custom_dialog_box, parent, false);
ViewHolder holder = new ViewHolder();
holder.textView = (TextView) retView.findViewById(R.id.number);
holder.cb = (CheckBox) retView.findViewById(R.id.checkBox1);
retView.setTag(holder);
return retView;
}
private static class ViewHolder {
TextView textView;
CheckBox cb;
}
#Override
public void bindView(View view, final Context context, Cursor cursor) {
// here we are setting our data
// that means, take the data from the cursor and put it in views
final int position = cursor.getPosition();
final CheckBox CheckBoxPersonName = (CheckBox) view.findViewById(R.id.checkBox1);
CheckBoxPersonName.setTag(cursor);
CheckBoxPersonName.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked) {
sba.put(position, true);
}
else {
sba.put(position, false);
}
}
});
CheckBoxPersonName.setText(cursor.getString(cursor.getColumnIndex(cursor.getColumnName(1))));
TextView textViewPersonPIN = (TextView) view.findViewById(R.id.number);
textViewPersonPIN.setText(cursor.getString(cursor.getColumnIndex(cursor.getColumnName(2))));
}
}
Here is my mainActivity where the button will be clicked.
public class TemplateActivity extends Activity {
CheckBox cb;
Button btnSort, btnDel;
private ListViewAdapter listAdapter;
private RetailerDatabaseHelper dbHelper;
private ListView listView;
private static final String TAG = TemplateActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_template);
btnSort = (Button) findViewById(R.id.btnSort);
btnDel = (Button) findViewById(R.id.btnDelete);
dbHelper = new RetailerDatabaseHelper(this);
listView = (ListView) findViewById(R.id.listViewData);
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
System.out.println("Control: " + listView.getCheckedItemPositions());
Cursor c = (Cursor) parent.getAdapter().getItem(position);
String name = c.getString(1);
String number = c.getString(2);
AlertDialog.Builder alertDialog = new AlertDialog.Builder(TemplateActivity.this);
alertDialog.setTitle("RETAILER");
alertDialog.setMessage("Are you sure you want to send " + name + " load to " + number + " ?");
alertDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//insertData(textVal, value);
dialog.dismiss();
}
});
alertDialog.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alertDialog.show();
}
});
btnDel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int count = listView.getAdapter().getCount();
SparseBooleanArray array = listView.getCheckedItemPositions(); /* 11/07/15 */
System.out.println("Count: "+ count);
/* 11/07/15 */
for(int x = 0; x < array.size(); x++)
{
if(array.get(x)) /* 11/07/15 */
{
Log.d(TAG, "Checked: " + listView.getTag());
Toast.makeText(getApplicationContext(), "Success", Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(getApplicationContext(), "Failed", Toast.LENGTH_SHORT).show();
}
listAdapter.notifyDataSetChanged();
}
}
});
It is working but when the listview data is not clicked the checkbox value is not displaying.
You are declaring SparseBooleanArray as null here:
SparseBooleanArray array = null;
and no assignment to array.. and you are using it in for loop, then it will definitely give you null reference error.
This is a very basic issue.
It is that, I have a basic Spinner implemented with a listener as below:
Spinner sensModeSpinner = (Spinner) findViewById(R.id.SensorModeSpinner);
ArrayAdapter<CharSequence> sensModeAdapter = ArrayAdapter.createFromResource(this, R.array.sensorMode_array, android.R.layout.simple_spinner_item);
sensModeAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
sensModeSpinner.setAdapter(sensModeAdapter);
sensModeSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
sMode = parent.getItemAtPosition(pos).toString();
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
Toast.makeText(getBaseContext(), "You need to select atleast one mode!", Toast.LENGTH_SHORT).show();
}
});
Toast.makeText(getBaseContext(), "sensorMode = " + sMode, Toast.LENGTH_SHORT).show();
The issue is the sMode variable result is NOT appearing in the Toast message(value is NULL) where as it works fine within the OnItemSelected method.
Where am I going wrong?
you are executing the Toast.show(); method before the sMode value could be set, instead place this in onItemSelected() after setting sMode value, change your code to following:
Spinner sensModeSpinner = (Spinner) findViewById(R.id.SensorModeSpinner);
ArrayAdapter<CharSequence> sensModeAdapter = ArrayAdapter.createFromResource(this, R.array.sensorMode_array,
android.R.layout.simple_spinner_item);
sensModeAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
sensModeSpinner.setAdapter(sensModeAdapter);
sensModeSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent,
View view, int pos, long id) {
sMode = parent.getItemAtPosition(pos).toString();
Toast.makeText(getBaseContext(), "sensorMode = " + sMode, Toast.LENGTH_SHORT).show();
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
Toast.makeText(getBaseContext(),
"You need to select atleast one mode!",
Toast.LENGTH_SHORT).show();
}
});
You can do this
Spinner sensModeSpinner = (Spinner) findViewById(R.id.SensorModeSpinner);
ArrayAdapter<CharSequence> sensModeAdapter = ArrayAdapter.createFromResource(this, R.array.sensorMode_array, android.R.layout.simple_spinner_item);
sensModeAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
sensModeSpinner.setAdapter(sensModeAdapter);
sensModeSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
sMode = parent.getItemAtPosition(pos).toString();
//CALL_YOUR_FUNCTION_HERE
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
Toast.makeText(getBaseContext(), "You need to select atleast one mode!", Toast.LENGTH_SHORT).show();
}
});
some time may be it is silly mistake so try this..
#Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
// sMode = parent.getItemAtPosition(pos).toString();
sMode = parent.getAdapter().getItemAtPosition(pos).toString();
}