在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;无法输入很多,在我的手机上
答
好的。我修好了它。我不得不在我的主要活动中保存片段的状态:)。
这是我不明白。如何从CLUB_NEWS键填充适配器! – Theo
您的适配器代码在哪里?通常对于那种数据你可以继承ArrayAdapter – peter
请看我的编辑。适配器在那里。 – Theo