How to go through the items in a RecyclerView

0

I am developing an application where I use a RecyclerView to display a list of elements. Each item of this list is personalized, consisting of textview a spinner and% editText . The purpose is to update the data of the elements of that list in my database. The problem is that when I go through the list and try to update these data I take the update of the last modified iten, that is, what is selected in my spinner and editText in the other items. Let's see if someone can help me.

ConfiguraçãoObraSocial.java

public class ConfiguracionOS extends AppCompatActivity {

BaseDeDatos db;
RecyclerView osView;
LinearLayout cancelar, actualizar;
int contador;
Context context;
String nombre, est, cos;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_configuracion_os);
    context = ConfiguracionOS.this;

    db = new BaseDeDatos(context,null,null,1);
    osView = (RecyclerView) findViewById(R.id.configuracionOS);
    osView.setLayoutManager(new LinearLayoutManager(context));
    osView.setItemAnimator(new DefaultItemAnimator());
    ControladorObraSocial controlador = new ControladorObraSocial(context);
    final ConfiguracionOSAdapter adapter = new ConfiguracionOSAdapter(context, controlador.listaObraSocial());
    osView.setAdapter(adapter);


    cancelar = (LinearLayout) findViewById(R.id.btnVolverGestionarOS);
    actualizar = (LinearLayout) findViewById(R.id.btnActualizarEstadoOS);
    cancelar.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
        finish();
        }
        });

    actualizar.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ControladorObraSocial controlador = new ControladorObraSocial(context);

            contador = osView.getAdapter().getItemCount();

            for (int i=0; i < contador; i++ ) {
            nombre = adapter.nombre;
            cos = adapter.coseguro;
            est = adapter.estado;
            controlador.setDatos(nombre, est, cos);
            controlador.cargarDatos();
           }
           finish();
        }
    });
}
}

ControllerOS.java

public class ControladorObraSocial {

Context context;
public String est, cos, nom;


public ControladorObraSocial(Context c) {
    this.context = c;
}
 public void cargarDatos(){
    BaseDeDatos conn = new BaseDeDatos(context,null,null,1);
    ContentValues values = new ContentValues();
    values.put(Tablas.COLUMNA_ESTADO_OS, est);
    values.put(Tablas.COLUMNA_COSEGURO_OS, cos);
    SQLiteDatabase bd = conn.getWritableDatabase();
    String[] parametro = {nom};
    bd.update(Tablas.TABLA_OS, values, Tablas.COLUMNA_NOMBRE_OS + "= ?", parametro);
    bd.close();

}

public void setDatos(String nombre, String estado, String coseguro){
   nom = nombre;
   est = estado;
   cos = coseguro;

}

SettingsAdapter.java

public class ConfiguracionOSAdapter extends RecyclerView.Adapter<ConfiguracionOSHolder> implements Filterable {

Context c;
public ArrayList<ObraSocial> OS, listaFiltrada;
FiltroConfiguracionOS filtro;
public String  coseguro, estado, nombre;



public ConfiguracionOSAdapter(Context ctx, ArrayList<ObraSocial> OS){
    this.c=ctx;
    this.OS=OS;
    this.listaFiltrada=OS;


}


@Override
public ConfiguracionOSHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v= LayoutInflater.from(parent.getContext()).inflate(R.layout.item_configuracion_os,null);

    //HOLDER
    ConfiguracionOSHolder holder=new ConfiguracionOSHolder(v);
    return holder;


}

@Override
public void onBindViewHolder(final ConfiguracionOSHolder holder, int position) {
    holder.nombreOS.setText(OS.get(position).getNombre());
    holder.estado.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            estado = holder.estado.getSelectedItem().toString();
            nombre = holder.nombreOS.getText().toString();


            if (position == 1) {
                holder.coseguroOS.setEnabled(true);


            }else {
                holder.coseguroOS.setText("");
                holder.coseguroOS.setEnabled(false);

            }
            }
        @Override
        public void onNothingSelected(AdapterView<?> parent) {
        }
    });

    holder.coseguroOS.addTextChangedListener(new TextWatcher() {
        public void afterTextChanged(Editable s) {
            coseguro = holder.coseguroOS.getText().toString();

        }

        public void beforeTextChanged(CharSequence s, int start,
                                      int count, int after) {
        }
        public void onTextChanged(CharSequence s, int start,
                                  int before, int count) {
        }
    });
}


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

