【问题标题】:Recyclerview adapter data don't changeRecyclerview 适配器数据不会改变
【发布时间】:2016-07-28 20:02:03
【问题描述】:

我正在使用 Recyclerview 适配器将图像放入 Recyclerview 我的代码逻辑是在解析后从 JSON 中获取图像 URL,然后适配器应将图像放入 Recyclerview 中。 图片 URL 取决于某些 SharedPreferences,但问题是当 SharedPreferences 更改时,图片不会随之改变,它们只会在我重新启动应用程序时改变

我的 Recyclerview 适配器:

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {

public Context context;
public ArrayList<MoviesData> array;
public LayoutInflater inflater;


RecyclerViewAdapter(Context context,ArrayList<MoviesData> array)
{
    this.context = context;
    this.array = array;
    this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}



public class ViewHolder extends RecyclerView.ViewHolder {

    ImageView image;


    public ViewHolder(View itemView) {
        super(itemView);
         image = (ImageView) itemView.findViewById(R.id.oneMovieBlockImageView);
    }



}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    View rootview = inflater.inflate(R.layout.movie_block,parent,false);

    ViewHolder viewHolder = new ViewHolder(rootview);

    return viewHolder;
}

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

    Picasso.with(context).load(array.get(position).getPoster_path()).into(holder.image);

}

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

onPostExecute 方法

 @Override
    protected void onPostExecute(ArrayList<MoviesData> result) {
        if (result != null) {

            recyclerView = (RecyclerView) getActivity().findViewById(R.id.recyclerview);

            adapter = new RecyclerViewAdapter(getActivity(),moviesDatas);
            recyclerView.setAdapter(adapter);
            recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));



        }
    }

这是根据 SharedPreferences 更改图像 URL 的方式

 if(sortByStr.equals("popular"))
            {
                url = new URL("http://api.themoviedb.org/3/movie/popular?api_key=9a005dd380ec772cf6045b8c370f8ef7");
            }

            else if(sortByStr.equals("top_rated"))
            {
                url = new URL("http://api.themoviedb.org/3/movie/top_rated?api_key=9a005dd380ec772cf6045b8c370f8ef7");
            }

            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.connect();

我在其中收集所有数据的 MoviesData 类

public class MoviesData implements Parcelable{

MoviesData()
{


}

private String title,rate,release,overview,poster_path;

protected MoviesData(Parcel in) {
    title = in.readString();
    rate = in.readString();
    release = in.readString();
    overview = in.readString();
    poster_path = in.readString();
}

public static final Creator<MoviesData> CREATOR = new Creator<MoviesData>() {
    @Override
    public MoviesData createFromParcel(Parcel in) {
        return new MoviesData(in);
    }

    @Override
    public MoviesData[] newArray(int size) {
        return new MoviesData[size];
    }
};

public void setTitle(String title) {
    this.title = title;
}

public void setRate(String rate) {
    this.rate = rate;
}

public void setRelease(String release) {
    this.release = release;
}

public void setOverview(String overview) {
    this.overview = overview;
}

public void setPoster_path(String poster_path) {
    this.poster_path = "http://image.tmdb.org/t/p/w185" + poster_path;
}

////////////////////////////////////////////////////

public String getTitle() {
    return title;
}

public String getRate() {
    return rate;
}

public String getRelease() {
    return release;
}

public String getOverview() {
    return overview;
}

public String getPoster_path() {
    return poster_path;
}

@Override
public int describeContents() {
    return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(title);
    dest.writeString(rate);
    dest.writeString(release);
    dest.writeString(overview);
    dest.writeString(poster_path);
}}

我在 MoviesData 类中设置所有数据(包括图像 URL)的函数

 private ArrayList<MoviesData> getMoviesDataFromJson(String moviesJsonStr) throws JSONException
    {


        JSONObject forecastJson = new JSONObject(moviesJsonStr);
        JSONArray moviesArray = forecastJson.getJSONArray("results");


        for(int i = 0; i <moviesArray.length(); i++)
        {


           JSONObject movieObject = moviesArray.getJSONObject(i);


            MoviesData movie = new MoviesData();

            movie.setPoster_path(movieObject.getString("poster_path"));
            movie.setTitle(movieObject.getString("title"));
            movie.setOverview(movieObject.getString("overview"));
            movie.setRate(movieObject.getString("vote_average"));
            movie.setRelease(movieObject.getString("release_date"));
            moviesDatas.add(movie);

        }


        return moviesDatas;


    }

【问题讨论】:

    标签: android json android-recyclerview sharedpreferences


    【解决方案1】:

    尝试调用:

    adapter.notifyDataSetChanged();
    

    调用getMoviesDataFromJson 方法后。

    来自notifyDataSetChanged 的文档:

    通知附加的观察者基础数据已被 发生变化,任何反映数据集的视图都应自行刷新。

    希望对你有帮助!

    【讨论】:

    • 你能贴出将网址设置为 MoviesData 的代码吗?
    • 这是我调用 getMoviesDataFromJson 方法的那一行 ` return getMoviesDataFromJson(moviesJsonStr); ` 如果我调用 ` adapter.notifyDataSetChanged(); ` 在它之后,它显示“无法访问的语句”
    • 将 notifyDataSetChanged 放在调用返回 getMoviesDataFromJson(moviesJsonStr) 的方法之后,或者在方法中这样做:ArrayList movies = getMoviesDataFromJson(moviesJsonStr);适配器.notifyDataSetChanged();返回电影;
    【解决方案2】:

    移动此代码

        recyclerView = (RecyclerView) getActivity().findViewById(R.id.recyclerview);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
    

    onPostExecuteonActivityCreated。在onPostExecute 检查适配器是否为空。如果是null 创建它但不是null 刷新它的数据。

    if (adapter == null) {
            adapter = new RecyclerViewAdapter(getActivity(), moviesDatas);
            recyclerView.setAdapter(adapter);
        } else {
            adapter.setData(moviesDatas);
            adapter.notifyDataSetChanged();
        }
    

    您需要在RecyclerViewAdapter 中调用一个名为setData 的方法。

    public void setData(ArrayList<MoviesData> array) {
        this.array = array;
    }
    

    P.S.:编辑SharedPreferences后不要忘记commit

    【讨论】:

    • 我进行了这些更改,但仍然没有运气,这很奇怪,因为当我使用 GridView 而不是 Recyclerview 时它确实工作得很好,也许问题出在我的 Recyclerview 适配器内部?
    • 顺便说一句,它在日志中显示“未连接适配器;跳过布局”
    • 你能在改变这个“Picasso.with(context).load(array.get(position).getPoster_path()).into(holder.image);”之后试试吗在 onBindViewHolder 到 "ViewHolder viewHolder = (ViewHolder) holder; Picasso.with(context).load(array.get(position).getPoster_path()).into(viewHolder.image);"
    【解决方案3】:

    getMoviesDataFromJson 内部初始化 moviesDatas = new ArrayList&lt;&gt;(); 后它可以工作,即使没有 notifyDataSetChanged 老实说,我不知道它为什么起作用,大声笑,有人知道吗?

    【讨论】:

      猜你喜欢
      • 2021-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-30
      • 1970-01-01
      相关资源
      最近更新 更多