我的列表视图在旋转屏幕时不会保存;使用包裹式接口和 onSaveInstanceState



用户提交查询并搜索 API 后,将填充一个列表。但是当我切换到风景时,它就消失了。我需要以某种方式保存它。我实现了一个可包裹的接口,并添加了覆盖和恢复 onSaveInstanceState 的方法。我在这里所拥有的对我的应用程序的性能没有影响,不幸的是,我对新代码不够熟悉,无法弄清楚我做错了什么。我在网上找到的大部分内容都假设我知道的比我做的多哈哈。任何建议不胜感激。谢谢!

public class MainActivity extends AppCompatActivity {
Book myClass;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Find the ListView.xml in the view hierarchy.
ListView listItemView = (ListView) findViewById(R.id.list);
// Shows an empty text view when there's nothing to show
mEmptyStateTextView = (TextView) findViewById(R.id.empty_view);
listItemView.setEmptyView(mEmptyStateTextView);
// Create a new adapter that takes an empty list of books as input
mAdapter = new BookAdapter(this, new ArrayList<Book>());
// Hide loading indicator because the data has been loaded
View loadingIndicator = findViewById(R.id.loading_indicator);
loadingIndicator.setVisibility(View.GONE);
// Populates the adapter with the list view xml file
listItemView.setAdapter(mAdapter);
handleIntent(getIntent());
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable("obj", myClass);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
myClass=savedInstanceState.getParcelable("obj");
}

还有我的自定义课程:

public class Book implements Parcelable {
private int mData;
// Book title
private String mTitle;
// Book author
private String mAuthor;
/**
* Create a new Book object
* @param title is the title of the book
* @param author is the author of the book
*/
public Book(String title, String author) {
mTitle = title;
mAuthor = author;
}
//Get the title of the book.
public String getTitle() {
return mTitle;
}
//Get the author of the book.
public String getAuthor() {
return mAuthor;
}
protected Book(Parcel in) {
mTitle = in.readString();
mAuthor = in.readString();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mTitle);
dest.writeString(mAuthor);
}
public static final Parcelable.Creator<Book> CREATOR = new Parcelable.Creator<Book>() {
@Override
public Book createFromParcel(Parcel in) {
return new Book(in);
}
@Override
public Book[] newArray(int size) {
return new Book[size];
}
};
}

和我的列表适配器:

public class BookAdapter extends ArrayAdapter<Book> {
//constructor
public BookAdapter(Activity context, ArrayList<Book> books) {
super(context, 0, books);
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
// control-O automatically created
View listItemView = convertView;
if(listItemView == null) {
listItemView = LayoutInflater.from(getContext()).inflate(R.layout.list_item, parent, false);
}
// Get the book at the current position on the list
Book currentBook = getItem(position);
// Find the TextView in the list_item.xml with this ID
TextView titleTextView = (TextView) listItemView.findViewById(R.id.title_text);
// Get the title from the current Book object and set it on the TextView
titleTextView.setText(currentBook.getTitle());
// Find the TextView in the list_item.xml with this ID
TextView authorTextView = (TextView) listItemView.findViewById(R.id.author_text);
// Get the title from the current Book object and set it on the TextView
authorTextView.setText(currentBook.getAuthor());
// Return the whole list item layout (containing 2 TextViews)
// so that it can be shown in the ListView
return listItemView;
}
}

用这行

mAdapter = new BookAdapter(this, new ArrayList<Book>());

您正在将空的书籍列表传递给列表视图的适配器。因此,您的列表视图将是空的,因为它没有要显示的内容。

然后,您保存myClass如我所见,该内容从未实例化,因此您正在保存一个空对象。然后还原此空对象。

您必须做的是:

  • 创建一个书籍列表并将它们放入ArrayList
  • 将以前创建的ArrayList传递到您的Adapter
  • 若要在旋转前保存数据,必须将ArrayList保存到onSaveInstanceState方法
  • 要在轮换后恢复数据,您必须将ArrayList重新获取到onRestoreInstanceState方法
  • 然后使用还原的数据重新创建适配器,并将其重新分配给列表视图

更新

在 Book myClass 级别声明您的 ArrayListArrayList<Book> bookList;

尝试拆分此行

mAdapter = new BookAdapter(this, new ArrayList<Book>());

分为这两行:

bookList = new ArrayList<Book>();
mAdapter = new BookAdapter(this, bookList);

然后在你的onSaveInstanceState

outState.putParcelableArrayList("bookList", bookList);

在你的onRestoreInstanceState

bookList = savedInstanceState.getParcelableArrayList("bookList");

之后,您必须重新创建Adapter并将其重新分配给ListView

这应该是正确的方式

首先创建公共ArrayList<Book> list对象,您可以将其设置为 适配器

ArrayList<Book> list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayList list = new ArrayList<Book>();
list = getListData()// assign list values to list object
.....
mAdapter = new BookAdapter(this, list);
.....
.....
listItemView.setAdapter(mAdapter);
}

当应用程序获得旋转活动时onSaveInstanceState和销毁的活动。因此,您应该将该列表值设置为 saveInstatantState 对象

@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putParcelableArrayList("obj", list);
super.onSaveInstanceState(outState);
}

之后,您可以在 Activity 上发生回调方法时获取该传递数据值onRestoreInstanceState并且您应该将该列表设置为适配器并刷新列表视图,如果您可以使用回收器视图而不是列表视图。

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if (savedInstanceState != null) {
list = savedInstanceState.getParcelableArrayList("obj");
if (list != null) {
mAdapter.addAll(list);
......
listItemView.setAdapter(mAdapter);
}
}
}

我希望您能通过此解决方案获得解决方案,这不是完整的源代码更正。 这是您应该在技术上执行的解决方案。

问题是,当OrientationActivity中更改时,它会重新渲染布局。要停止此操作并保留布局视图,请在android manifest file中添加以下内容:

android:configChanges="orientation"

这将在方向更改时覆盖默认行为。

最新更新