我正在设置一个像这样的ListView适配器:
public class SeeAllQuestionsActivity extends Activity
{
//ArrayAdapter<Question> adapter;
SimpleAdapter mSchedule = null;
ListView list = new ListView (this);
TextView loading_questions = null;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.all_question_page);
TextView loading_questions = (TextView) findViewById(R.id.loading_questions);
list = (ListView) findViewById(R.id.list);
ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
HashMap<String, String> map = new HashMap<String, String>();
mSchedule = new SimpleAdapter(this, mylist, R.layout.questions_list,
new String[] {"train", "from", "to"},
new int[] {R.id.TRAIN_CELL, R.id.FROM_CELL, R.id.TO_CELL});
list.setAdapter(mSchedule);
list.setTextFilterEnabled(true);
list.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View view,
int position, long id)
{
...
然后进行远程Asynch调用以从我的数据库中获取列表,并尝试在onPostExecute方法中执行此操作:
ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
HashMap<String, String> map = new HashMap<String, String>();
try
{
JSONArray obj = new JSONArray(result);
if ( obj != null )
{
for ( int i = 0; i < obj.length(); i++ )
{
JSONObject o = obj.getJSONObject(i);
map.put("train", "Business Name");
map.put("from", ">");
map.put("to", ">");
mylist.add(map);
map = new HashMap<String, String>();
map.put("train", "103(x)");
map.put("from", "6:35 AM");
map.put("to", "7:45 AM");
mylist.add(map);
}
}
}
catch ( Exception e )
{
}
list.setAdapter(mSchedule);
但是我在这一行得到了Null Pointer异常:
ListView list = new ListView (this);
但我认为通常我在postExecute方法中需要完成这项工作。任何有关如何正确执行此操作的帮助都非常感谢。
答案 0 :(得分:1)
我记得并且作为一个合乎逻辑的结论:在您致电的那一刻,此的引用为 null 。 此将在 ListView 的构造函数中访问,因此将引发 NullPointerException 。如果您想动态创建它,则必须在活动的 onCreate 方法中调用 ListView 构造函数。
至少最好按照MartijnVanMierloo的建议实施,如果可能的话。
答案 1 :(得分:1)
在 OnCreate 中,您可以定义一个新的SimpleAdapter并将其附加到ListView。这是对的。数据源(在您的情况下为mylist
)此时为空,因此您将在AsyncTask
填充它。
在 onPostExecute 中,您正在创建新的ArrayList
。根据您收到的结果,您可以填写它。执行此操作后,您将再次设置适配器。由于适配器没有数据,因此无法执行任何操作。您要执行的操作是将新填充的列表提供给适配器,以便它可以使用您的数据填充ListView
。
解决方案1
onPostExecute {
// create a list to store your data
new ArrayList
// fill the new list with the data you received (result)
fillArrayList from JSON
// create an adapter and give the new list with it
mAdapter = new SimpleAdapter(.., ArrayList, ...)
listView.setAdapter(mAdapter);
}
这是你可以做到的一种方式,适合你当前的实施。
解决方案2
我会选择这个解决方案
onPostExecute {
// don't create a new arraylist but use the mylist-object you created in the OnCreate
fill mylist object with new data
// mylist is the datasource of your adapter and it is now changed.
// let the ListView know his adapter received new information
mSchedule.notifyDataSetChanged
}
<强>更新强>
结帐this tutorial。我使用相同的布局和相同的源来填充我的列表,但我已经改变它,所以它类似于你的情况。祝你好运:)
MainActivity
public class MainActivity extends Activity {
private List<HashMap<String, String>> fillMaps;
private SimpleAdapter adapter;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView lv = (ListView) findViewById(R.id.listview);
String[] from = new String[] { "rowid", "col_1", "col_2", "col_3" };
int[] to = new int[] { R.id.item1, R.id.item2, R.id.item3, R.id.item4 };
// My data
fillMaps = new ArrayList<HashMap<String, String>>();
// Create an adapter which will tell my ListView what to show..
// fillMaps is still empty so at the moment it my ListView will show
// nothing.
adapter = new SimpleAdapter(this, fillMaps, R.layout.row, from, to);
lv.setAdapter(adapter);
// Retreive data from somewhere
new UpdateListWithAsyncTask().execute();
}
private class UpdateListWithAsyncTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... params) {
// do stuff
return null;
}
protected void onPostExecute(Void result) {
// Fill your datasource that your adapter has. In my case fillMaps
for (int i = 0; i < 10; i++) {
HashMap<String, String> map = new HashMap<String, String>();
map.put("rowid", "" + i);
map.put("col_1", "col_1_item_" + i);
map.put("col_2", "col_2_item_" + i);
map.put("col_3", "col_3_item_" + i);
fillMaps.add(map);
}
// my datasource is now changed, I want my adapter to know this and
// update my ListView
adapter.notifyDataSetChanged();
}
}
}