更改设备方向后如何保存 ArrayList 数据并在 AutoCompleteTextView 中使用
How to save ArrayList data and use in AutoCompleteTextView , after change device orientation
我有 tride saveInstanceState 它实际上有助于保存数据但是 AutoCompleteTextView 没有 看到任何数据(在日志中我看到数据存在并且它们是正确的)
然后我第二次改变方向,在日志中看到 ArrayList = null;
这里有一些代码
...
public class AddDayActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor>
...
ArrayAdapter<String> adapter;
private AutoCompleteTextView edit_day_name;
private ArrayList<String> autoCompleteList;
private ArrayList<Integer> autoCompleteListPrice;
...
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.add_pay_day);
autoCompleteList = new ArrayList<String>(); //Array list witch need to save
autoCompleteListPrice = new ArrayList<Integer>();//Array list witch need to save
...
edit_day_name = findViewById(R.id.edit_day_name); //AutoCompleteTextView
...
if (savedInstanceState != null) {
autoCompleteList.addAll(Objects.requireNonNull(savedInstanceState.getStringArrayList("BundleAutoCompleteList")));
autoCompleteListPrice.addAll(Objects.requireNonNull(savedInstanceState.getIntegerArrayList("BundleAutoCompleteListPrice")));
Log.d(UtilContract.LOG_KEY, " onRestoreInstanceState Working " + savedInstanceState.getIntegerArrayList("BundleAutoCompleteList")
+ "\n" +
savedInstanceState.getIntegerArrayList("BundleAutoCompleteListPrice")
+ "\n" + autoCompleteList + "\n" + autoCompleteListPrice);
}
adapter = new ArrayAdapter<String>(this,
R.layout.dropdown_menu_popup_item, autoCompleteList);
Log.d(UtilContract.LOG_KEY, ".." + autoCompleteList);
edit_day_name.setAdapter(adapter);
...
LoaderManager.getInstance(this).initLoader(NAME_UNIC_LOADER, null, this);
...
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
//Save data in Bundle
outState.putStringArrayList("BundleAutoCompleteList", autoCompleteList);
outState.putIntegerArrayList("BundleAutoCompleteListPrice", autoCompleteListPrice);
Log.d(UtilContract.LOG_KEY, " savedInstanceState Save " + autoCompleteListPrice + "\n" + autoCompleteList);
}
从 SQL 数据库
填充数组的加载程序
@NonNull
@Override
public Loader<Cursor> onCreateLoader(int id, @Nullable Bundle args) {
String[] projection = {
UtilContract.KEY_ID,
KEY_NAME_DETAIL,
KEY_PRICE_OF_DETAIL
};
CursorLoader cursorLoader = new CursorLoader(this,
UtilContract.DetailTable.CONTENT_URI,
projection,
null,
null,
KEY_NAME_DETAIL
);
Log.d(LOG_KEY, " CursorLoader DetailTable " + cursorLoader);
return cursorLoader;
}
@Override
public void onLoadFinished(@NonNull Loader<Cursor> loader, Cursor data) {
int count = data.getCount();
if (autoCompleteList.isEmpty() || autoCompleteListPrice.isEmpty()) {
//
while (data.moveToNext()) {
autoCompleteList.add(data.getString(data.getColumnIndexOrThrow(KEY_NAME_DETAIL)));
autoCompleteListPrice.add(data.getInt(data.getColumnIndexOrThrow(KEY_PRICE_OF_DETAIL)));
}
} else {
//
autoCompleteList.clear();
autoCompleteListPrice.clear();
//
while (data.moveToNext()) {
autoCompleteList.add(data.getString(data.getColumnIndexOrThrow(KEY_NAME_DETAIL))); autoCompleteListPrice.add(data.getInt(data.getColumnIndexOrThrow(KEY_PRICE_OF_DETAIL)));
}
}
Log.d(LOG_KEY, " Cursor DetailTable " + data + " count " + count);
}
@Override
public void onLoaderReset(@NonNull Loader<Cursor> loader) {
adapter.clear();
}
在这种情况下如何正确保存 AutoComplateView 的数据?
PS: 我用 "androidx" 和 " .material:1.1.0-alpha09" 来自 AutoComplateView "ExposedDropdownMenu"
代码量太少,无法确定,但据我所知,问题可能出在 Loader 实现及其与其余代码的同步上。
Loaded 异步加载数据。这意味着在您旋转设备后,您的代码执行良好,但加载程序开始再次加载。在实际开始加载之前,它会调用 onLoaderReset
,其中包含 adapter.clear()
调用。因此,来自适配器的所有数据都消失了,因此 AutocompleteTextView
没有任何显示。
我还可以在 onLoadFinished
方法中看到您检索数据但没有将其设置到适配器中 - 因此适配器是空的。
再来一次 - 我不确定是不是这个原因,因为代码不完整,但我希望它能以某种方式帮助你。
我有 tride saveInstanceState 它实际上有助于保存数据但是 AutoCompleteTextView 没有 看到任何数据(在日志中我看到数据存在并且它们是正确的) 然后我第二次改变方向,在日志中看到 ArrayList = null; 这里有一些代码
...
public class AddDayActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor>
...
ArrayAdapter<String> adapter;
private AutoCompleteTextView edit_day_name;
private ArrayList<String> autoCompleteList;
private ArrayList<Integer> autoCompleteListPrice;
...
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.add_pay_day);
autoCompleteList = new ArrayList<String>(); //Array list witch need to save
autoCompleteListPrice = new ArrayList<Integer>();//Array list witch need to save
...
edit_day_name = findViewById(R.id.edit_day_name); //AutoCompleteTextView
...
if (savedInstanceState != null) {
autoCompleteList.addAll(Objects.requireNonNull(savedInstanceState.getStringArrayList("BundleAutoCompleteList")));
autoCompleteListPrice.addAll(Objects.requireNonNull(savedInstanceState.getIntegerArrayList("BundleAutoCompleteListPrice")));
Log.d(UtilContract.LOG_KEY, " onRestoreInstanceState Working " + savedInstanceState.getIntegerArrayList("BundleAutoCompleteList")
+ "\n" +
savedInstanceState.getIntegerArrayList("BundleAutoCompleteListPrice")
+ "\n" + autoCompleteList + "\n" + autoCompleteListPrice);
}
adapter = new ArrayAdapter<String>(this,
R.layout.dropdown_menu_popup_item, autoCompleteList);
Log.d(UtilContract.LOG_KEY, ".." + autoCompleteList);
edit_day_name.setAdapter(adapter);
...
LoaderManager.getInstance(this).initLoader(NAME_UNIC_LOADER, null, this);
...
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
//Save data in Bundle
outState.putStringArrayList("BundleAutoCompleteList", autoCompleteList);
outState.putIntegerArrayList("BundleAutoCompleteListPrice", autoCompleteListPrice);
Log.d(UtilContract.LOG_KEY, " savedInstanceState Save " + autoCompleteListPrice + "\n" + autoCompleteList);
}
从 SQL 数据库
填充数组的加载程序 @NonNull
@Override
public Loader<Cursor> onCreateLoader(int id, @Nullable Bundle args) {
String[] projection = {
UtilContract.KEY_ID,
KEY_NAME_DETAIL,
KEY_PRICE_OF_DETAIL
};
CursorLoader cursorLoader = new CursorLoader(this,
UtilContract.DetailTable.CONTENT_URI,
projection,
null,
null,
KEY_NAME_DETAIL
);
Log.d(LOG_KEY, " CursorLoader DetailTable " + cursorLoader);
return cursorLoader;
}
@Override
public void onLoadFinished(@NonNull Loader<Cursor> loader, Cursor data) {
int count = data.getCount();
if (autoCompleteList.isEmpty() || autoCompleteListPrice.isEmpty()) {
//
while (data.moveToNext()) {
autoCompleteList.add(data.getString(data.getColumnIndexOrThrow(KEY_NAME_DETAIL)));
autoCompleteListPrice.add(data.getInt(data.getColumnIndexOrThrow(KEY_PRICE_OF_DETAIL)));
}
} else {
//
autoCompleteList.clear();
autoCompleteListPrice.clear();
//
while (data.moveToNext()) {
autoCompleteList.add(data.getString(data.getColumnIndexOrThrow(KEY_NAME_DETAIL))); autoCompleteListPrice.add(data.getInt(data.getColumnIndexOrThrow(KEY_PRICE_OF_DETAIL)));
}
}
Log.d(LOG_KEY, " Cursor DetailTable " + data + " count " + count);
}
@Override
public void onLoaderReset(@NonNull Loader<Cursor> loader) {
adapter.clear();
}
在这种情况下如何正确保存 AutoComplateView 的数据?
PS: 我用 "androidx" 和 " .material:1.1.0-alpha09" 来自 AutoComplateView "ExposedDropdownMenu"
代码量太少,无法确定,但据我所知,问题可能出在 Loader 实现及其与其余代码的同步上。
Loaded 异步加载数据。这意味着在您旋转设备后,您的代码执行良好,但加载程序开始再次加载。在实际开始加载之前,它会调用 onLoaderReset
,其中包含 adapter.clear()
调用。因此,来自适配器的所有数据都消失了,因此 AutocompleteTextView
没有任何显示。
我还可以在 onLoadFinished
方法中看到您检索数据但没有将其设置到适配器中 - 因此适配器是空的。
再来一次 - 我不确定是不是这个原因,因为代码不完整,但我希望它能以某种方式帮助你。