这是我关于堆栈溢出的第一篇文章,所以如果感到困惑就道歉。
我在onClick方法中获取了foodListAdapter.notifyDatasetChanged()的nullpointer。
我正在使用自定义适配器。我的onClick方法在我的MainActivity类中。此外,请注意,如果我在我的onClick方法中注释掉foodListAdapter.notifyDataSetChanged并取消注释掉其他3行,我的代码工作正常。但我认为这不是最干净的方式。
public class MainActivity extends Activity implements View.OnClickListener
{
Button mainButton;
ListView mainListView;
ArrayAdapter spinnerDataAdapter;
FoodListAdapter foodListAdapter;
ArrayList newFoodList = new ArrayList();
ShareActionProvider mShareActionProvider;
private static final String PREFS = "prefs";
private static final String PREF_NAME = "name";
SharedPreferences mSharedPreferences;
Spinner mainSpinner;
TextView foodTextView;
CharSequence currentDate;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Access button in activity_main and set onClickListener
mainButton = (Button) findViewById(R.id.main_button);
mainButton.setOnClickListener(this);
//Access edit text in activity_main
foodTextView = (TextView) findViewById(R.id.food_textview);
//Access list view in activity_main
mainListView = (ListView) findViewById(R.id.main_listview);
mainSpinner = (Spinner) findViewById(R.id.main_spinner);
View header = (View)getLayoutInflater().inflate(R.layout.listview_header_row, null);
//Create an array foodListAdapter for the spinner
spinnerDataAdapter = ArrayAdapter.createFromResource(this, R.array.food_types, android.R.layout.simple_spinner_item);
mainSpinner.setAdapter(spinnerDataAdapter);
//Set this listview to react to items being pressed
// mainListView.setOnItemClickListener(this);
//Greet the user or ask for their name if they are new
displayWelcome();
//create food list and create foodListAdapter then set the foodListAdapter
newFoodList.add(new FoodItem(R.drawable.ic_chicken, "Chicken"));
FoodListAdapter adapter = new FoodListAdapter(this,
R.layout.listview_item_row, newFoodList);
mainListView.addHeaderView(header);
mainListView.setAdapter(adapter);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
//Access the Share Item defined in the menu XML
MenuItem shareItem = menu.findItem(R.id.menu_item_share);
//Access the object responsible for
//putting together the sharing submenu
if(shareItem !=null) {
mShareActionProvider = (ShareActionProvider)shareItem.getActionProvider();
}
return true;
}
public CharSequence getFormattedDate(){
Date d = new Date();
CharSequence s = DateFormat.format("MMMM d, yyyy ", d.getTime());
return s;
}
@Override
public void onClick(View v) {
currentDate = getFormattedDate();
foodTextView.setText(mainSpinner.getSelectedItem().toString());
newFoodList.add(new FoodItem(R.drawable.ic_chicken, mainSpinner.getSelectedItem().toString() + " was stored on: " + currentDate ));
foodListAdapter.notifyDataSetChanged();
// FoodListAdapter foodListAdapter = new FoodListAdapter(this,
// R.layout.listview_item_row, newFoodList);
// mainListView.setAdapter(foodListAdapter);
}
这是我的完整自定义适配器代码:
package com.vintage.freshulator;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
public class FoodListAdapter extends ArrayAdapter<FoodItem> {
Context context;
int layoutResourceId;
ArrayList<FoodItem> data;
public FoodListAdapter(Context context, int layoutResourceId, ArrayList data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
FoodListHolder holder = null;
if(row == null)
{
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new FoodListHolder();
holder.imgIcon = (ImageView)row.findViewById(R.id.imgIcon);
holder.txtTitle = (TextView)row.findViewById(R.id.txtTitle);
row.setTag(holder);
}
else
{
holder = (FoodListHolder)row.getTag();
}
FoodItem foodItem = data.get(position);
holder.txtTitle.setText(foodItem.title);
holder.imgIcon.setImageResource(foodItem.icon);
return row;
}
static class FoodListHolder
{
ImageView imgIcon;
TextView txtTitle;
}
}
答案 0 :(得分:1)
首先,您使用的是其他方法以后无法访问的变量。而是在onCreate
中创建适配器,如下所示:
foodListAdapter = new FoodListAdapter(this, R.layout.listview_item_row,
newFoodList);
mainListView.setAdapter(foodListAdapter);
其次,更改活动中的数组不会在适配器内部更改它。因此,将适配器内的data
变量设为public:
public ArrayList<FoodItem> data;
然后在onClick
方法中,您可以像这样操作适配器数据:
foodListAdapter.data.add(new FoodItem(R.drawable.ic_chicken,
mainSpinner.getSelectedItem().toString()+" was stored on: "+currentDate));
foodListAdapter.notifyDataSetChanged();
答案 1 :(得分:0)
使用
foodListAdapter = new FoodListAdapter(this,
R.layout.listview_item_row, newFoodList);
用于创建FoodListAdapter
对象。获取NullPointer异常,因为foodListAdapter
为空(创建adapter
的新FoodListAdapter
对象。)
答案 2 :(得分:0)
您的foodListAdapter
为空,因为您使用adapter
初始化并使用notifyDatasetChanged
foodListAdapter
进行初始化,因此
变化
FoodLisAdapter adapter = new FoodListAdapter(this,
R.layout.listview_item_row, newFoodList);
mainListView.addHeaderView(header);
mainListView.setAdapter(adapter);
到
foodListAdapter = new FoodListAdapter(this,
R.layout.listview_item_row, newFoodList);
mainListView.addHeaderView(header);
mainListView.setAdapter(foodListAdapter);