如何将 notifyDataSetChanged 与片段、AsyncTask、RecyclerView 和 GSON 一起使用
How to use notifyDataSetChanged with a fragment, AsyncTask,RecyclerView and GSON
我正在尝试开发一个天气应用程序,我已经尝试解决将 RecyclerView 与我的 ArrayList 一起使用的问题。但是我收到没有连接适配器的错误。我试图附加一个监听器,但它不起作用,所以我尝试使用 notifyDataSetChanged 方法,但我对如何使用它感到困惑。我试图将它放在 post 执行中,但我收到另一个错误。有人可以帮我弄清楚如何使用它吗?
这是我的片段:
public class WeatherAppFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private SearchView searchView = null;
private SearchView.OnQueryTextListener queryTextListener;
RecyclerView mRecyclerView;
String mStatusView;
private List<ForecastWeatherList> weatherList = new ArrayList<>();
private RecyclerViewAdapter mAdapter;
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public WeatherAppFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment WeatherAppFragment.
*/
// TODO: Rename and change types and number of parameters
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));
mRecyclerView.setAdapter(mAdapter);
new WeatherAppFragment.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);
mStatusView = query;
return true;
}
};
searchView.setOnQueryTextListener(queryTextListener);
}
super.onCreateOptionsMenu(menu, inflater);
}
public class GetWeatherAync extends AsyncTask<Context, Void, ArrayList<ForecastWeatherList>> {
private String TAG = GetWeatherAync.class.getSimpleName();
public String api_key = "&APPID=ce7da0eaca788fc6342028eae6f3dd5c";
private Context context;
private final String serviceUrl = "http://api.openweathermap.org/data/2.5/forecast?q=" + "Baltimore" + api_key;
@Override
protected ArrayList<ForecastWeatherList> doInBackground(Context...params) {
context = params[0];
try {
Log.e(TAG, "I'm in background");
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 (ArrayList<ForecastWeatherList>) weatherWrapper.getforecastWeatherLists();
} catch (Exception e) {}
return null;
}
@Override
protected void onPostExecute(ArrayList<ForecastWeatherList> result ) {
super.onPostExecute(result);
if (result != null) {
Log.e(TAG, "populate UI recycler view with gson converted data");
RecyclerViewAdapter weatherRecyclerViewAdapter = new RecyclerViewAdapter(result,context);
mRecyclerView.setAdapter(weatherRecyclerViewAdapter);
mAdapter.notifyDataSetChanged();
}
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_search:
// Not implemented here
return false;
default:
break;
}
searchView.setOnQueryTextListener(queryTextListener);
return super.onOptionsItemSelected(item);
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
这是我的 RecyclerViewAdapter:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ForecastRecycler> {
ArrayList<ForecastWeatherList> mForecastWeatherDataList;
private Context context;
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 context) {
this.mForecastWeatherDataList = (ArrayList<ForecastWeatherList>) mForecastWeatherDataList;
this.context = context;
}
@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();
}
}
您似乎忘记用您的结果更新适配器...在 onPostExecute
:
更新 mForecastWeatherDataList
然后调用 notifyDataSetChanged()
notifyDataSetChanged()
在setting-addingRecyclerView
的Adapter
数据后使用
尝试在
之后添加: notifyDataSetChanged()
mRecyclerView.setAdapter(mAdapter);
或者无论你在哪里更新-添加数据到 Adapter
。或者,你可以试试这个:
mAdapter.notifyDataSetChanged()
在onPostExecute
.
我正在尝试开发一个天气应用程序,我已经尝试解决将 RecyclerView 与我的 ArrayList 一起使用的问题。但是我收到没有连接适配器的错误。我试图附加一个监听器,但它不起作用,所以我尝试使用 notifyDataSetChanged 方法,但我对如何使用它感到困惑。我试图将它放在 post 执行中,但我收到另一个错误。有人可以帮我弄清楚如何使用它吗?
这是我的片段:
public class WeatherAppFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private SearchView searchView = null;
private SearchView.OnQueryTextListener queryTextListener;
RecyclerView mRecyclerView;
String mStatusView;
private List<ForecastWeatherList> weatherList = new ArrayList<>();
private RecyclerViewAdapter mAdapter;
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public WeatherAppFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment WeatherAppFragment.
*/
// TODO: Rename and change types and number of parameters
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));
mRecyclerView.setAdapter(mAdapter);
new WeatherAppFragment.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);
mStatusView = query;
return true;
}
};
searchView.setOnQueryTextListener(queryTextListener);
}
super.onCreateOptionsMenu(menu, inflater);
}
public class GetWeatherAync extends AsyncTask<Context, Void, ArrayList<ForecastWeatherList>> {
private String TAG = GetWeatherAync.class.getSimpleName();
public String api_key = "&APPID=ce7da0eaca788fc6342028eae6f3dd5c";
private Context context;
private final String serviceUrl = "http://api.openweathermap.org/data/2.5/forecast?q=" + "Baltimore" + api_key;
@Override
protected ArrayList<ForecastWeatherList> doInBackground(Context...params) {
context = params[0];
try {
Log.e(TAG, "I'm in background");
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 (ArrayList<ForecastWeatherList>) weatherWrapper.getforecastWeatherLists();
} catch (Exception e) {}
return null;
}
@Override
protected void onPostExecute(ArrayList<ForecastWeatherList> result ) {
super.onPostExecute(result);
if (result != null) {
Log.e(TAG, "populate UI recycler view with gson converted data");
RecyclerViewAdapter weatherRecyclerViewAdapter = new RecyclerViewAdapter(result,context);
mRecyclerView.setAdapter(weatherRecyclerViewAdapter);
mAdapter.notifyDataSetChanged();
}
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_search:
// Not implemented here
return false;
default:
break;
}
searchView.setOnQueryTextListener(queryTextListener);
return super.onOptionsItemSelected(item);
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
} 这是我的 RecyclerViewAdapter:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ForecastRecycler> {
ArrayList<ForecastWeatherList> mForecastWeatherDataList;
private Context context;
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 context) {
this.mForecastWeatherDataList = (ArrayList<ForecastWeatherList>) mForecastWeatherDataList;
this.context = context;
}
@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();
}
}
您似乎忘记用您的结果更新适配器...在 onPostExecute
:
更新 mForecastWeatherDataList
然后调用 notifyDataSetChanged()
notifyDataSetChanged()
在setting-addingRecyclerView
的Adapter
数据后使用
尝试在
之后添加:notifyDataSetChanged()
mRecyclerView.setAdapter(mAdapter);
或者无论你在哪里更新-添加数据到 Adapter
。或者,你可以试试这个:
mAdapter.notifyDataSetChanged()
在onPostExecute
.