I've tried to look for a solution but I have not been able to find one with my specific situation. I'm using a recyclerview
with GSON
and I'm getting the message of skipping layout. My code looks correct but I know I should set an empty adapter in the onCreateView section. I'm not sure how to exactly do that. Any help will be appreciated. My fragment activity is below.
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_weather_app, container, false);
mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mRecyclerView.addItemDecoration(new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration.VERTICAL));
new GetWeatherAync().execute(getActivity());
return view;
}
private class GetWeatherAync extends AsyncTask<Context, Void,
List<ForecastWeatherList>> {
private String TAG = GetWeatherAync.class.getSimpleName();
private Context mContext;
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected List<ForecastWeatherList> doInBackground(Context...params) {
mContext = params[0];
return getWeatherFromServer();
}
@Override
protected void onPostExecute(List<ForecastWeatherList> result) {
super.onPostExecute(result);
if (result != null) {
Log.e(TAG, "populate UI recycler view with gson converted data");
RecyclerViewAdapter weatherRecyclerViewAdapter = new RecyclerViewAdapter(result, mContext);
mRecyclerView.setAdapter(weatherRecyclerViewAdapter);
}
}
}
public List<ForecastWeatherList> getWeatherFromServer(){
String serviceUrl = "http://api.openweathermap.org/data/2.5/forecast?q=" + searchView + api_key;
URL url = null;
try {
url = new URL(serviceUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.setConnectTimeout(4000);
connection.setReadTimeout(4000);
connection.connect();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
//pass buffered reader to convert json to javaobject using gson
return convertJsonToObject(bufferedReader);
}catch (Exception e){
}
return null;
}
public List<ForecastWeatherList> convertJsonToObject(BufferedReader bufferedReader){
final Gson gson = new Gson();
//pass root element type to fromJson method along with input stream
ForecastWeatherListWrapper weatherWrapper = gson.fromJson(bufferedReader,ForecastWeatherListWrapper.class);
List<ForecastWeatherList> weatherlst = weatherWrapper.getforecastWeatherLists();
return weatherlst;
}
EDIT:
So I've implemented the following changes:
Listener Interface.
import com.ksburneytwo.weathertest.ForecastWeather.ForecastWeatherList;
import java.util.List;
public interface Listener {
void afterSearch(List<ForecastWeatherList> result);
}
Fragment:
public static WeatherAppFragment newInstance(String param1, String param2) {
WeatherAppFragment fragment = new WeatherAppFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_weather_app, container, false);
mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mRecyclerView.addItemDecoration(new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration.VERTICAL));
new GetWeatherAync().execute(getActivity());
return view;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu, menu);
MenuItem searchItem = menu.findItem(R.id.menu_search);
SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE);
if (searchItem != null) {
searchView = (SearchView) searchItem.getActionView();
}
if (searchView != null) {
searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName()));
queryTextListener = new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextChange(String newText) {
Log.i("onQueryTextChange", newText);
return true;
}
@Override
public boolean onQueryTextSubmit(String query) {
Log.i("onQueryTextSubmit", query);
return true;
}
};
searchView.setOnQueryTextListener(queryTextListener);
}
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public void afterSearch(List<ForecastWeatherList> result) {
mRecyclerView.setAdapter(new RecyclerViewAdapter(result, mRecyclerView.getContext()));
}
private static class GetWeatherAync extends AsyncTask<Context, Void, List<ForecastWeatherList>> {
private String TAG = GetWeatherAync.class.getSimpleName();
private final String serviceUrl;
private Context mContext;
private Listener listener;
GetWeatherAync(Listener listener,String searchView, String api_key) {
this.listener = listener;
this.serviceUrl = "http://api.openweathermap.org/data/2.5/forecast?q=" + searchView + api_key;
}
@Override
protected List<ForecastWeatherList> doInBackground(Context...params) {
try {
URL url = new URL(serviceUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.setConnectTimeout(4000);
connection.setReadTimeout(4000);
connection.connect();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
ForecastWeatherListWrapper weatherWrapper = new Gson().fromJson(bufferedReader, ForecastWeatherListWrapper.class);
return weatherWrapper.getforecastWeatherLists();
} catch (Exception e) {}
return null;
}
@Override
protected void onPostExecute(List<ForecastWeatherList> result) {
super.onPostExecute(result);
if (result != null) {
Log.e(TAG, "populate UI recycler view with gson converted data");
listener.afterSearch(result);
}
}
}
Here is the recyclerview adapter.
public class RecyclerViewAdapter extends
RecyclerView.Adapter<RecyclerViewAdapter.ForecastRecycler> {
List<ForecastWeatherList> mForecastWeatherDataList;
public static class ForecastRecycler extends RecyclerView.ViewHolder{
public TextView currentTemp;
public TextView currentHumidity;
public TextView currentDescription;
public ImageView currentIcon;
public ForecastRecycler (View view) {
super (view);
currentTemp = (TextView) view.findViewById(R.id.current_temperature);
currentHumidity = (TextView) view.findViewById(R.id.current_humidity);
currentDescription = (TextView) view.findViewById(R.id.current_weather_description);
currentIcon = (ImageView) view.findViewById(R.id.current_weather_icon);
}
}
public RecyclerViewAdapter(List<ForecastWeatherList> mForecastWeatherDataList, Context mContext) {
this.mForecastWeatherDataList = mForecastWeatherDataList;
}
@Override
public ForecastRecycler onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_item, parent, false);
final ForecastRecycler currentRecycler = new ForecastRecycler(view);
return currentRecycler;
}
@Override
public void onBindViewHolder( ForecastRecycler holder, int position) {
final ForecastWeatherList currentRecycler = mForecastWeatherDataList.get(position);
holder.currentTemp.setText((currentRecycler.getMain().getTempKf()));
holder.currentHumidity.setText(currentRecycler.getMain().getHumidity());
holder.currentDescription.setText(currentRecycler.getWeather().getDescription());
Picasso.with(holder.currentIcon.getContext()).load(currentRecycler.getWeather().getIcon());
}
@Override
public int getItemCount() {
return mForecastWeatherDataList.size();
}
}
Here are my current logs. I know its connecting to the server but I'm still getting no adapter attached error.
11371-11371/com.ksburneytwo.weathertest D/debugMode: The application is in onCreateView
11371-11396/com.ksburneytwo.weathertest D/debugMode: The application is in doInBackground
11371-11371/com.ksburneytwo.weathertest E/RecyclerView: No adapter attached; skipping layout
11371-11396/com.ksburneytwo.weathertest D/NetworkSecurityConfig: No Network Security Config specified, using platform default
11371-11396/com.ksburneytwo.weathertest D/debugMode: The application stopped after catch