更新适配器数据后,RecyclerView未显示任何内容

时间:2015-11-13 16:59:30

标签: android android-fragments arraylist android-recyclerview recycler-adapter

我需要帮助解决这个问题,我已经通过我的代码几天来弄清楚是什么问题,但我无法理解。 我有一个带有RecyclerView的片段我使用图像占位符和一些默认文本初始化适配器数据,片段按预期显示它们然后使用加载器我从互联网获取数据并解析并将新数据传递给适配器(所有这种情况发生在需要)直到数据到达适配器然后Taaadaaaa初始数据消失和新数据没有显示实际上片段显示一个空白屏幕肯定我做错了请建议。 这是片段代码

public class fragment_MovieStartGridlayout extends android.support.v4.app.Fragment implements MyGridAdapter.MyGridAdapterListener{

private static RecyclerView myRecyclerView;
private static MyGridAdapter myGridAdapter;
private static RecyclerView.LayoutManager rvLayoutManager;
private LoaderManager.LoaderCallbacks<ArrayList<HashMap>> dataLoaderCallbacks;


private OnFragmentInteractionListener mListener;

public fragment_MovieStartGridlayout() {

}

@Override
public void onActivityCreated  (Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

  dataLoaderCallbacks = new LoaderManager.LoaderCallbacks<ArrayList<HashMap>>() {

  @Override
  public Loader<ArrayList<HashMap>> onCreateLoader(int id, Bundle args) {
   return new DataLoader(getActivityContext(), MyUriBuilder.DISCOVER, null);
            }

@Override
public void onLoadFinished(Loader<ArrayList<HashMap>> loader,ArrayList<HashMap> data) {
                myGridAdapter.setMyAdapterData(data);
            }

            @Override
            public void onLoaderReset(Loader<ArrayList<HashMap>> loader) {
                loader.reset();
            }

        };
        getLoaderManager().initLoader(0, null, dataLoaderCallbacks);

    setRetainInstance(true);
}

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

    View fragGridLayout = inflater.inflate(R.layout.fragment_gridlayout_movie_start, container, false);
    myRecyclerView = (RecyclerView) fragGridLayout.findViewById(R.id.myViewRecycler);
    rvLayoutManager = new GridLayoutManager(getActivityContext(),2);
    myRecyclerView.setLayoutManager(rvLayoutManager);
    myGridAdapter = new MyGridAdapter(getActivityContext());
    myRecyclerView.setAdapter(myGridAdapter);

    return fragGridLayout;
}


@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    try {
        mListener = (OnFragmentInteractionListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
                + " must implement OnFragmentInteractionListener");
    }
}

@Override
public void onDataSetChanged(boolean state) {
    if (state){
        myGridAdapter.notifyDataSetChanged();
    }
}


public interface OnFragmentInteractionListener {
    public void onFragmentInteraction(Uri uri);
}


    public Context getActivityContext(){
        return this.getActivity();
    }

}

这是RecyclerView的适配器

 public class MyGridAdapter extends RecyclerView.Adapter<MyGridAdapter.MyViewHolder> {

LayoutInflater layoutInflater;
private static ArrayList<HashMap> data=null;
private Context mContext;
public static Bitmap placeHolder;
    public MyGridAdapter(Context context){
      mContext = context;
      setInitialData();
      placeHolder =    BitmapFactory.decodeResource(mContext.getResources(),R.drawable.android_blue);
}
    public interface MyGridAdapterListener{
        public void onDataSetChanged(boolean state);
    }

private MyGridAdapterListener listener = null;
public void registerListener(MyGridAdapterListener newListener){
    listener = newListener;
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    Context context = parent.getContext();
    layoutInflater = LayoutInflater.from(context);
    View v = layoutInflater.inflate(R.layout.gridlayout_item_movie_start, parent, false);
    MyViewHolder vHolder=new MyViewHolder(v);
    return vHolder;
}

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {

      HashMap singleData = data.get(position);
      String movieRate = String.valueOf(singleData.get(MyJSONDataParser.TAG_VOTE_AVERAGE)) ;
        holder.movieTitle.setText((String)singleData.get(MyJSONDataParser.TAG_TITLE));
        holder.moviePoster.setImageBitmap(placeHolder);
        holder.movieRating.setRating(Float.valueOf(movieRate));
}

@Override
public int getItemCount() {
    return data.size();
}


public static class MyViewHolder extends RecyclerView.ViewHolder  {
    TextView movieTitle;
    RoundedImageView moviePoster;
    RatingBar movieRating;

    public MyViewHolder(View v) {
        super(v);
        movieTitle = (TextView) v.findViewById(R.id.movieTitleTextView);
        moviePoster = (RoundedImageView) v.findViewById(R.id.roundImageView);
        movieRating = (RatingBar) v.findViewById(R.id.ratingBar);
    }
}


private boolean dataChanged = false;

public void setMyAdapterData(ArrayList<HashMap> data){
        this.data = data;
        dataChanged = true;
        if (listener != null){
            listener.onDataSetChanged(dataChanged);
        }
    }


protected void setInitialData(){
    HashMap initialItem = new HashMap();
    ArrayList<HashMap> initialData = new ArrayList<>(20);

    initialItem.put(MyJSONDataParser.TAG_TITLE, "Loading...");
    initialItem.put(MyJSONDataParser.TAG_MOVIE_BITMAP, placeHolder);
    initialItem.put(MyJSONDataParser.TAG_VOTE_AVERAGE, 3.3);
    for (int i = 0;i<20;i++){
        initialData.add(initialItem);
    }
    this.data = initialData;
}

}

2 个答案:

答案 0 :(得分:2)

我确实调用了notifyDataSetChanged 但是在测试alooooooooot之后这不是问题,并且使用setAdapterData方法记录问题,其中我只是将数据引用从加载器传递到适配器但是这没有工作,我不得不克隆arraylist而不是仅仅传递对我来说听起来很奇怪的参考,如果你能看一下MyGridAdapter类中的setAdapterData方法并告诉我你的想法,我仍然不明白为什么我必须这样做

答案 1 :(得分:0)

在修改适配器数据时尝试调用notifyDataSetChanged():

public void setMyAdapterData(ArrayList<HashMap> data){
    this.data = data;
    dataChanged = true;
    notifyDataSetChanged();
    if (listener != null){
        listener.onDataSetChanged(dataChanged);
    }
}

我看到你试图在你的监听器的回调中这样做,但也许它是null,因此从不触发通知?

[注释] 当我想要替换适配器中的整个数据集时,我经常编写一个类似于此的方法:

public void setData(List<MyData> newData) {
    this.data.clear();
    this.data.addAll(newData);
    this.notifyDataSetChanged();
}