在RecyclerView中旋转后显示存储的数据

问题描述:

这是我的情况。我在Volley Library的帮助下从数据库中检索一些数据。一切正常。但是当我旋转屏幕时,web服务再次运行,我不希望发生这种情况。所以这里是我遵循的步骤。在RecyclerView中旋转后显示存储的数据

1)在我的模型对象中,我实现了包含要存储的数据的Parcelable接口。

2)我重写onSaveInstanceState方法来存储旋转屏幕时的数据。这部分工作。

@Override 
public void onSaveInstanceState(Bundle outState) { 
    super.onSaveInstanceState(outState); 

    outState.putParcelableArrayList(CLUB_NEWS,listItemsList); 
} 

3)接下来我在旋转手机后使用该工作正常的那条线恢复这些数据:)。

listItemsList = savedInstanceState.getParcelableArrayList(CLUB_NEWS); 

正如我所说的web服务在轮换后再次运行。我通过读取各种web服务的单个值来解决这个问题。但是,当涉及到回收站时,我有点困惑。这是我的代码。

模型对象

public class ClubNewsObject implements Parcelable{ 
String title; 
public ClubNewsObject(){ 

} 
public ClubNewsObject(Parcel in) { 
    title = in.readString(); 
    article = in.readString(); 
    image = in.readString(); 
} 

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

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

public void setArticle(String article) { 
    this.article = article; 
} 

public void setImage(String image) { 
    this.image = image; 
} 

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

public String getArticle() { 
    return article; 
} 

public String getTitle() { 
    return title; 
} 

public String getImage() { 
    return image; 
} 

String article; 
String image; 

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

@Override 
public void writeToParcel(Parcel dest, int flags) { 
    dest.writeString(title); 
    dest.writeString(article); 
    dest.writeString(image); 
} 

}

ClubNewsFragment

public class ClubNewsFragment extends Fragment { 

public static final String TAG = "ManuApp"; 
private static final String IMAGE_URL = "xxxxxx" ; 
private static final String CLUB_NEWS ="Club news" ; 
private ArrayList<ClubNewsObject> listItemsList; 
LinearLayoutManager linearLayoutManager; 
private RecyclerView mRecyclerView; 
private ClubNewsAdapter adapter; 
private Parcelable mListState; 
public ClubNewsFragment() { 
    // Required empty public constructor 
} 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setHasOptionsMenu(true); 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    // Inflate the layout for this fragment 
    View v = inflater.inflate(R.layout.fragment_club_news, container, false); 
    // Inflate the layout for this fragment 
    listItemsList = new ArrayList<>(); 
    mRecyclerView = (RecyclerView)v.findViewById(R.id.club_news_recycler_view); 

    final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity()); 
    mRecyclerView.setHasFixedSize(true); 
    mRecyclerView.setLayoutManager(linearLayoutManager); 
    adapter = new ClubNewsAdapter(getActivity(), listItemsList); 
    mRecyclerView.setAdapter(adapter); 

    if(savedInstanceState!=null){ 
     listItemsList = savedInstanceState.getParcelableArrayList(CLUB_NEWS); 

    } 

    return v; 
} 

@Override 
public void onActivityCreated(Bundle savedInstanceState) { 
    super.onActivityCreated(savedInstanceState); 
    if(savedInstanceState==null) { 
     updateClubNewsList(); 
    } 
} 

public void updateClubNewsList() { 

    listItemsList.clear(); 

    //declare the adapter and attach it to the recyclerview 

    // Instantiate the RequestQueue. 
    RequestQueue queue = Volley.newRequestQueue(getActivity()); 

    // Request a string response from the provided URL. 
    JsonArrayRequest jsObjRequest = new JsonArrayRequest(Request.Method.GET, Config.URL_CLUB_NEWS, new Response.Listener<JSONArray>() { 

     @Override 
     public void onResponse(JSONArray response) { 

      Log.d(TAG, response.toString()); 
      //hidePD(); 

      // Parse json data. 
      // Declare the json objects that we need and then for loop through the children array. 
      // Do the json parse in a try catch block to catch the exceptions 
      try { 



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

        JSONObject post = response.getJSONObject(i); 
        ClubNewsObject item = new ClubNewsObject(); 
        item.setTitle(post.getString("title")); 
        item.setImage(IMAGE_URL + post.getString("images")); 
        item.setArticle(post.getString("article")); 


        listItemsList.add(item); 

       } 
      } catch (JSONException e) { 
       e.printStackTrace(); 
      } 

      // Update list by notifying the adapter of changes 
      adapter.notifyDataSetChanged(); 
     } 
    }, new Response.ErrorListener() { 
     @Override 
     public void onErrorResponse(VolleyError error) { 
      VolleyLog.d(TAG, "Error: " + error.getMessage()); 
      //hidePD(); 
     } 
    }); 
    queue.add(jsObjRequest); 

} 

