I have my RecyclerView that gets the data from my MySQL database through json. The fact is that when I run the app and it gets the remote data, I want it to be ordered by date taking advantage of the box in which I have the date.
I need the elements that have a more recent date to be first and the ones from the oldest date to be the last ones.
Thank you.
Here I put the code:
Meta class definition:
public class Meta {
private static final String TAG = Meta.class.getSimpleName();
/*
Atributos
*/
private String idMeta;
private String titulo;
private String descripcion;
private String prioridad;
private String fechaLim;
private String categoria;
public Meta(String idMeta,
String titulo,
String descripcion,
String fechaLim,
String categoria,
String prioridad) {
this.idMeta = idMeta;
this.titulo = titulo;
this.descripcion = descripcion;
this.prioridad = prioridad;
this.fechaLim = fechaLim;
this.categoria = categoria;
}
public String getIdMeta() {
return idMeta;
}
public String getTitulo() {
return titulo;
}
public String getDescripcion() {
return descripcion;
}
public String getPrioridad() {
return prioridad;
}
public String getFechaLim() {
return fechaLim;
}
public String getCategoria() {
return categoria;
}
/**
* Compara los atributos de dos metas
*
* @param meta Meta externa
* @return true si son iguales, false si hay cambios
*/
public boolean compararCon(Meta meta) {
return this.titulo.compareTo(meta.titulo) == 0 &&
this.descripcion.compareTo(meta.descripcion) == 0 &&
this.fechaLim.compareTo(meta.fechaLim) == 0 &&
this.categoria.compareTo(meta.categoria) == 0 &&
this.prioridad.compareTo(meta.prioridad) == 0;
}
}
MetaAdapter:
/**
* Adaptador del recycler view
*/
public class MetaAdapter extends RecyclerView.Adapter<MetaAdapter.MetaViewHolder>
implements ItemClickListener {
/**
* Lista de objetos {@link Meta} que representan la fuente de datos
* de inflado
*/
private List<Meta> items;
/*
Contexto donde actua el recycler view
*/
private Context context;
public MetaAdapter(List<Meta> items, Context context) {
this.context = context;
this.items = items;
}
@Override
public int getItemCount() {
return items.size();
}
@Override
public MetaViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.item_list, viewGroup, false);
return new MetaViewHolder(v, this);
}
@Override
public void onBindViewHolder(MetaViewHolder viewHolder, int i) {
viewHolder.titulo.setText(items.get(i).getTitulo());
viewHolder.prioridad.setText(items.get(i).getPrioridad());
viewHolder.fechaLim.setText(items.get(i).getFechaLim());
viewHolder.categoria.setText(items.get(i).getCategoria());
}
/**
* Sobrescritura del método de la interfaz {@link ItemClickListener}
*
* @param view item actual
* @param position posición del item actual
*/
@Override
public void onItemClick(View view, int position) {
DetailActivity.launch(
(Activity) context, items.get(position).getIdMeta());
}
public static class MetaViewHolder extends RecyclerView.ViewHolder
implements View.OnClickListener {
// Campos respectivos de un item
public TextView titulo;
public TextView prioridad;
public TextView fechaLim;
public TextView categoria;
public ItemClickListener listener;
public MetaViewHolder(View v, ItemClickListener listener) {
super(v);
titulo = (TextView) v.findViewById(R.id.titulo);
prioridad = (TextView) v.findViewById(R.id.prioridad);
fechaLim = (TextView) v.findViewById(R.id.fecha);
categoria = (TextView) v.findViewById(R.id.categoria);
this.listener = listener;
v.setOnClickListener(this);
}
@Override
public void onClick(View v) {
listener.onItemClick(v, getAdapterPosition());
}
}
}
interface ItemClickListener {
void onItemClick(View view, int position);
}
Where the RecyclerView list is loaded:
public class MainFragment extends Fragment {
...
/*
Adaptador del recycler view
*/
private MetaAdapter adapter;
/*
Instancia global del recycler view
*/
private RecyclerView lista;
...
/**
* Interpreta los resultados de la respuesta y así
* realizar las operaciones correspondientes
*
* @param response Objeto Json con la respuesta
*/
private void procesarRespuesta(JSONObject response) {
try {
// Obtener atributo "estado"
String estado = response.getString("estado");
switch (estado) {
case "1": // EXITO
// Obtener array "metas" Json
JSONArray mensaje = response.getJSONArray("metas");
// Parsear con Gson
Meta[] metas = gson.fromJson(mensaje.toString(), Meta[].class);
// Inicializar adaptador
adapter = new MetaAdapter(Arrays.asList(metas), getActivity());
// Setear adaptador a la lista
lista.setAdapter(adapter);
break;
case "2": // FALLIDO
String mensaje2 = response.getString("mensaje");
Toast.makeText(
getActivity(),
mensaje2,
Toast.LENGTH_LONG).show();
break;
}
} catch (JSONException e) {
Log.d(TAG, e.getMessage());
}
}
}
I have ordered it but I need to sort by date
// Obtener array "metas" Json
JSONArray mensaje = response.getJSONArray("metas");
// Parsear con Gson
Meta[] metas = gson.fromJson(mensaje.toString(), Meta[].class);
// APLICACIÓN DE ORDEN:
// Ordenar el array de metas por idMeta de forma descendente:
Arrays.sort(metas, new Comparator<Meta>() {
@Override
public int compare(meta objeto1, meta objeto2) {
int result;
// Comparamos por idMeta, de forma descendente:
result = objeto2.idMeta.compareTo(objeto1.idMeta);
/*
// Comparamos por fechaLim de forma descendente:
result = objeto2.fechaLim.compareTo(objeto1.fechaLim);
*/
return result;
}
});
// Fin del ordenamiento.
// Inicializar adaptador
adapter = new MetaAdapter(Arrays.asList(metas), getActivity());
// Setear adaptador a la lista
lista.setAdapter(adapter);
I think this is what you mean
/**
* Fragmento con formulario para actualizar la meta
*/
public class UpdateFragment extends Fragment {
/*
Etiqueta de depuración
*/
private static final String TAG = UpdateFragment.class.getSimpleName();
/*
Controles
*/
private EditText titulo_input;
private EditText descripcion_input;
private Spinner prioridad_spinner;
private TextView fecha_text;
private Spinner categoria_spinner;
/*
Valor del argumento extra
*/
private String idMeta;
/**
* Es la meta obtenida como respuesta de la petición HTTP
*/
private Meta metaOriginal;
/**
* Instancia Gson para el parsing Json
*/
private Gson gson = new Gson();
public UpdateFragment() {
}
/**
* Crea un nuevo fragmento basado en un argumento
*
* @param extra Argumento de entrada
* @return Nuevo fragmento
*/
public static Fragment createInstance(String extra) {
UpdateFragment detailFragment = new UpdateFragment();
Bundle bundle = new Bundle();
bundle.putString(Constantes.EXTRA_ID, extra);
detailFragment.setArguments(bundle);
return detailFragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflando layout del fragmento
View v = inflater.inflate(R.layout.fragment_form, container, false);
// Obtención de instancias controles
titulo_input = (EditText) v.findViewById(R.id.titulo_input);
descripcion_input = (EditText) v.findViewById(R.id.descripcion_input);
fecha_text = (TextView) v.findViewById(R.id.fecha_ejemplo_text);
categoria_spinner = (Spinner) v.findViewById(R.id.categoria_spinner);
prioridad_spinner = (Spinner) v.findViewById(R.id.prioridad_spinner);
fecha_text.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
DialogFragment picker = new DatePickerFragment();
picker.show(getFragmentManager(), "datePicker");
}
}
);
// Obtener valor extra
idMeta = getArguments().getString(Constantes.EXTRA_ID);
if (idMeta != null) {
cargarDatos();
}
return v;
}
/**
* Obtiene los datos desde el servidor
*/
private void cargarDatos() {
// Añadiendo idMeta como parámetro a la URL
String newURL = Constantes.GET_BY_ID + "?idMeta=" + idMeta;
// Consultar el detalle de la meta
VolleySingleton.getInstance(getActivity()).addToRequestQueue(
new JsonObjectRequest(
Request.Method.GET,
newURL,
null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
// Procesa la respuesta GET_BY_ID
procesarRespuestaGet(response);
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, "Error Volley: " + error.getMessage());
}
}
)
);
}
/**
* Procesa la respuesta de obtención obtenida desde el sevidor *
*/
private void procesarRespuestaGet(JSONObject response) {
try {
String estado = response.getString("estado");
switch (estado) {
case "1":
JSONObject meta = response.getJSONObject("meta");
// Guardar instancia
metaOriginal = gson.fromJson(meta.toString(), Meta.class);
// Setear valores de la meta
cargarViews(metaOriginal);
break;
case "2":
String mensaje = response.getString("mensaje");
// Mostrar mensaje
Toast.makeText(
getActivity(),
mensaje,
Toast.LENGTH_LONG).show();
// Enviar código de falla
getActivity().setResult(Activity.RESULT_CANCELED);
// Terminar actividad
getActivity().finish();
break;
}
} catch (JSONException e) {
e.printStackTrace();
}
}
/**
* Carga los datos iniciales del formulario con los
* atributos de un objeto {@link Meta}
*
* @param meta Instancia
*/
private void cargarViews(Meta meta) {
// Seteando valores de la respuesta
titulo_input.setText(meta.getTitulo());
descripcion_input.setText(meta.getDescripcion());
fecha_text.setText(meta.getFechaLim());
// Obteniendo acceso a los array de strings para categorias y prioridades
String[] categorias = getResources().getStringArray(R.array.entradas_categoria);
String[] prioridades = getResources().getStringArray(R.array.entradas_prioridad);
// Obteniendo la posición del spinner categorias
int posicion_categoria = 0;
for (int i = 0; i < categorias.length; i++) {
if (categorias[i].compareTo(meta.getCategoria()) == 0) {
posicion_categoria = i;
break;
}
}
// Setear selección del Spinner de categorías
categoria_spinner.setSelection(posicion_categoria);
// Obteniendo la posición del spinner de prioridades
int posicion_prioridad = 0;
for (int i = 0; i < prioridades.length; i++) {
Log.d(TAG, "posición:" + i);
if (prioridades[i].compareTo(meta.getPrioridad()) == 0) {
posicion_prioridad = i;
break;
}
}
// Setear selección del Spinner de prioridades
prioridad_spinner.setSelection(posicion_prioridad);
}
/**
* Compara los datos actuales con aquellos que se obtuvieron
* por primera vez en la respuesta HTTP
*
* @return true si los datos no han cambiado, de lo contrario false
*/
public boolean validarCambios() {
return metaOriginal.compararCon(obtenederDatos());
}
/**
* Retorna en una nueva meta creada a partir
* de los datos del formulario actual
*
* @return Instancia {@link Meta}
*/
private Meta obtenederDatos() {
String titulo = titulo_input.getText().toString();
String descripcion = descripcion_input.getText().toString();
String fecha = fecha_text.getText().toString();
String categoria = (String) categoria_spinner.getSelectedItem();
String prioridad = (String) prioridad_spinner.getSelectedItem();
return new Meta("0", titulo, descripcion, fecha, categoria, prioridad);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true); // Contribución a la AB
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case android.R.id.home:// CONFIRMAR
if (!validarCambios())
guardarMeta();
else
// Terminar actividad, ya que no hay cambios
getActivity().finish();
return true;
case R.id.action_delete:// ELIMINAR
mostrarDialogo(R.string.dialog_delete_msg);
break;
case R.id.action_discard:// DESCARTAR
if (!validarCambios()) {
mostrarDialogo(R.string.dialog_discard_msg);
} else
// Terminar actividad, ya que no hay cambios
getActivity().finish();
break;
}
;
return super.onOptionsItemSelected(item);
}
/**
* Guarda los cambios de una meta editada.
* <p>
* Si está en modo inserción, entonces crea una nueva
* meta en la base de datos
*/
private void guardarMeta() {
// Obtener valores actuales de los controles
final String titulo = titulo_input.getText().toString();
final String descripcion = descripcion_input.getText().toString();
final String fecha = fecha_text.getText().toString();
final String categoria = categoria_spinner.getSelectedItem().toString();
final String prioridad = prioridad_spinner.getSelectedItem().toString();
HashMap<String, String> map = new HashMap<>();// Mapeo previo
map.put("idMeta", idMeta);
map.put("titulo", titulo);
map.put("descripcion", descripcion);
map.put("fechaLim", fecha);
map.put("categoria", categoria);
map.put("prioridad", prioridad);
// Crear nuevo objeto Json basado en el mapa
JSONObject jobject = new JSONObject(map);
// Depurando objeto Json...
Log.d(TAG, jobject.toString());
// Actualizar datos en el servidor
VolleySingleton.getInstance(getActivity()).addToRequestQueue(
new JsonObjectRequest(
Request.Method.POST,
Constantes.UPDATE,
jobject,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
procesarRespuestaActualizar(response);
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, "Error Volley: " + error.getMessage());
}
}
) {
@Override
public Map<String, String> getHeaders() {
Map<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json; charset=utf-8");
headers.put("Accept", "application/json");
return headers;
}
@Override
public String getBodyContentType() {
return "application/json; charset=utf-8" + getParamsEncoding();
}
}
);
}
/**
* Procesa todos las tareas para eliminar
* una meta en la aplicación. Este método solo se usa
* en la edición
*/
public void eliminarMeta() {
HashMap<String, String> map = new HashMap<>();// MAPEO
map.put("idMeta", idMeta);// Identificador
JSONObject jobject = new JSONObject(map);// Objeto Json
// Eliminar datos en el servidor
VolleySingleton.getInstance(getActivity()).addToRequestQueue(
new JsonObjectRequest(
Request.Method.POST,
Constantes.DELETE,
jobject,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
// Procesar la respuesta
procesarRespuestaEliminar(response);
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, "Error Volley: " + error.getMessage());
}
}
) {
@Override
public Map<String, String> getHeaders() {
Map<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json; charset=utf-8");
headers.put("Accept", "application/json");
return headers;
}
@Override
public String getBodyContentType() {
return "application/json; charset=utf-8" + getParamsEncoding();
}
}
);
}
/**
* Procesa la respuesta de eliminación obtenida desde el sevidor
*/
private void procesarRespuestaEliminar(JSONObject response) {
try {
// Obtener estado
String estado = response.getString("estado");
// Obtener mensaje
String mensaje = response.getString("mensaje");
switch (estado) {
case "1":
// Mostrar mensaje
Toast.makeText(
getActivity(),
mensaje,
Toast.LENGTH_LONG).show();
// Enviar código de éxito
getActivity().setResult(203);
// Terminar actividad
getActivity().finish();
break;
case "2":
// Mostrar mensaje
Toast.makeText(
getActivity(),
mensaje,
Toast.LENGTH_LONG).show();
// Enviar código de falla
getActivity().setResult(Activity.RESULT_CANCELED);
// Terminar actividad
getActivity().finish();
break;
}
} catch (JSONException e) {
e.printStackTrace();
}
}
/**
* Procesa la respuesta de actualización obtenida desde el sevidor
*/
private void procesarRespuestaActualizar(JSONObject response) {
try {
// Obtener estado
String estado = response.getString("estado");
// Obtener mensaje
String mensaje = response.getString("mensaje");
switch (estado) {
case "1":
// Mostrar mensaje
Toast.makeText(
getActivity(),
mensaje,
Toast.LENGTH_LONG).show();
// Enviar código de éxito
getActivity().setResult(Activity.RESULT_OK);
// Terminar actividad
getActivity().finish();
break;
case "2":
// Mostrar mensaje
Toast.makeText(
getActivity(),
mensaje,
Toast.LENGTH_LONG).show();
// Enviar código de falla
getActivity().setResult(Activity.RESULT_CANCELED);
// Terminar actividad
getActivity().finish();
break;
}
} catch (JSONException e) {
e.printStackTrace();
}
}
/**
* Actualiza la fecha del campo {@link fecha_text}
*
* @param ano Año
* @param mes Mes
* @param dia Día
*/
public void actualizarFecha(int ano, int mes, int dia) {
// Setear en el textview la fecha
fecha_text.setText(ano + "-" + (mes + 1) + "-" + dia);
}
/**
* Muestra un diálogo de confirmación, cuyo mensaje esta
* basado en el parámetro identificador de Strings
*
* @param id Parámetro
*/
private void mostrarDialogo(int id) {
DialogFragment dialogo = ConfirmDialogFragment.
createInstance(
getResources().
getString(id));
dialogo.show(getFragmentManager(), "ConfirmDialog");
}
}
Datepicker
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class DatePickerFragment2 extends DialogFragment
implements DatePickerDialog.OnDateSetListener {
OnDateSelectedListener mCallback;
// Container Activity must implement this interface
public interface OnDateSelectedListener {
void onDateSelected(int year, int month, int day);
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the current date as the default date in the picker
final Calendar c = Calendar.getInstance();
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH);
int day = c.get(Calendar.DAY_OF_MONTH);
// Create a new instance of DatePickerDialog and return it
return new DatePickerDialog(getActivity(), this, year, month, day);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mCallback = (OnDateSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " debe implementar OnDateSelectedListener");
}
}
@Override
public void onDateSet(DatePicker view, int ano, int mes, int dia) {
mCallback.onDateSelected(ano, mes, dia);
}
}
FINAL CODE:
Arrays.sort (goals, new Comparator () { int result; DateFormat f = new SimpleDateFormat ("yyyy-MM-dd"); @Override public int compare (Goal object1, Goal object2) {
// Comparamos por fechaLim de forma descendente:
try {
result = f.parse(objeto2.fechaLim).compareTo(f.parse(objeto1.fechaLim));
} catch (ParseException e) {
e.printStackTrace();
}
return result;
}
});