我有一个包含100多个对象的数据库。每个对象都有一个特定的图像文件名,主题字符串,标题字符串和pdf文件名。
我有一个活动,它是对象的网格视图。
首次创建时,网格视图将加载要显示的对象数组。数组的确切内容可能会有所不同,具体取决于我在首次打开活动时运行的数据库查询。
默认设置是从数据库中检索并显示所有对象。但是我有时只检索和显示对象的一个子集(基于主题)。
单击网格中的按钮将打开一个活动,该活动显示该对象的pdf。很好
问题是,当我从PDF活动中“返回”时,将重新创建网格视图。始终使用“默认”所有对象。
因此,如果我有一个仅显示某个“主题”对象的网格视图,则如果我打开pdf活动,则返回时将重新创建网格视图并显示所有对象,而不显示pdf活动之前的原始网格视图开始。
问题: 1)如何在不重新创建网格视图的情况下返回网格视图?
代码:
public class SubjectListActivity extends AppCompatActivity {
String DB_NAME = "XXXXX.sqlite";
String TABLE_NAME = "XXXXX";
DataBaseHelper myDBHelper;
private GridView gridView;
private MyAdapter myAdapter;
private ArrayList<Subject> subjectsArrayList;
private Context context;
private String subjectAreas = ""; // this is sent to the activity from whichever activity opened it.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_subject_list);
Bundle extras = getIntent().getExtras();
if (extras != null) {
subjectAreas = extras.getString("subjectAreas");
}
gridView = findViewById(R.id.gv);
// Database
AssetDatabaseOpenHelper assetDatabaseOpenHelper = new AssetDatabaseOpenHelper(this, DB_NAME);
assetDatabaseOpenHelper.saveDatabase();
myDBHelper = new DataBaseHelper(this, DB_NAME);
// populates subjectsArray
subjectsArrayList = populateSubjects();
loadGrid();
// listener
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String title = subjectsArrayList.get(position).getSubjectTitle();
String iconStyle = subjectsArrayList.get(position).getSubjectIconStyle();
String pdf = subjectsArrayList.get(position).getSubjectPDF();
String ref = subjectsArrayList.get(position).getSubjectRefs();
String linked = subjectsArrayList.get(position).getSubjectLinked();
Intent intent = new Intent(view.getContext(), SubjectActivity.class);
intent.putExtra("title", title);
intent.putExtra("icon", iconStyle);
intent.putExtra("pdf", pdf);
intent.putExtra("ref", ref);
intent.putExtra("linked", linked);
intent.putExtra("subjectAreas", subjectAreas);
startActivityForResult(intent, 1);
}
});
}
private void loadGrid(){
myAdapter = new MyAdapter(getApplicationContext(), subjectsArrayList);
gridView.setAdapter(myAdapter);
}
// The SQL query that populates the subjectArray depends on the 'subjectAreas' string which is set when the activity first opens. The default is 'getAllSubjects'
private ArrayList<Subject> populateSubjects() {
Cursor res = myDBHelper.getAllSubjects(TABLE_NAME);
if (subjectAreas.equals("emerg")){res = myDBHelper.getEmergSubjects(TABLE_NAME);}
else if (subjectAreas.equals("all")){res = myDBHelper.getAllSubjects(TABLE_NAME);}
else if (subjectAreas.equals("ax")){res = myDBHelper.getAxSubjects(TABLE_NAME);}
else if (subjectAreas.equals("mx")){res = myDBHelper.getMxSubjects(TABLE_NAME);}
else if (subjectAreas.equals("ref")){res = myDBHelper.getRefSubjects(TABLE_NAME);}
else if (subjectAreas.equals("cal")){res = myDBHelper.getCalSubjects(TABLE_NAME);}
else if (subjectAreas.equals("search")){res = myDBHelper.getSearchSubjects(TABLE_NAME, keywords);}
ArrayList<Subject> list = new ArrayList<>();
if (res.getCount() == 0) {
} else {
while (res.moveToNext()) {
Subject subject = new Subject();
subject.setSubjectID(res.getString(0));
subject.setSubjectTitle(res.getString(1));
subject.setSubjectIconStyle(res.getString(2));
subject.setSubjectPDF(res.getString(3));
subject.setSubjectKeywords(res.getString(4));
subject.setSubjectLinked(res.getString(5));
subject.setSubjectRefs(res.getString(6));
list.add(subject);
}
}
return list;
}
// Tried sending 'back' subjectAreas from PDF activity and re-populating the array and gridview - this doesn't seem to be called
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1) {
if(resultCode == RESULT_OK) {
subjectAreas = data.getStringExtra("subjectAreas");
subjectsArrayList = populateSubjects();
myAdapter = new MyAdapter(getApplicationContext(), subjectsArrayList);
gridView.invalidateViews();
gridView.setAdapter(myAdapter);
}
}
}
}
预先感谢
更新: 使用savedInstanceState“保存”我的subjectAreas字符串,我使用了以下内容:
private String subjectAreas = "";
private static final String subjectAreasSaved = "";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_subject_list);
Bundle extras = getIntent().getExtras();
if (extras != null) {
subjectAreas = extras.getString("subjectAreas");
title = extras.getString("title");
keywords = extras.getStringArrayList("keywords");
}
// Check whether we're recreating a previously destroyed instance
if (savedInstanceState != null) {
// Restore value of members from saved state
subjectAreas = savedInstanceState.getString(subjectAreasSaved);
}
并且:
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putString(subjectAreasSaved, subjectAreas);
super.onSaveInstanceState(savedInstanceState);
}
当第二个活动是开放式活动时,onSaveINstanceState是自动调用的还是我需要调用它?目前似乎什么也没发生
答案 0 :(得分:2)
娱乐取决于框架。如果它确定需要资源,则无论是否需要它都会销毁先前的副本。你无法阻止它。
您可以做的是实现onSaveInstanceState和onRestoreInstanceState来保存需要从该确切状态重新创建的所有数据。
答案 1 :(得分:0)
首先,应该对帮助很大的作者们表示敬意。
我的代码问题得到了很好的解释,并通过以下线程解决了:Stackoverflow thread
基本上,操作栏中的“主页”按钮会导致重新创建上一个活动。因此,我的问题。当我尝试实现InstanceState时,我一直为saveInstanceState获取一个'null'...然后将我引向我上面链接的线程。
我真的希望这对其他人有帮助