@Override
public Filter getFilter() {
    if (filtro==null){
        filtro = new FiltroConfiguracionOS(listaFiltrada, this);
    }
    return filtro;
}

}

ConfigurationsOSHolder

public class ConfiguracionOSHolder extends RecyclerView.ViewHolder {


public TextView nombreOS;
public Spinner estado;
public EditText coseguroOS;


public ConfiguracionOSHolder(View itemView) {
    super(itemView);
    this.nombreOS = (TextView) itemView.findViewById(R.id.NombreOS);
    this.estado = (Spinner) itemView.findViewById(R.id.spEstadosOS);
    this.coseguroOS = (EditText) itemView.findViewById(R.id.CoseguroOS);




}
}

    
asked by Germanccho 29.11.2017 в 14:58
source

1 answer

1

The problem is that you are storing the values of the items selected in variables ( coseguro , estado and nombre ) and each time you select a new item the value of that variable is updated. So in for what you do is get the same value of the same variables several times, which gives the illusion of only get the value of the last item, since the last value that you assign to the variables is the of the last item. So in your database you are updating the same value several times. It is something that you can easily verify if in the for you print the value of the variables with the statement Log.i() .

To solve your problem you must store the values of the variables in a list and then in for you go through the list and get the different values it contains, and you proceed to store them in your base of data.

SettingsAdapter

public class ConfiguracionOSAdapter extends RecyclerView.Adapter<ConfiguracionOSHolder> implements Filterable {

    ...

    public List<String> coseguro = new ArrayList<>(); 
    public List<String> estado = new ArrayList<>(); 
    public List<String> nombre = new ArrayList<>();

    ...

    @Override
    public void onBindViewHolder(final ConfiguracionOSHolder holder, int position) {

        final int posicionPadre = position;

        holder.nombreOS.setText(OS.get(position).getNombre());
        holder.estado.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

                // Si a a lista no se ha añadido ningún elemento, el método
                // remove() lanzara una exepcion y se saltara al catch, donde
                // se añadirán los primeros elementos a lista. Si a la lista
                // ya se le había agregado un elemento, se removerá el elemento
                // con el método remove() y se agregara uno nuevo en su posición. 
                try {
                    estado.remove(posicionPadre);
                    nombre.remove(posicisionPadre);
                    estado.add(posicionPadre, holder.estado.getSelectedItem().toString());
                    nombre.add(posicionPadre, holder.nombreOS.getText().toString());
                } catch (IndexOutOfBoundsException i) {
                    estado.add(posicionPadre, holder.estado.getSelectedItem().toString());
                    nombre.add(posicionPadre, holder.nombreOS.getText().toString());
                }

                if (position == 1) {
                    holder.coseguroOS.setEnabled(true);

                }else {
                    holder.coseguroOS.setText("");
                    holder.coseguroOS.setEnabled(false);
                }
            }

            ...
        });

        holder.coseguroOS.addTextChangedListener(new TextWatcher() {
            public void afterTextChanged(Editable s) {

                try {
                    coseguro.remove(posicionPadre);
                    coseguro.add(posicionPadre, holder.coseguroOS.getText().toString());
                } catch (IndexOutOfBoundsException i) {
                    coseguro.add(posicionPadre, holder.coseguroOS.getText().toString());
                }
            }

            ...
        });
    }

    ...
}

In your activity you get the values of the lists and store them in your database. But instead of going through the lists with the total number of items in recyclerView , it is better that you do it with the number of items in one of the lists, since the number of items in the list can be less than the number of items from the recyclerView. That will save you some mistakes.

ConfigurationsOS

public class ConfiguracionOS extends AppCompatActivity {

    ...

    String nombre, est, cos;


    @Override
    protected void onCreate(Bundle savedInstanceState) {

        ...

        actualizar.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ControladorObraSocial controlador = new ControladorObraSocial(context);

                // Obtienes el tamaño de la lista nombre. Este es el valor 
                // que utilizaras para recorrer todas las listas
                contador = osView.getAdapter().nombre.size();

                // Obtienes los valores de las listas y los almacenas en 
                // base de datos.
                for (int i=0; i < contador; i++ ) {
                nombre = adapter.nombre.get(i);
                cos = adapter.coseguro.get(i);
                est = adapter.estado.get(i);
                controlador.setDatos(nombre, est, cos);
                controlador.cargarDatos();
               }
               finish();
            }
        });
    }
}
    
answered by 29.11.2017 / 21:50
source