I am working on an application of time and the design is with three tabs, the problem comes to me when I show the predictions for the next five days in a recycler
, which generates an error indicating that I invoke a reference of null objects . I have used the debugger and indeed, the values are null, but I can not find the error.
My adapter :
public class MyCincoDiasRecyclerViewAdapter extends RecyclerView.Adapter<MyCincoDiasRecyclerViewAdapter.ViewHolder> {
private final List<Day> mValues;
//El error era que estaba declarado como final y no como private solo
private IPredictionListener mListener;
//Recordar que hay que poner el context, como en los ejemplos de Miguel
Context ctx;
public MyCincoDiasRecyclerViewAdapter(List<Day> items, IPredictionListener listener, Context context ) {
mValues = items;
ctx = context;
mListener = listener;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fragment_cincodias_item,parent,false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.mItem = mValues.get(position);
Day currentDay = mValues.get(position);
List<Predictions> mainPredictionList = currentDay.getMainPredictionList();
//Para mostrar la fecha del día
holder.fechaActual.setText(currentDay.getLongFormatDate(ctx));
//Declaramos el objeto para poder obtener las predicciones
Predictions prediccionActual = mainPredictionList.get(0);
holder.iconoEstadoDia.setImageResource(prediccionActual.getWeather().get(0).getCustomIcons());
//holder.tmpMaxima.setText(prediccionActual.getMain().getTempMax());
holder.tmpMaxima.setText(prediccionActual.getMain().getTempMax().toString());
holder.tmpMaxima.setText(prediccionActual.getMain().getTempMin().toString());
//holder.diaSemana.setText(prediccionActual.getName());
}
@Override
public int getItemCount() {
return mValues.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public final View mView;
public Day mItem;
/*Intentaremos mostrar por cada día el pronóstico más actual*/
@BindView(R.id.textView_fecha_actual)
TextView fechaActual;
@BindView(R.id.id_dia_semana)
TextView diaSemana;
//cambiar esto por la hora en caso de que no salga
@BindView(R.id.estado_dia)
TextView estadoDia;
@BindView(R.id.textView_temperatura_maxima)
TextView tmpMaxima;
@BindView(R.id.textView_temperatura_minima)
TextView tmpMinima;
@BindView(R.id.imageView_estado_dia)
ImageView iconoEstadoDia;
public ViewHolder(View view) {
super(view);
mView = view;
/*
Para simplificar las cosas usamos ButterKnife
*/
ButterKnife.bind(this,view);
}
@Override
public String toString() {
return super.toString() + " '" + /*mContentView.getText()*/ "'";
}
}
}
The fragment :
public class CincoDiasFragment extends Fragment {
private static final String ARG_COLUMN_COUNT = "column-count";
private int mColumnCount = 1;
private IPredictionListener mListener;
RecyclerView recyclerView;
/**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
*/
public CincoDiasFragment() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_cincodias_list, container, false);
// Set the adapter
if (view instanceof RecyclerView) {
Context context = view.getContext();
RecyclerView recyclerView = (RecyclerView) view;
if (mColumnCount <= 1) {
recyclerView.setLayoutManager(new LinearLayoutManager(context));
} else {
recyclerView.setLayoutManager(new GridLayoutManager(context, mColumnCount));
}
/*Además este método filtra las predicciones y se las pasa al adapter*/
consultarPronostico();
}
return view;
}
/*Consultando el pronóstico para poder mostrarlo*/
private void consultarPronostico() {
/*Una vez más, recurrimos a las preferencias para leer la ciudad, latitud y longitud*/
SharedPreferences sharedpreferences = getActivity().getPreferences(Context.MODE_PRIVATE);
String lon = sharedpreferences.getString(Constantes.KEY_CURRENT_LON,"");
String lat = sharedpreferences.getString(Constantes.KEY_CURRENT_LAT,"");
String city = sharedpreferences.getString(Constantes.KEY_CURRENT_CITY,"");
mListener.cambiarTitulo(city);
/*Consulta retrofit*/
Retrofit retrofit = ((AutocompleteApp) getActivity().getApplication()).getRetrofitOpenWeather();
final IOpenWeatherApi service = retrofit.create(IOpenWeatherApi.class);
//final Call<RootPredictions> call =service.getPronostico(lat,lon);
final Call<RootPredictions> call = service.getPronostico(lat,lon);
call.enqueue(new Callback<RootPredictions>() {
@Override
public void onResponse(Response<RootPredictions> response, Retrofit retrofit) {
if (response.isSuccess()){
RootPredictions rootDayList = response.body();
/*Creando la lista de días*/
getListaDias(rootDayList);
}else{
Toast.makeText(getActivity(), "Error" + response.code(), Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Throwable t) {
Toast.makeText(getActivity(), "Error" + t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
/*Obteniendo una lista de días a partir de las predicciones*/
public void getListaDias(RootPredictions root) {
//Obteniendo las fechas con el maestro Joda
DateTime day0 = new DateTime();
String strDay0 = day0.getDayOfMonth()+" / "+day0.getMonthOfYear();
DateTime day1 = day0.plusDays(1);
String strDay1 = day1.getDayOfMonth()+" / "+day1.getMonthOfYear();
DateTime day2 = day0.plusDays(2);
String strDay2 = day2.getDayOfMonth()+" / "+day2.getMonthOfYear();
DateTime day3 = day0.plusDays(3);
String strDay3 = day3.getDayOfMonth()+" / "+day3.getMonthOfYear();
DateTime day4 = day0.plusDays(4);
String strDay4 = day4.getDayOfMonth()+" / "+day4.getMonthOfYear();
/*Fintrando las predicciones*/
List<Predictions> day0List = new ArrayList<>();
List<Predictions> day1List = new ArrayList<>();
List<Predictions> day2List = new ArrayList<>();
List<Predictions> day3List = new ArrayList<>();
List<Predictions> day4List = new ArrayList<>();
/*bucle que sirve para guardar las predicciones, cada predicción en su array correspondiente*/
for (Predictions p:
root.getPredictionList()) {
if (p.getDayMonth().equals(strDay0)){
day0List.add(p);
}else if (p.getDayMonth().equals(strDay1)){
day1List.add(p);
}else if (p.getDayMonth().equals(strDay2)){
day2List.add(p);
}else if (p.getDayMonth().equals(strDay3)){
day3List.add(p);
}else if (p.getDayMonth().equals(strDay4)){
day4List.add(p);
}
}
/*Para obtener la lista de los días, colocamos cada listado en su día con su fecha*/
List<Day> dayList = new ArrayList<>();
if (day0List.size()>0){
dayList.add(new Day(day0List.get(0).getDt(),day0List));
}
if (day1List.size()>0){
dayList.add(new Day(day1List.get(0).getDt(),day1List));
}
if (day2List.size()>0){
dayList.add(new Day(day2List.get(0).getDt(),day2List));
}
if (day3List.size()>0){
dayList.add(new Day(day3List.get(0).getDt(),day3List));
}
if (day4List.size()>0){
dayList.add(new Day(day4List.get(0).getDt(),day4List));
}
/*Al final lo mostramos en el recyclerView*/
recyclerView.setAdapter(new MyCincoDiasRecyclerViewAdapter(dayList,mListener,getActivity()));
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof IPredictionListener) {
mListener = (IPredictionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnListFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
}
The error :
W / EGL_emulation: eglSurfaceAttrib not implemented W / OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xe1119220, error = EGL_SUCCESS E / RecyclerView: No adapter attached; skipping layout E / RecyclerView: No adapter attached; skipping layout I / Choreographer: Skipped 93 frames! The application may be doing too much work on its main thread. D / AndroidRuntime: Shutting down VM E / AndroidRuntime: FATAL EXCEPTION: main Process: com.example.jmpgallego.di_maps, PID: 5275 java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setAdapter (android.support.v7.widget.RecyclerView $ Adapter) ' on a null object reference at com.example.jmpgallego.di_maps.fragments.CincoDiasFragment.getListaDias (CincoDiasFragment.java:189) at com.example.jmpgallego.di_maps.fragments.CincoDiasFragment $ 1.onResponse (CincoDiasFragment.java:108)
Lines 189 and 108 are respectively :
recyclerView.setAdapter(new MyCincoDiasRecyclerViewAdapter(dayList,mListener,getActivity()));
getListaDias(rootDayList);