2017-03-23 10 views
0

Ich bekomme nicht die Daten in Recyclerview holen Daten vom Server mit Retrofit-Client. Und keinen Wert in "Log.d (TAG," Anzahl der stündlichen empfangenen Wetterdaten "+ list.size()) anzeigen;"Recyclerview zeigt keine Daten

Recyclerview Adapter

public class HourlyAdapter extends RecyclerView.Adapter<HourlyAdapter.HourlyViewHolder> { 

    List<HourlyList> hourlist; 
    Context context; 
    public HourlyAdapter(List<HourlyList> hourlist,Context context){ 
     this.hourlist = hourlist; 
     this.context = context; 

    } 
    @Override 
    public HourlyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.hourly_list,parent,false); 

     return new HourlyViewHolder(view); 
    } 


    @Override 
    public void onBindViewHolder(HourlyViewHolder holder, int position) { 
     Date date = new Date(hourlist.get(position).getDt()*1000L); 
     SimpleDateFormat sdf = new SimpleDateFormat("HH:mm"); 
     String formateDate = sdf.format(date); 
     holder.hour.setText(formateDate); 


    } 

    @Override 
    public int getItemCount() { 
     Log.d("datasize", String.valueOf(hourlist.size())); 
     return hourlist == null ? 0 : hourlist.size(); 

    } 

    public class HourlyViewHolder extends RecyclerView.ViewHolder { 
     @BindView(R.id.hour) 
     TextView hour; 
     public HourlyViewHolder(View itemView) { 
      super(itemView); 
      ButterKnife.bind(this,itemView); 
     } 
    } 
} 

Fragmentdatei

public class HourlyFragment extends Fragment { 
    @BindView(R.id.recyclerview) 
    RecyclerView recyclerView; 
    List<HourlyList> list; 
    HourlyAdapter adapter; 


    public HourlyFragment() { 
     // Required empty public constructor 
    } 


    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     // Inflate the layout for this fragment 
     View view = inflater.inflate(R.layout.fragment_hourly, container, false); 

     ButterKnife.bind(this,view); 
     recyclerView.setHasFixedSize(true); 
     LinearLayoutManager lm = new LinearLayoutManager(getActivity()); 
     lm.setOrientation(LinearLayoutManager.VERTICAL); 
     recyclerView.setLayoutManager(lm); 

     adapter = new HourlyAdapter(list,getActivity().getApplicationContext()); 
     hourlyWeather(); 


     return view; 
    } 
    public void hourlyWeather(){ 
     ApiInterface apiInterface = ApiClient.getRetrofit().create(ApiInterface.class); 
     Call<HourlyWeather> call = apiInterface.getHourlyWeather("London","metric",getResources().getString(R.string.api_key)); 

     call.enqueue(new Callback<HourlyWeather>() { 
      @Override 
      public void onResponse(Call<HourlyWeather> call, Response<HourlyWeather> response) { 

        list = response.body().getList(); 


       Log.d(TAG,"Number of hourly weather data received "+list.size()); 
       recyclerView.setAdapter(adapter); 







      } 

      @Override 
      public void onFailure(Call<HourlyWeather> call, Throwable t) { 
       t.printStackTrace(); 

      } 
     }); 

    } 

} 

Schnittstellendatei

@GET("forecast?") 
    Call<HourlyWeather> getHourlyWeather(@Query("q") String city, 
             @Query("units") String units, 
             @Query("APPID") String appId); 

Retrofit Client

public class ApiClient { 
    public static final String BASE_URL="http://api.openweathermap.org/data/2.5/"; 
    public static Retrofit retrofit =null; 

    public static Retrofit getRetrofit(){ 
     if (retrofit == null){ 

      retrofit = new Retrofit.Builder() 
        .baseUrl(BASE_URL) 
        .addConverterFactory(GsonConverterFactory.create()) 
        .build(); 
     } 
     return retrofit; 

    } 
} 

XML-Datei

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    tools:context="com.example.prem.weatherapp.fragment.HourlyFragment"> 

    <android.support.v7.widget.RecyclerView 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:id="@+id/recyclerview" 
     android:scrollbars="none" 
     android:clipToPadding="false"> 

    </android.support.v7.widget.RecyclerView> 





</RelativeLayout> 

Liste der Daten XML-Datei ist

<?xml version="1.0" encoding="utf-8"?> 
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    app:cardBackgroundColor="@android:color/transparent" 
    android:elevation="0dp" 
    app:cardPreventCornerOverlap="false" 
    app:contentPadding="0dp"> 
    <RelativeLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:paddingBottom="10dp" 
     android:paddingLeft="10dp" 
     android:paddingRight="10dp" 
     android:paddingTop="10dp"> 

     <TextView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_centerHorizontal="true" 
      android:id="@+id/date"/> 
     <TextView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:id="@+id/hour" 
      android:layout_below="@id/date"/> 
    </RelativeLayout> 

</android.support.v7.widget.CardView> 
+0

haben Sie den StackTrace auf Fehler überprüft? – MadScientist

+1

können Sie Ihre Antwortstruktur teilen? –

+0

list = response.body(). GetList(); -> Sie aktualisieren den Verweis auf die Liste in HourlyFragment nicht im Adapter. – dtx12

Antwort

0

