【发布时间】:2022-07-22 00:47:23
【问题描述】:
主要目标:-
我有一份体育新闻列表。每个项目都包含一个运动名称和一些信息。单击它将显示有关该特定运动的最新消息。用户可以选择滑动以关闭新闻,如果他们不希望它在列表中,或者他们也可以拖放它,例如,如果他们想在其他新闻之上看到一些新闻。 列表中的每一项都以编程方式表示为一个 Sport.java 对象。
我想在设备方向更改时保留列表的状态。
我尝试过的:-
对于列表,我有一个运动对象数组列表 (ArrayList)。我了解到,要保存自定义对象列表,这些对象本身需要Parcelable。为此,我实现了 Parcelable.java 接口,如下所示:
package com.example.android.materialme;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.NonNull;
/**
* Data model for each row of the RecyclerView.
*/
class Sport implements Parcelable {
//Member variables representing the title and information about the sport
private String title;
private String info;
private String detail;
private final int imageResource;
/**
* Constructor for the Sport data model
* @param title The name if the sport.
* @param info Information about the sport.
*/
Sport(String title, String info, String detail, int imageResource) {
this.title = title;
this.info = info;
this.detail = detail;
this.imageResource = imageResource;
}
protected Sport(@NonNull Parcel in) {
title = in.readString();
info = in.readString();
detail = in.readString();
imageResource = in.readInt();
}
public static final Creator<Sport> CREATOR = new Creator<Sport>() {
@Override
public Sport createFromParcel(Parcel in) {
return new Sport(in);
}
@Override
public Sport[] newArray(int size) {
return new Sport[size];
}
};
String getTitle() {
return title;
}
String getInfo() {
return info;
}
int getImageResource(){
return imageResource;
}
String getDetail(){
return detail;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(title);
parcel.writeString(info);
parcel.writeString(detail);
parcel.writeInt(imageResource);
}
}
然后我用了
outState.putParcelableArrayList(KEY, sportsList);
但是,这不起作用。旋转设备时屏幕只是空白。
我尝试调试应用程序,发现数组列表正确传递,数据完整,只是应用程序由于某种原因无法显示它。
此外,fab 按钮的实现是在单击时将整个列表重置为其初始状态。工厂正常工作,但如果方向改变一次,它就会停止工作(应用程序不会崩溃)。改变方向也不能修复晶圆厂。因此,要再次获取列表以进行任何其他测试,我必须重新运行整个应用程序。
完整代码:-
MainActivity.java
package com.example.android.materialme;
import android.content.res.TypedArray;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.ArrayList;
import java.util.Collections;
public class MainActivity extends AppCompatActivity {
//Member variables
private RecyclerView mRecyclerView;
private ArrayList<Sport> mSportsData;
private SportsAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(view -> resetSports());
//Initialize the RecyclerView
mRecyclerView = (RecyclerView)findViewById(R.id.recyclerView);
//Set the Layout Manager
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
//Initialize the ArrayLIst that will contain the data
mSportsData = new ArrayList<>();
//Initialize the adapter and set it ot the RecyclerView
mAdapter = new SportsAdapter(this, mSportsData);
mRecyclerView.setAdapter(mAdapter);
initializeData(savedInstanceState);
ItemTouchHelper helper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(
ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT | ItemTouchHelper.UP | ItemTouchHelper.DOWN,
ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
int from = viewHolder.getAdapterPosition();
int to = target.getAdapterPosition();
Collections.swap(mSportsData, from, to);
mAdapter.notifyItemMoved(from, to);
return true;
}
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
mSportsData.remove(viewHolder.getAdapterPosition());
mAdapter.notifyItemRemoved(viewHolder.getAdapterPosition());
}
});
helper.attachToRecyclerView(mRecyclerView);
}
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelableArrayList("state", mSportsData);
}
/**
* Method for initializing the sports data from resources.
*/
private void initializeData(Bundle savedInstanceState) {
if(savedInstanceState!=null){
mSportsData.clear();
mSportsData = savedInstanceState.getParcelableArrayList("state");
} else {
//Get the resources from the XML file
String[] sportsList = getResources().getStringArray(R.array.sports_titles);
String[] sportsInfo = getResources().getStringArray(R.array.sports_info);
String[] sportsDetail = getResources().getStringArray(R.array.sports_detail);
TypedArray sportsImageResource = getResources().obtainTypedArray(R.array.sports_images);
//Clear the existing data (to avoid duplication)
mSportsData.clear();
//Create the ArrayList of Sports objects with the titles and information about each sport
for (int i = 0; i < sportsList.length; i++) {
mSportsData.add(new Sport(sportsList[i], sportsInfo[i], sportsDetail[i], sportsImageResource.getResourceId(i, 0)));
}
sportsImageResource.recycle();
}
//Notify the adapter of the change
mAdapter.notifyDataSetChanged();
}
public void resetSports(){
initializeData(null);
}
}
应用图片:-
#1 初始列表
#2 变更列表(运动篮球卡#2被刷)
【问题讨论】:
标签: java android android-recyclerview android-orientation onsaveinstancestate