我有一个ArrayList,其中包含从Volley获取的自定义json对象。我希望能够在屏幕旋转上保存和恢复这些对象。我还想在屏幕旋转时保存并恢复当前的滚动位置。
我有一个粗略的想法,可以用onSaveInstanceState和onRestoreInstanceState来完成吗?
活动代码
delay()
提前致谢。
请注意How to save custom ArrayList on Android screen rotate?的副本。虽然该问题中的arraylist在活动中被宣布,但是我的网络中有凌空抽射。我不知道如何为我的arraylist实现它,否则不会问这个问题
答案 0 :(得分:1)
事实上,这是the post you mentioned的副本。是的,列表是在该帖子中活动的onCreate()中声明的,而您是异步进行的。但是,这个想法是一样的。
一旦有数据要发送,您可以在应用程序的任何位置保存和恢复数据。
在您的情况下,密钥是每次旋转设备时都不调用getData()。如果已经在mPostItemsList中加载了数据,则通过onSaveInstanceState()保存并恢复它,并在onCreate()中获取保存状态的数据。如果该数据不存在,则调用getData()。
public class MainActivity extends AppCompatActivity {
private final String TAG = "MainActivity";
private final String KEY_POST_ITEMS = "#postitems";
//Creating a list of posts
private List<PostItems> mPostItemsList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initializeViews();
if (savedInstanceState != null && savedInstanceState.containsKey(KEY_POST_ITEMS)){
mPostItemsList = savedInstanceState.getParcelableArrayList(KEY_POST_ITEMS);
} else {
//Initializing the postlist
mPostItemsList = new ArrayList<>();
if (NetworkCheck.isAvailableAndConnected(this)) {
//Caling method to get data
getData();
} else {
showNoNetworkDialog();
}
}
mAdapter = new PostAdapter(mPostItemsList, this);
recyclerView.setAdapter(adapter);
}
private void parseData(JSONArray array){
mPostItemsList.clear();
for(int i = 0; i<array.length(); i++) {
PostItems postItem = new PostItems();
JSONObject jsonObject = null;
try {
jsonObject = array.getJSONObject(i);
postItem.setPost_title(jsonObject.getString(ConfigPost.TAG_POST_TITLE));
postItem.setPost_body(jsonObject.getString(ConfigPost.TAG_POST_BODY));
} catch (JSONException w) {
w.printStackTrace();
}
mPostItemsList.add(postItem);
}
mAdapter.notifyDataSetchanged();
}
编辑:我没有看到保存滚动位置的要求。请查看Emin Ayar's answer。此外,它的类似答案也在这里:How to save recyclerview scroll position。
答案 1 :(得分:0)
您可以在活动中使用onConfigurationChanged
来检测轮换变化。此外,您应该使用lastVisibleItemPosition
跟踪layoutManager.findLastVisibleItemPosition()
,当轮换更改时,您应该滚动到此位置。您需要使用recyclerView.setOnScrollListener()
收听滚动条以保持lastVisibleItemPosition
更新
public class MainActivity extends AppCompatActivity {
private final String TAG = "MainActivity";
//Creating and initializing list of posts
private List<PostItems> mPostItemsList = new ArrayList<>();;
//Creating Views
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private RecyclerView.LayoutManager layoutManager;
private ProgressDialog mProgressDialog;
private int lastVisibleItemPos = -1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "Device rotated and onCreate called");
if (NetworkCheck.isAvailableAndConnected(this)) {
//Caling method to get data and check if postList have value set before or not
// because this part will be called on every rotation change, we are controlling this
if (mPostItemsList.size() <= 0) {
//Initializing Views
recyclerView = (RecyclerView) findViewById(R.id.post_recycler);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
adapter = new PostAdapter(mPostItemsList, this);
recyclerView.setAdapter(adapter);
getData();
}
} else {
final Context mContext;
mContext = this;
final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle(R.string.alert_titl);
alertDialogBuilder.setMessage(R.string.alert_mess);
alertDialogBuilder.setPositiveButton(R.string.alert_posi, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (!NetworkCheck.isAvailableAndConnected(mContext)) {
alertDialogBuilder.show();
} else {
getData();
}
}
});
alertDialogBuilder.setNegativeButton(R.string.alert_nega, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
alertDialogBuilder.show();
}
}
//This method will get data from the web api
private void getData(){
Log.d(TAG, "getData called");
//Showing progress dialog
mProgressDialog = new ProgressDialog(MainActivity.this);
mProgressDialog.setCancelable(false);
mProgressDialog.setMessage(this.getResources().getString(R.string.load_post));
mProgressDialog.show();
//Creating a json request
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(ConfigPost.GET_URL,
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
Log.d(TAG, "onResponse called");
//Dismissing the progress dialog
if (mProgressDialog != null) {
mProgressDialog.hide();
}
/*progressDialog.dismiss();*/
//calling method to parse json array
parseData(response);
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
//Creating request queue
RequestQueue requestQueue = Volley.newRequestQueue(this);
//Adding request to the queue
requestQueue.add(jsonArrayRequest);
}
//This method will parse json data
private void parseData(JSONArray array){
Log.d(TAG, "Parsing array");
for(int i = 0; i<array.length(); i++) {
PostItems postItem = new PostItems();
JSONObject jsonObject = null;
try {
jsonObject = array.getJSONObject(i);
postItem.setPost_title(jsonObject.getString(ConfigPost.TAG_POST_TITLE));
postItem.setPost_body(jsonObject.getString(ConfigPost.TAG_POST_BODY));
} catch (JSONException w) {
w.printStackTrace();
}
mPostItemsList.add(postItem);
}
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// set your adapter here with your data
adapter = new PostAdapter(mPostItemsList, this);
recyclerView.setAdapter(adapter);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy called");
if (mProgressDialog != null){
mProgressDialog.dismiss();
Log.d(TAG, "mProgress dialog dismissed");
}
}