Dieses Problem, dass Sie Ihren Adapter festlegen, bevor Sie Ihre Liste zu füllen. Sie erstellen Ihren Adapter, bevor Sie eine Antwort von Ihrer Liste erhalten. Sie müssen sich daran erinnern, dass Sie bei einer Nachrüstanforderung auf die Antwort warten müssen. Andernfalls senden Sie nur eine leere Liste an Ihren Adapter.

Sie sollte so etwas tun:

@Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     // Inflate the layout for this fragment 
     View view = inflater.inflate(R.layout.fragment_hourly, container, false); 

     ButterKnife.bind(this,view); 
     recyclerView.setHasFixedSize(true); 
     LinearLayoutManager lm = new LinearLayoutManager(getActivity()); 
     lm.setOrientation(LinearLayoutManager.VERTICAL); 
     recyclerView.setLayoutManager(lm); 
     hourlyWeather(); 


     return view; 
    } 

public void hourlyWeather(){ 
     ApiInterface apiInterface = ApiClient.getRetrofit().create(ApiInterface.class); 
     Call<HourlyWeather> call = apiInterface.getHourlyWeather("London","metric",getResources().getString(R.string.api_key)); 

     call.enqueue(new Callback<HourlyWeather>() { 
      @Override 
      public void onResponse(Call<HourlyWeather> call, Response<HourlyWeather> response) { 

        list = response.body().getList(); 

       adapter = new HourlyAdapter(list,getActivity().getApplicationContext()); 

       Log.d(TAG,"Number of hourly weather data received "+list.size()); 
       recyclerView.setAdapter(adapter); 







      } 
+0

Ich versuchte immer noch nicht funktioniert – prem

+0

Sie sollten Ihre 'list' überprüfen dann. Ich vermute, dass die Antwort, die Sie erhalten, nicht die ist, die Sie erwarten, oder Sie sind 'getList()' Methode gibt Ihre Liste nicht zurück. – BlackHatSamurai

0

die Sie interessieren, erstellen Sie eine Callback-Schnittstelle

public interface callbackInterface { 
     public void onSuccess(yourList); 
} 

Dann

hourlyWeather(new callbackInterface() { 
     @Override 
     public void onSuccess(yourList) { 
       //Set your adapter here. 
     } 
} 

In hourlyWeatherMethod

hourlyWeather(callbackInterface ci) { 
    //Your retrofit Code goes here 
    ci.onSuccess(yourList); 
} 
0

Ich würde vorschlagen, Retrofit Netzwerkanruf mit Android LoaderManager & AsyncTaskLoader zu behandeln, nicht von onCreateView aufrufen. Fühlen Sie sich frei, diesen Ansatz zu versuchen:

1) Veränderung HourlyFragment

import android.support.v4.app.LoaderManager; 
import android.support.v4.content.AsyncTaskLoader; 
import android.support.v4.content.Loader; 

public class HourlyFragment extends Fragment implements LoaderManager.LoaderCallbacks<List<HourlyList>> { 
    final List<HourlyList> list = new ArrayList<>(); 
    HourlyAdapter adapter; 
    ..... 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     ...... 

     adapter = new HourlyAdapter(this.list, getActivity().getApplicationContext()); 
     recyclerView.setAdapter(adapter); 

     return view; 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 
     getLoaderManager().initLoader(0, null, this); 
    } 

    @Override 
    public Loader<List<HourlyList>> onCreateLoader(int arg0, Bundle arg1) { 
     return new HourlyWeatherLoader(this.getActivity()); 
    } 

    @Override 
    public void onLoadFinished(Loader<List<HourlyList>> arg0, List<HourlyList> datas) {  
     this.list.clear(); 
     this.list.addAll(datas); 

     // this shall update recyclerview to show newly added data 
     this.adapter.notifyDataSetChanged(); 
    } 

    @Override 
    public void onLoaderReset(Loader<List<HourlyList>> arg0) { 
    } 

2) hinzufügen HourlyWeatherLoader Klasse Retrofit Netzanruf

public class HourlyWeatherLoader extends AsyncTaskLoader<List<HourlyList>> { 
    private List<HourlyList> list; 

    public HourlyWeatherLoader(Context context) { 
     super(context); 
    } 

    @Override 
    public List<HourlyList> loadInBackground() { 

     ApiInterface apiInterface = ApiClient.getRetrofit().create(ApiInterface.class); 
     Call<HourlyWeather> call = apiInterface.getHourlyWeather("London","metric",getResources().getString(R.string.api_key)); 

     try { 
      HourlyWeather hourlyWeather = call.execute().body(); 
      this.list = hourlyWeather.getList(); 
     } catch (IOException e) { 
      // handle exception catched 
      ..... 
     } 

     return this.list; 
    } 

    @Override 
    public void onCanceled(List<HourlyList> list) { 
     super.onCanceled(list); 
    } 

    @Override 
    protected void onStopLoading() { 
     cancelLoad(); 
    } 

    @Override 
    protected void onStartLoading() { 
     if (this.list != null) { 
      deliverResult(this.list); 
     } 

     if (takeContentChanged() || this.list == null) { 
      forceLoad(); 
     } 
    } 

    @Override 
    protected void onReset() { 
     super.onReset(); 
     onStopLoading(); 
     this.list = null; 
    } 
} 

hoffe, das hilft zu handhaben!