如何将 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-addingRecyclerViewAdapter数据后使用

尝试在

之后添加: notifyDataSetChanged()
mRecyclerView.setAdapter(mAdapter);

或者无论你在哪里更新-添加数据到 Adapter。或者,你可以试试这个:

mAdapter.notifyDataSetChanged()

onPostExecute.