I have a recycler view which is just a list of rows. Each row contains two edit texts. I have a button that when clicked should add a new row underneath the last row and still keep all the EditTexts that have been filled out. For some reason I am getting some very random behaviour of where these rows are being added when my button is clicked.
Code below:
Adapter.class:
package b.calvin.com.evaccheck;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
public class PersonAdapter extends
RecyclerView.Adapter<PersonAdapter.PersonViewHolder>{
private Context mCtx;
private List<String> peopleNames;
private List<String> peoplePhones;
public PersonAdapter(Context mCtx, List<String> peopleNames, List<String> peoplePhones) {
this.mCtx = mCtx;
this.peopleNames = peopleNames;
this.peoplePhones = peoplePhones;
}
#Override
public PersonViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mCtx);
View view = inflater.inflate(R.layout.row_addpersonnew,null);
PersonViewHolder holder = new PersonViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(PersonViewHolder holder, int position) {
holder.personsName.setTag(R.id.personNameEditText, position);
String person = peopleNames.get(position);
if(!person.equals("HOLDER")){
holder.personsName.setText(peopleNames.get(position));
}
}
#Override
public int getItemCount() {
return peopleNames.size();
}
class PersonViewHolder extends RecyclerView.ViewHolder{
EditText personsName;
EditText personsContact;
public PersonViewHolder(View itemView) {
super(itemView);
personsName = itemView.findViewById(R.id.personNameEditText);
personsContact = itemView.findViewById(R.id.personPhoneNoEditText);
personsName.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void afterTextChanged(Editable editable) {
int position = (int) personsName.getTag(R.id.personNameEditText);
peopleNames.set(getAdapterPosition(),personsName.getText().toString());
System.out.println(peopleNames.get(getAdapterPosition()));
}
});
}
}
}
AddPeopleNewProcedureActivity.class:
package b.calvin.com.evaccheck;
public class AddPeopleNewProcedureActivity extends AppCompatActivity {
private FloatingActionButton fab;
private EditText personsNameET;
private EditText personsPhoneET;
private RecyclerView recyclerView;
private PersonAdapter personAdapter;
private List<String> peopleNames;
private List<String> peoplePhones;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.addpeoplenew_activity);
setupActivityReferences();
setupClickListeners();
}
private void setupClickListeners() {
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
peopleNames.add("HOLDER");
personAdapter.notifyDataSetChanged();
}
});
}
private void setupActivityReferences() {
fab = findViewById(R.id.fabAddPerson);
peopleNames = new ArrayList<String>();
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
peopleNames.add("HOLDER");
personAdapter = new PersonAdapter(this,peopleNames,peoplePhones);
recyclerView.setAdapter(personAdapter);
}
}
Related
Been working on this code for a while and as im new to recyclerList I can't seem to figure out why the button works only once.
Here is the adapter:
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class AdaptadorLista extends RecyclerView.Adapter<AdaptadorLista.ViewHolderLista> {
ArrayList<ComponentesLista> listaComponentes;
public AdaptadorLista(ArrayList<ComponentesLista> listaComponentes) {
this.listaComponentes = listaComponentes;
}
#NonNull
#Override
public ViewHolderLista onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list_lista, parent, false);
return new ViewHolderLista(view);
}
#Override
public void onBindViewHolder(ViewHolderLista holder, int position) {
holder.textViewDescripcion.setText(String.valueOf(listaComponentes.get(position).getDescripcion()));
holder.textViewDinero.setText(String.valueOf(listaComponentes.get(position).getDinero()));
holder.textViewCantidad.setText(String.valueOf(listaComponentes.get(position).getCantidad()));
}
#Override
public int getItemCount() {
return listaComponentes.size();
}
public class ViewHolderLista extends RecyclerView.ViewHolder {
private TextView textViewCantidad, textViewDescripcion, textViewDinero;
public ViewHolderLista(#NonNull View itemView) {
super(itemView);
textViewCantidad= (TextView) itemView.findViewById(R.id.textMuestraCantidad);
textViewDescripcion = (TextView) itemView.findViewById(R.id.textMuestraDescripcion);
textViewDinero = (TextView) itemView.findViewById(R.id.textMuestraPrecio);
}
}
}
Here is the object it works with:
public class ComponentesLista {
private String descripcion;
private String cantidad;
private String dinero;
public ComponentesLista() {
}
public ComponentesLista(String descripcion, String cantidad, String dinero) {
this.descripcion = descripcion;
this.cantidad = cantidad;
this.dinero = dinero;
}
public String getDescripcion() {
return descripcion;
}
public void setDescripcion(String descripcion) {
this.descripcion = descripcion;
}
public String getCantidad() {
return cantidad;
}
public void setCantidad(String cantidad) {
this.cantidad = cantidad;
}
public String getDinero() {
return dinero;
}
public void setDinero(String dinero) {
this.dinero = dinero;
}
}
And here is the main method (It's not the main method, it's another screen I use after a button press but it shouldn't be the issue right?)
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class PantallaLista extends AppCompatActivity {
ArrayList<ComponentesLista> componentesLista;
RecyclerView recyclerLista;
//int cont = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lista);
// Seccion ArrayList Lista
componentesLista=new ArrayList<>();
recyclerLista= (RecyclerView) findViewById(R.id.recyclerViewLista);
recyclerLista.setLayoutManager(new LinearLayoutManager(this));
// Botones
Button nuevo = (Button) findViewById(R.id.nuevoButton);
nuevo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
llenarLista();
}
});
Button guardarVolver = (Button) findViewById(R.id.terminarButton);
guardarVolver.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(PantallaLista.this, MainActivity.class);
startActivity(intent);
}
});
}
private void llenarLista () {
EditText textoGetDescripcion = (EditText) findViewById(R.id.textInputProducto);
EditText textoGetCantidad = (EditText) findViewById(R.id.textInputCantidad);
EditText textoGetPrecio = (EditText) findViewById(R.id.textInputPrecio);
componentesLista.add(new ComponentesLista(textoGetDescripcion.getText().toString(), textoGetPrecio.getText().toString(), textoGetCantidad.getText().toString()));
AdaptadorLista adapter = new AdaptadorLista(componentesLista);
recyclerLista.setAdapter(adapter);
//System.out.println(textoGetDescripcion.getText().toString() + textoGetPrecio.getText().toString() + textoGetPrecio.getText().toString());
}
}
You are setting an adapter every time you add the item to the list. Whenever you are adding a new item to the list, you've to use adapter.notifyItemInserted(position)
Here's the activiy
public class PantallaLista extends AppCompatActivity {
ArrayList<ComponentesLista> componentesLista;
RecyclerView recyclerLista;
AdaptadorLista adapter;
//int cont = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lista);
// Seccion ArrayList Lista
componentesLista=new ArrayList<>();
recyclerLista= (RecyclerView) findViewById(R.id.recyclerViewLista);
recyclerLista.setLayoutManager(new LinearLayoutManager(this));
adapter = new AdaptadorLista(componentesLista);
recyclerLista.setAdapter(adapter);
// Botones
Button nuevo = (Button) findViewById(R.id.nuevoButton);
nuevo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
llenarLista();
}
});
Button guardarVolver = (Button) findViewById(R.id.terminarButton);
guardarVolver.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(PantallaLista.this, MainActivity.class);
startActivity(intent);
}
});
}
private void llenarLista () {
EditText textoGetDescripcion = (EditText) findViewById(R.id.textInputProducto);
EditText textoGetCantidad = (EditText) findViewById(R.id.textInputCantidad);
EditText textoGetPrecio = (EditText) findViewById(R.id.textInputPrecio);
ComponentesLista tempData = new ComponentesLista(textoGetDescripcion.getText().toString(), textoGetPrecio.getText().toString(), textoGetCantidad.getText().toString())
adapter.addNewItems(tempData);
}
}
heres the adapter
public class AdaptadorLista extends RecyclerView.Adapter<AdaptadorLista.ViewHolderLista> {
ArrayList<ComponentesLista> listaComponentes;
public AdaptadorLista(ArrayList<ComponentesLista> listaComponentes) {
this.listaComponentes = listaComponentes;
}
public addNewItems(ComponentesLista tempComponent){
this.listaComponentes.add(tempComponent);
notifyDataSetChanged();
}
#NonNull
#Override
public ViewHolderLista onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list_lista, parent, false);
return new ViewHolderLista(view);
}
#Override
public void onBindViewHolder(ViewHolderLista holder, int position) {
holder.textViewDescripcion.setText(String.valueOf(listaComponentes.get(position).getDescripcion()));
holder.textViewDinero.setText(String.valueOf(listaComponentes.get(position).getDinero()));
holder.textViewCantidad.setText(String.valueOf(listaComponentes.get(position).getCantidad()));
}
#Override
public int getItemCount() {
return listaComponentes.size();
}
public class ViewHolderLista extends RecyclerView.ViewHolder {
private TextView textViewCantidad, textViewDescripcion, textViewDinero;
public ViewHolderLista(#NonNull View itemView) {
super(itemView);
textViewCantidad= (TextView) itemView.findViewById(R.id.textMuestraCantidad);
textViewDescripcion = (TextView) itemView.findViewById(R.id.textMuestraDescripcion);
textViewDinero = (TextView) itemView.findViewById(R.id.textMuestraPrecio);
}
}
}
please tell if you are not understanding something.
I want to add onClick to recyclerView to send data back to form Activity for update data process. How can I implement onItemClickListner when this code doesn't have adapter in it?
Show_Employees.java:
package com.example.roomdatabaseandroid;
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 android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import com.example.roomdatabaseandroid.DataModel.EmployeeDao;
import com.example.roomdatabaseandroid.DataModel.EmployeeDatabase;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
public class ShowEmployees extends AppCompatActivity {
private static final int EDIT_COURSE_REQUEST = 2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_employees);
RecyclerView recyclerView;
FloatingActionButton fab = findViewById(R.id.idFABAdd);
EmployeeDao employeeDao;
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//starting a new activity for adding a new course and passing a constant value in it.
Intent intent = new Intent(ShowEmployees.this, MainActivity.class);
startActivity(intent);
}
});
employeeDao = EmployeeDatabase.getDBInstance(this).employeeDao();
recyclerView = findViewById(R.id.employeeRecyclerView);
EmployeeRecycler employeeRecycler = new EmployeeRecycler(employeeDao.getAllEmployee());
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(employeeRecycler);
//below method is use to add swipe to delete method for item of recycler view.
new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | 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) {
//on recycler view item swiped then we are deleting the item of our recycler view.
employeeDao.deleteEmployee(employeeRecycler.data.get(viewHolder.getAdapterPosition()));
Toast.makeText(ShowEmployees.this, "Employee deleted", Toast.LENGTH_SHORT).show();
}
}).attachToRecyclerView(recyclerView);
}
}
Employee_Recycler.java:
package com.example.roomdatabaseandroid;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.roomdatabaseandroid.DataModel.DataConverter;
import com.example.roomdatabaseandroid.DataModel.Employee;
import java.util.List;
public class EmployeeRecycler extends RecyclerView.Adapter<EmployeeViewHolder> {
List<Employee> data;
public EmployeeRecycler(List<Employee> employees){
data = employees;
}
#NonNull
#Override
public EmployeeViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(
R.layout.list_item_1,
parent,false
);
return new EmployeeViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull EmployeeViewHolder holder, int position) {
Employee employee = data.get(position);
holder.imageView.setImageBitmap(DataConverter.convertByteArraytoImage(employee.getImage()));
holder.firstName.setText(employee.getFirstName());
holder.middleName.setText(employee.getMiddleName());
holder.lastName.setText(employee.getLastName());
holder.dob.setText(employee.getDOB());
holder.gender.setText(employee.getGender());
holder.address.setText(employee.getAddress());
holder.designation.setText(employee.getDesignation());
holder.email.setText(employee.getEmail());
holder.phoneNumber.setText(employee.getPhoneNumber());
}
#Override
public int getItemCount() {
return data.size();
}
}
EmployeeViewHolder.java:
package com.example.roomdatabaseandroid;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
public class EmployeeViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
TextView firstName,middleName,lastName,email,phoneNumber,address,designation,gender,dob;
public EmployeeViewHolder(#NonNull View itemView) {
super(itemView);
firstName = itemView.findViewById(R.id.idTVFirstName);
middleName = itemView.findViewById(R.id.idTVMiddleName);
lastName = itemView.findViewById(R.id.idTVLastName);
dob = itemView.findViewById(R.id.idTVDOB);
address = itemView.findViewById(R.id.idTVAddress);
gender = itemView.findViewById(R.id.idTVGender);
designation = itemView.findViewById(R.id.idTVDesignation);
email = itemView.findViewById(R.id.idTVEmail);
phoneNumber = itemView.findViewById(R.id.idTVPhoneNumber);
imageView = itemView.findViewById(R.id.profileImageView);
}
}
add an interface
interface AdapterItemClickListener {
void onItemClickListener(Employee employee, int position)
}
your actvity must implement this interface
public class ShowEmployees extends AppCompatActivity implements AdapterItemClickListener {
private static final int EDIT_COURSE_REQUEST = 2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_employees);
RecyclerView recyclerView;
FloatingActionButton fab = findViewById(R.id.idFABAdd);
EmployeeDao employeeDao;
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//starting a new activity for adding a new course and passing a constant value in it.
Intent intent = new Intent(ShowEmployees.this, MainActivity.class);
startActivity(intent);
}
});
employeeDao = EmployeeDatabase.getDBInstance(this).employeeDao();
recyclerView = findViewById(R.id.employeeRecyclerView);
EmployeeRecycler employeeRecycler = new EmployeeRecycler(employeeDao.getAllEmployee(), this);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(employeeRecycler);
//below method is use to add swipe to delete method for item of recycler view.
new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | 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) {
//on recycler view item swiped then we are deleting the item of our recycler view.
employeeDao.deleteEmployee(employeeRecycler.data.get(viewHolder.getAdapterPosition()));
Toast.makeText(ShowEmployees.this, "Employee deleted", Toast.LENGTH_SHORT).show();
}
}).attachToRecyclerView(recyclerView);
}
void onItemClickListener(Employee employee, int position) {
//update or another job
}
}
and your adapter
public class EmployeeRecycler extends RecyclerView.Adapter<EmployeeViewHolder> {
List<Employee> data;
AdapterItemClickListener itemClickListener;
public EmployeeRecycler(List<Employee> employees, AdapterItemClickListener itemClickListener){
data = employees;
this.itemClickListener = itemClickListener;
}
#NonNull
#Override
public EmployeeViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(
R.layout.list_item_1,
parent,false
);
return new EmployeeViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull EmployeeViewHolder holder, int position) {
Employee employee = data.get(position);
holder.imageView.setImageBitmap(DataConverter.convertByteArraytoImage(employee.getImage()));
holder.firstName.setText(employee.getFirstName());
holder.middleName.setText(employee.getMiddleName());
holder.lastName.setText(employee.getLastName());
holder.dob.setText(employee.getDOB());
holder.gender.setText(employee.getGender());
holder.address.setText(employee.getAddress());
holder.designation.setText(employee.getDesignation());
holder.email.setText(employee.getEmail());
holder.phoneNumber.setText(employee.getPhoneNumber());
holder.itemView.setOnClickListener (v -> {
itemClickListener.onItemClickListener(employee, position);
});
}
#Override
public int getItemCount() {
return data.size();
}
}
I am trying to create a note-taking app focusing on color-changing.
In one of the activity, I am trying to implement item addition and deletion to the note
picture_of_the_activity.
Item addition obviously works as intended.
The problem is with the deletion, it is very inconsistent: when I delete all the item starting from the last one upward, everything work fine; if I delete items in another order the adapter mess up, do not always delete the correct one and crashes when removing the last item.
I looked it up and found some possible solution (here or in other websites) but couldn't find a solution, or, so I thought.
I created methods inside the adapter addItem() and removeItem() so any changes is done within the class.
Maybe I am misunderstanding a concept or missing something?
Thank you in advance!
some interfaces or protion of the code are missing because I didn't implement some features yet
Activity Code
package com.example.colornoteplus;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Objects;
public class CheckListNoteActivity extends AppCompatActivity{
// note editable views
private EditText titleView;
private TextView titleCharacterCount;
private ImageButton colorView;
private RecyclerView contentView;
private FloatingActionButton fab;
CheckListAdapter adapter;
// toolbar
private Toolbar toolbar;
// Current note
private CheckListNote note;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getNoteFromIntent();
note.getContent().add(new CheckListItem("ONE"));
note.getContent().add(new CheckListItem("TWO"));
note.getContent().add(new CheckListItem("THREE"));
note.getContent().add(new CheckListItem("FOUR"));
note.getContent().add(new CheckListItem("FIVE"));
changeViewsColor(0);
}
// Method used to add menus and configure button action
// like OnClickListeners ...
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Create a submenu for sorting purpose
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_check_list_activity,menu);
return super.onCreateOptionsMenu(menu);
}
// get note from the intent
private void getNoteFromIntent(){
if (!getIntent().getStringExtra(Statics.KEY_NOTE_ACTIVITY).equals(Statics.NOTE_DEFAULT_UID)){
note = MySharedPreferences.LoadCheckListNoteFromSharedPreferences(getIntent().getStringExtra(Statics.KEY_NOTE_ACTIVITY),getApplicationContext());
} else {
note = new CheckListNote();
}
}
private void changeViewsColor(int color){
// set the global theme
setTheme(StyleManager.getTheme(color));
// set the appropriate layout
setContentView(R.layout.activity_check_list_note);
// change status bar color
getWindow().setStatusBarColor(getResources().getColor(StyleManager.getThemeColor(color)));
// set up FAB action
fab = findViewById(R.id.fab_add_item);
fab.setOnClickListener(view -> onFabClickListener());
// setting the toolbar
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.setBackgroundColor(getResources().getColor(StyleManager.getThemeColor(color)));
Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
// setting the note title
titleView = findViewById(R.id.note_title_view);
titleView.setText("");
titleView.setTextColor(getResources().getColor(StyleManager.getThemeColorDark(color)));
titleView.setHintTextColor(getResources().getColor(StyleManager.getThemeColorLight(color)));
// setting the character counter for the note title
titleCharacterCount = findViewById(R.id.note_title_characters);
String m = titleView.getText().toString().trim().length()+ getString(R.string.text_divider)+ getResources().getInteger(R.integer.title_max_length);
titleCharacterCount.setText(m);
titleCharacterCount.setTextColor(getResources().getColor(StyleManager.getThemeColor(color)));
titleView.addTextChangedListener(new TextWatcher()
{
#Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int aft)
{
}
#Override
public void afterTextChanged(Editable s)
{
// this will show characters remaining
String msg = titleView.getText().toString().length()+ getString(R.string.text_divider)+ getResources().getInteger(R.integer.title_max_length);
titleCharacterCount.setText(msg);
}
});
// setting the color view
colorView = findViewById(R.id.note_color_view);
colorView.setOnClickListener(view -> buildColorPickDialog());
colorView.setBackgroundResource(StyleManager.getBackground(color));
adapter = new CheckListAdapter(getApplicationContext(),note.getContent(),color);
adapter.setOnItemClickListener(new CheckListAdapter.OnItemClickListener() {
#Override
public void onChecked(int position) {
Toast.makeText(CheckListNoteActivity.this, "Checked item: " +position, Toast.LENGTH_SHORT).show();
}
#Override
public void onUnchecked(int position) {
Toast.makeText(CheckListNoteActivity.this, "Unchecked item: " +position, Toast.LENGTH_SHORT).show();
}
#Override
public void onSetPriority(int position) {
}
#Override
public void onSetReminder(int position) {
}
#Override
public void onDelete(int position) {
adapter.removeItem(position);
Toast.makeText(CheckListNoteActivity.this, "List has "+note.getContent().size()+" elements", Toast.LENGTH_SHORT).show();
}
});
contentView = findViewById(R.id.note_content_view);
contentView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
contentView.setAdapter(adapter);
}
private void switchColor(int color){
String tempTitle = titleView.getText().toString().trim();
changeViewsColor(color);
titleView.setText(tempTitle);
}
// build the color picker dialog
private void buildColorPickDialog(){
FragmentPickColor fragment = new FragmentPickColor(new ColorAdapter(),5,note.getColor());
fragment.show(getSupportFragmentManager(),Statics.TAG_FRAGMENT_COLOR_PICK);
fragment.setOnItemClickListener(new ColorAdapter.OnItemClickListener() {
#Override
public void OnClickListener(int position) {
note.setColor(position);
switchColor(position);
fragment.dismiss();
}
#Override
public void OnLongClickListener(int position) {
}
});
}
private void onFabClickListener(){
FragmentAddCheckListItem fragment = new FragmentAddCheckListItem(note.getColor());
fragment.show(getSupportFragmentManager(),Statics.TAG_FRAGMENT_ADD_CHECK_LIST_ITEM);
fragment.setOnClickListener(new FragmentAddCheckListItem.OnClickListener() {
#Override
public void onConfirmClickListener() {
fragment.getItem().setDescription(fragment.getInputText());
adapter.addItem(fragment.getItem(),0);
fragment.dismiss();
}
#Override
public void onSetPriorityClickListener() {
}
#Override
public void onSetDueTimeClickListener() {
FragmentDatePicker datePicker = new FragmentDatePicker();
datePicker.show(getSupportFragmentManager(),Statics.TAG_FRAGMENT_DATE_PICKER);
datePicker.setOnDateSet((year, month, day) -> {
Calendar c = Calendar.getInstance();
c.set(Calendar.YEAR,year);
c.set(Calendar.MONTH,month);
c.set(Calendar.DAY_OF_MONTH,day);
fragment.getItem().setDueDate(c.getTime().getTime());
fragment.setDueTimeText(DateFormat.getDateInstance().format(new Date(fragment.getItem().getDueDate())));
});
}
});
}
}
Adapter
package com.example.colornoteplus;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.recyclerview.widget.RecyclerView;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
public class CheckListAdapter extends RecyclerView.Adapter<CheckListAdapter.MyViewHolder> {
public CheckListAdapter(Context context,ArrayList<CheckListItem> list, int color) {
this.list = list;
this.color = color;
this.context = context;
}
final private ArrayList<CheckListItem> list;
final private int color;
final private Context context;
private OnItemClickListener listener;
#NonNull
#Override
public CheckListAdapter.MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new CheckListAdapter.MyViewHolder(LayoutInflater.
from(parent.getContext()).
inflate(R.layout.item_check_list,parent,false));
}
#Override
public void onBindViewHolder(#NonNull CheckListAdapter.MyViewHolder holder, int position) {
CheckListItem currentItem = list.get(position);
holder.background.setBackgroundResource(StyleManager.getBackgroundLight(color));
holder.checkBox.setOnCheckedChangeListener((compoundButton, b) -> {
if (b) listener.onChecked(position);
else listener.onUnchecked(position);
});
holder.title.setTextColor(context.getResources().getColor(StyleManager.getThemeColorDark(color)));
holder.title.setHintTextColor(context.getResources().getColor(StyleManager.getThemeColor(color)));
assert currentItem != null;
holder.title.setText(currentItem.getDescription().trim());
holder.dueTimeText.setTextColor(context.getResources().getColor(StyleManager.getThemeColor(color)));
holder.dueTimeText.setText(currentItem.getDoneDate() != -1 ? DateFormat.getDateInstance().format(new Date(currentItem.getDueDate())) : context.getString(R.string.set_reminder));
holder.dueTimeText.setOnClickListener(view -> listener.onSetReminder(position));
holder.priorityText.setTextColor(context.getResources().getColor(StyleManager.getThemeColor(color)));
holder.priorityText.setText(currentItem.priorityToString(context));
holder.priorityText.setOnClickListener(view -> listener.onSetPriority(position));
holder.delete.setBackgroundResource(StyleManager.getBackground(color));
holder.delete.setOnClickListener(view -> {
// listener.onDelete(position);
removeItem(position);
});
}
#Override
public int getItemCount() {
return list.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder{
CheckBox checkBox;
ConstraintLayout background;
EditText title;
ImageButton delete;
TextView priorityText,dueTimeText;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
checkBox = itemView.findViewById(R.id.item_check_box);
title = itemView.findViewById(R.id.item_title);
dueTimeText = itemView.findViewById(R.id.item_due_time_text);
priorityText = itemView.findViewById(R.id.item_priority_text);
delete = itemView.findViewById(R.id.item_delete);
background = itemView.findViewById(R.id.item_background);
}
}
public void addItem(CheckListItem item,int position){
if (position < 0){
list.add(item);
notifyItemInserted(list.size()-1);
}
else {
list.add(position,item);
notifyItemInserted(position);
}
}
public void removeItem(int position){
list.remove(position);
notifyItemRemoved(position);
}
public void setOnItemClickListener(OnItemClickListener listener){
this.listener = listener;
}
public interface OnItemClickListener{
void onChecked(int position);
void onUnchecked(int position);
void onSetPriority(int position);
void onSetReminder(int position);
void onDelete(int position);
}
}
public void addItem(CheckListItem item, int position) {
if (position >= 0) {
list.add(position, item);
notifyItemInserted(position);
}
}
public void removeItem(int position) {
if (position >= 0) {
list.remove(position);
notifyItemRemoved(position);
}
}
And in onBindViewHolder use holder.getAdapterPosition() instead of position in your listeners like this:
holder.delete.setOnClickListener(view -> {
// listener.onDelete(position);
removeItem(holder.getAdapterPosition());
});
I am trying to send the user to another activity when he clicks on the picture inside the recycle view after gathering the position, the problem whatever I do i still gitting null on the Adapter when using context, please find the codes below and describe to me what is the thing that I missed ?!
the problem is in the codes of onclick method ( last one ):-
package com.example.boc.Teachers;
import androidx.appcompat.app.AppCompatActivity;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.example.boc.R;
import com.example.boc.main.DashboardActivity;
import java.util.ArrayList;
public class TeachersAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private LayoutInflater mInflater;
private ArrayList<TeachersModel> items;
private TeacherMain mActivity;
private Context context;
public TeachersAdapter(ArrayList<TeachersModel> data, TeacherMain activity) {
this.items = data;
this.mActivity = activity;
this.mInflater = LayoutInflater.from(mActivity);
}
public void addItem(TeachersModel result) {
items.add(result);
}
public TeachersAdapter(Context context) {
this.context = context;
}
public void setInflater(LayoutInflater layoutInflater){
this.mInflater =layoutInflater;
}
public void replaceItems(ArrayList<TeachersModel> newItems) {
this.items.clear();
for(TeachersModel item: newItems)
this.items.add(item);
}
public void insertItem(TeachersModel item) {
items.add(0, item);
}
public void clearItems(){
items.clear();
}
public void AddResults(ArrayList<TeachersModel> result) {
items.addAll(result);
}
public TeachersModel getItemsAt(int position){
return items.get(position);
}
#Override
public int getItemCount() {
return items.size();
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
TeachersModel model = items.get(position);
MessageViewHolder messageViewHolder = (MessageViewHolder) holder;
messageViewHolder.imageViewIcon.setBackgroundResource(model.getImage());
messageViewHolder.textViewName.setText(model.getName());
messageViewHolder.textViewStatus.setText(model.getStatus());
messageViewHolder.textViewMobile.setText(model.getMobile());
}
#Override
public int getItemViewType(int position) {
return super.getItemViewType(position);
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View rootCategoryView = mInflater.inflate(R.layout.row_item_teachers, parent, false);
return new MessageViewHolder(rootCategoryView, this);
}
private class MessageViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private ImageView imageViewIcon;
private TextView textViewName;
private TextView textViewStatus;
private TextView textViewMobile;
private CardView cardView;
private MessageViewHolder(View itemView, TeachersAdapter adapter) {
super(itemView);
imageViewIcon = (ImageView) itemView.findViewById(R.id.imageViewIcon);
textViewName = (TextView) itemView.findViewById(R.id.textViewName);
textViewStatus = (TextView) itemView.findViewById(R.id.textViewStatus);
textViewMobile = (TextView) itemView.findViewById(R.id.textViewMobile);
cardView = (CardView) itemView.findViewById(R.id.cardView);
cardView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
final int pos = getAdapterPosition();
if (pos == 0) {
imageViewIcon.setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent( context, DashboardActivity.class );
context.startActivity( intent );
}
} );
Toast.makeText(mActivity, "Selected Item Position "+pos, Toast.LENGTH_SHORT).show();
}
}
}
}
I am assuming you are using the constrcutor without passing a context:
//update the constructor to take a context
public TeachersAdapter(ArrayList<TeachersModel> data, TeacherMain activity , Context context) {
this.items = data;
this.mActivity = activity;
this.mInflater = LayoutInflater.from(mActivity);
//add this
this.context = context;
}
Set the click listener in onBindViewHolder:
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
....
....
....
messageViewHolder.imageViewIcon.setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context, DashboardActivity.class );
context.startActivity(intent);
}
});
}
When you create the adapter in your activity, make sure to pass the correct context:
adapter = new TeachersAdapter(... , .... , getApplicationContext());
I want to change the list contents in a bottom sheet view though click event, but I only got empty sheet. Here is a demo modified from BottomSheetSample(github.com/niravkalola/BottomSheetSample).
mainActivity.java
package com.nkdroid.bottomsheetsample;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomSheetBehavior;
import android.support.design.widget.BottomSheetDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Button;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class MainActivity extends AppCompatActivity implements ItemAdapter.ItemListener {
private Button btnView, btnDialog;
BottomSheetBehavior behavior;
private BottomSheetDialog mBottomSheetDialog;
private ItemAdapter mAdapter;
RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnView = (Button) findViewById(R.id.btnView);
btnDialog = (Button) findViewById(R.id.btnDialog);
btnView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mAdapter = new ItemAdapter(createItems());
recyclerView.setAdapter(mAdapter);
behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}
});
btnDialog.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showBottomSheetDialog();
}
});
View bottomSheet = findViewById(R.id.bottom_sheet);
behavior = BottomSheetBehavior.from(bottomSheet);
behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
#Override
public void onStateChanged(#NonNull View bottomSheet, int newState) {
// React to state change
}
#Override
public void onSlide(#NonNull View bottomSheet, float slideOffset) {
// React to dragging events
}
});
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
mAdapter = new ItemAdapter(createItems(), this);
recyclerView.setAdapter(mAdapter);
}
private void showBottomSheetDialog() {
if (behavior.getState() == BottomSheetBehavior.STATE_EXPANDED) {
behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
mBottomSheetDialog = new BottomSheetDialog(this);
View view = getLayoutInflater().inflate(R.layout.sheet, null);
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(new ItemAdapter(createItems(), new ItemAdapter.ItemListener() {
#Override
public void onItemClick(Item item) {
if (mBottomSheetDialog != null) {
mBottomSheetDialog.dismiss();
}
}
}));
mBottomSheetDialog.setContentView(view);
mBottomSheetDialog.show();
mBottomSheetDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
mBottomSheetDialog = null;
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
mAdapter.setListener(null);
}
public List<Item> createItems() {
Random r = new Random();
ArrayList<Item> items = new ArrayList<>();
items.add(new Item(R.mipmap.ic_launcher, "Item 1"+ r.nextInt(100)));
items.add(new Item(R.mipmap.ic_launcher, "Item 2"));
items.add(new Item(R.mipmap.ic_launcher, "Item 3"));
items.add(new Item(R.mipmap.ic_launcher, "Item 4"));
return items;
}
#Override
public void onItemClick(Item item) {
behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
}
ItemAdapter.java:
package com.nkdroid.bottomsheetsample;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.ViewHolder> {
private List<Item> mItems;
private ItemListener mListener;
public ItemAdapter(List<Item> items, ItemListener listener) {
mItems = items;
mListener = listener;
}
public ItemAdapter(List<Item> items) {
mItems = items;
}
public void setListener(ItemListener listener) {
mListener = listener;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.adapter, parent, false));
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.setData(mItems.get(position));
}
#Override
public int getItemCount() {
return mItems.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public ImageView imageView;
public TextView textView;
public Item item;
public ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
imageView = (ImageView) itemView.findViewById(R.id.imageView);
textView = (TextView) itemView.findViewById(R.id.textView);
}
public void setData(Item item) {
this.item = item;
imageView.setImageResource(item.getDrawableResource());
textView.setText(item.getTitle());
}
#Override
public void onClick(View v) {
if (mListener != null) {
mListener.onItemClick(item);
}
}
}
public interface ItemListener {
void onItemClick(Item item);
}
}
Here are the capture after click show view button for the first and second time:
first click
second click
This is fixed in 24.0.0 i.e. the recyclerView gets updated. But if you are using wrap_content on the bottomsheet as well as recyclerview you will have to use this so that the bottomsheet height is calculated properly.
bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
#Override
public void onStateChanged(#NonNull View bottomSheet, int newState) {
if(newState==BottomSheetBehavior.STATE_EXPANDED){
bottomSheet.requestLayout();
/*or
recyclerView.scrollToPosition(0);
recyclerView.requestLayout();*/
}
}
#Override
public void onSlide(#NonNull View bottomSheet, float slideOffset) {
}
});
If you want to work with earlier versions use
bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
#Override
public void onStateChanged(#NonNull View bottomSheet, int newState) {
if(newState==BottomSheetBehavior.STATE_EXPANDED){
bottomSheet.requestLayout();
bottomSheet.invalidate();
}
}
#Override
public void onSlide(#NonNull View bottomSheet, float slideOffset) {
}
});