@Override 
public void onSaveInstanceState(Bundle outState) { 
    super.onSaveInstanceState(outState); 

    outState.putParcelableArrayList(CLUB_NEWS,listItemsList); 
} 

} 

我认为所有的窍门是,我成功地恢复所有的数据片段的onCreateView(...)方法中。

任何想法?

谢谢,

泰奥。

编辑

在我的适配器代码我已经把所谓的setClubNews一个额外的方法。

public class ClubNewsAdapter extends RecyclerView.Adapter<ClubNewsRowHolder> { 

private List<ClubNewsObject> clubNewsObjectList; 
private Context mContext; 
private ImageLoader mImageLoader; 
private int focused = 0; 

public ClubNewsAdapter(Activity activity, List<ClubNewsObject> clubNewsObjectList){ 
    this.clubNewsObjectList = clubNewsObjectList; 
    this.mContext = activity; 
} 
@Override 
public ClubNewsRowHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.club_news_row,null); 

    final ClubNewsRowHolder holder = new ClubNewsRowHolder(v); 
    return holder; 
} 

@Override 
public void onBindViewHolder(ClubNewsRowHolder holder, int position) { 
    final ClubNewsObject listItems = clubNewsObjectList.get(position); 
    holder.itemView.setSelected(focused==position); 

    holder.getLayoutPosition(); 

    mImageLoader = AppController.getInstance().getImageLoader(); 

    holder.thumbnail.setImageUrl(listItems.getImage(),mImageLoader); 
    holder.thumbnail.setDefaultImageResId(R.drawable.reddit_placeholder); 

    holder.name.setText(Html.fromHtml(listItems.getTitle())); 
    holder.relativeLayout.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      String title = listItems.getTitle(); 
      String article = listItems.getArticle(); 
      String image = listItems.getImage(); 
      Intent i = new Intent(mContext, Extras.class); 
      i.putExtra("title",title); 
      i.putExtra("article",article); 
      i.putExtra("image",image); 
      mContext.startActivity(i); 
      //Toast.makeText(mContext,"You clicked",Toast.LENGTH_SHORT).show(); 
      //Intent intent = new Intent(mContext,WebActivity.class); 
      //intent.putExtra("url",postUrl); 
      // mContext.startActivity(intent); 
     } 
    }); 
} 

@Override 
public int getItemCount() { 
    return (null != clubNewsObjectList?clubNewsObjectList.size() :0); 
} 

public void setClubNews(ArrayList<ClubNewsObject> clNews) { 

     clubNewsObjectList = clNews; 
    //update the adapter to reflect the new set of movies 
    notifyDataSetChanged(); 
    } 
} 

然后我恢复onCreateView里面的数据后,把它称为。

if(savedInstanceState!=null){ 
     ArrayList<ClubNewsObject> items = 
     savedInstanceState.getParcelableArrayList(CLUB_NEWS); 
     adapter.setClubNews(items); 
    }else{ 
     updateClubNewsList(); 
    } 

但仍然web服务在设备旋转后运行。

当你旋转你的屏幕。您的活动状态将被存储并将传递给片段的onActivityCreated方法。因此,如果检查CLUB_NEWS键是否存在于Bundle中,并且Bundle不为空,您可能会做些什么。

@Override 
protected void onActivityCreated(Bundle state){ 
    if(state != null){ 
     //fill adapter with data from 
     // state using CLUB_NEWS key 

    }else{ 

     //fill adapter with data from 
     // web service 
    } 

}

PS;无法输入很多,在我的手机上

+0

这是我不明白。如何从CLUB_NEWS键填充适配器! – Theo

+0

您的适配器代码在哪里?通常对于那种数据你可以继承ArrayAdapter – peter

+0

请看我的编辑。适配器在那里。 – Theo

好的。我修好了它。我不得不在我的主要活动中保存片段的状态:)。