我尝试使用复选框作为更大的应用程序的一部分来实现listView。当我尝试启动活动时,我收到了nullPointer错误,但我无法找出问题所在。
也许我的AsyncTask没有返回真值?
这是logcat:https://www.dropbox.com/s/p8w9mz7lbofaeja/log.txt?dl=0
我的代码:
public class ListActivity extends Activity {
/**
* Xml Name List
*/
private String url;
/**
* List of products from the parsed xml
*/
List<Book> products;
/**
* actual Activity
*/
private Activity currentActivity;
/**
* Xml files path
*/
@SuppressLint("SdCardPath")
private String folder = "/data/data/com.group7.ule.barcodeshoppinglist/files/";
/**
* Products list's ListView
*/
ListView listView;
/**
* Array with lists the user can change to
*/
String[] data;
@SuppressWarnings("unchecked")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
currentActivity = this;
// Catch the xml's name
Bundle bundle = this.getIntent().getExtras();
this.url = bundle.getString("LISTNAME");
Log.d("LISTAS LIBROS", "estamos en lista:" + url);
// Get the available lists
// FolderAdmin folderAdmin = new FolderAdmin(folder);
// this.data = folderAdmin.getListsNames();
ArrayList<String> lists = Database.getInstance(null).getLists();
this.data = new String[lists.size()];
for (int i = 0; i < lists.size(); i++) {
data[i] = lists.get(i);
}
// Show the elements of the list
refreshList();
/***************************** SPINNER TO CHANGE THE LIST **************************/
final Spinner availableLists = (Spinner) findViewById(R.id.listSpinner);
ArrayAdapter<String> adaptador = new ArrayAdapter<String>(
currentActivity, android.R.layout.simple_spinner_item, data);
adaptador
.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
Log.d("SPINNER", "set adapter");
availableLists.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
// If a different list is selected we update the view
if ((availableLists.getSelectedItem().toString())
.compareTo(url) != 0) {
url = availableLists.getSelectedItem().toString();
refreshList();
}
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
}
});
// Attach the adapter to the spinner. It is a simple adapter
availableLists.setAdapter(adaptador);
// We selected the list in which we are
availableLists.setSelection(((ArrayAdapter<String>) availableLists
.getAdapter()).getPosition(url.substring(0, url.length() - 4)));
/***************************** ADD BUTTON **************************/
Button addButton = (Button) findViewById(R.id.addButton);
Log.d("ADD", "creado boton");
addButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// We call search screen
Intent intent = new Intent(currentActivity,
BarcodeActivity.class);
startActivity(intent);
}
});
/***************************** REMOVE BUTON **************************/
Button removeButton = (Button) findViewById(R.id.removeButton);
Log.d("REMOVE", "creado boton");
removeButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(currentActivity, " Eliminando... ",
Toast.LENGTH_LONG).show();
// get the selected items and delete them
for (int i = 0; i < listView.getCount(); i++) {
if (((CustomBaseAdapter) listView.getAdapter()).getItem(i)
.isChecked()) {
// op.removeElement(((CustomBaseAdapter)
// listView.getAdapter()).getItem(i).getTitle(), url,
// currentActivity);
}
}
refreshList();
}
});
/***************************** DESELECTALL BUTTON **************************/
Button deselectButton = (Button) findViewById(R.id.desSelectAllButton);
Log.d("DESELECTALL", "creado boton");
deselectButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Log.d("Deselec Element", "arrancando deseleccionar");
// Put all checkboxs to unchecked
for (int i = 0; i < listView.getCount(); i++) {
listView.getAdapter().getView(i, null, listView);
((CustomBaseAdapter) listView.getAdapter()).getHolder()
.getBookCheckBox().setChecked(false);
}
// Report the change to the adapter
((CustomBaseAdapter) listView.getAdapter())
.notifyDataSetChanged();
}
});
/***************************** SELECTALL BUTTON **************************/
Button selectButton = (Button) findViewById(R.id.selectAllButton);
Log.d("SELECTALL", "creado boton");
selectButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Log.d("Selec Element", "arrancando seleccionar");
// Put all checkboxs to checked
for (int i = 0; i < listView.getCount(); i++) {
listView.getAdapter().getView(i, null, listView);
((CustomBaseAdapter) listView.getAdapter()).getHolder()
.getBookCheckBox().setChecked(true);
}
// Report the change to the adapter
((CustomBaseAdapter) listView.getAdapter())
.notifyDataSetChanged();
}
});
/***************************** HOME BUTTON **************************/
Button homeButton = (Button) findViewById(R.id.inicioButton);
Log.d("HOME", "creado boton");
homeButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// Call the initial screen of the application
Intent intent = new Intent(currentActivity, MainActivity.class);
startActivity(intent);
}
});
/***************************** SELECT A PRODUCT **************************/
listView = (ListView) findViewById(R.id.product_list);
Log.d("SELECCIONAR", "creado boton");
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(ListActivity.this,
products.get(position).getIsbn10(), Toast.LENGTH_SHORT)
.show();
// Intent intent=new Intent(ListActivity.this,
// ElementActivity.class);
// Bundle bundle = new Bundle();
// bundle.putString("BARCODE",
// products.get(position).getBarcode());
// intent.putExtras(bundle);
// startActivity(intent);
}
});
}
/**
* Class in charge of loading an XML using asynchronous task
*
* @author Rut
*
*/
private class CargarXmlTask extends AsyncTask<String, Integer, Boolean> {
// Asynchronous Task to load an XML in background
protected Boolean doInBackground(String... params) {
// Parse xml to use product list
/*
* ListaParserSax2 saxparser = new ListaParserSax2(params[0],
* getApplicationContext()); products = saxparser.parse();
*/
Log.d("DO BACKGROUN", "arranca");
List<Usulibr> listaRelacciones = Database.getInstance(null)
.getUsulibr(params[0]);
ListIterator<Usulibr> iterador = listaRelacciones.listIterator();
products = new ArrayList<>();
while (iterador.hasNext()) {
Usulibr rel = (Usulibr) iterador.next();
Book libro = Database.getInstance(null)
.getBook(rel.getIsbn10());
products.add(libro);
System.out.println("Libro recuperado: " + libro.getTitle());
}
Log.d("PARSER", "parseo terminado");
return true;
}
protected void onPostExecute(Boolean result) {
Log.d("CUSTOMADAPTER", "arrancando adaptador");
// 1. Pass the context and the data to the adapter
CustomBaseAdapter adapter = new CustomBaseAdapter(currentActivity,
R.layout.product_list_row_layout, products, url);
// 2. Obtain ListView from activity_lists.xml
listView = (ListView) findViewById(R.id.product_list);
// 3. Put the adapter to the list
listView.setAdapter(adapter);
Log.d("CUSTOMADAPTER", "set adapter");
}
/**
* Method that inflates the menu, adding items to the action bar, if
* present.
*
* @param menu
* @return true
*/
@SuppressWarnings("unused")
public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
/**
* Method that reloads the xml
*/
public void refreshList() {
Log.d("TAREA ASINCRONA", "arrancando");
// Carga del XML mediante la tarea asíncrona
CargarXmlTask tarea = new CargarXmlTask();
tarea.execute(url);
}
}
public class Holder {
/**
* Declaration of variables
*/
private TextView bookName;
private TextView bookAmount;
private CheckBox bookCheckBox;
private Button bookMoreButton;
private Button bookLessButton;
/**
* Constructor
*/
public Holder(){
}
/**
* Method that returns the name´s TextView
* @return bookName
*/
public TextView getBookName() {
return bookName;
}
/**
* Method that sets the name´s TextView
* @param textView you want to attach to holder
*/
public void setBookName(TextView textView) {
this.bookName = textView;
}
/**
* Method that returns the amount´s TextView
* @return bookAmount
*/
public TextView getBookAmount() {
return bookAmount;
}
/**
* Method that sets the amount´s TextView
* @param bookAmount you want to attach to holder
*/
public void setBookAmount(TextView bookAmount) {
this.bookAmount = bookAmount;
}
/**
* Method that returns the checkbox
* @return bookCheckBox
*/
public CheckBox getBookCheckBox() {
return bookCheckBox;
}
/**
* Method that sets the row checkbox
* @param bookCheckBox you want to attach to holder
*/
public void setBookCheckBox(CheckBox bookCheckBox) {
this.bookCheckBox = bookCheckBox;
}
/**
* Method that returns the button to increase amount
* @return bookMoreButton
*/
public Button getbBokMoreButton() {
return bookMoreButton;
}
/**
* Method that sets the button to increase amount
* @param bookMoreButton you want to attach to holder
*/
public void setBookMoreButton(Button bookMoreButton) {
this.bookMoreButton = bookMoreButton;
}
/**
* Method that returns the button to decrease amount
* @return bookLessButton
*/
public Button getBookLessButton() {
return bookLessButton;
}
/**
* Method that sets the button to decrease amount
* @param bookLessButton you want to attach to holder
*/
public void setBookLessButton(Button bookLessButton) {
this.bookLessButton = bookLessButton;
}
}
public class CustomBaseAdapter extends BaseAdapter{
/**
* Declaration of variables
*/
private final Activity context;
private final List<Book> booksList;
View v;
Holder holder = null;
private String xmlFile;
/**
* Constructor
* @param context the activity context
* @param textViewResourceId the interface element referred to
* @param objects list of objects to display
* @param xml xml file to which the objects belong
*/
public CustomBaseAdapter(Activity context, int textViewResourceId, List<Book> objects,String xml)
{
this.context = context;
this.booksList = objects;
this.xmlFile=xml;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent)
{
v = convertView;
if (v == null)
{
holder = new Holder();
Log.d("Holder", "Holder creado, empezando...");
LayoutInflater layoutInflater = context.getLayoutInflater();
v = layoutInflater.inflate(R.layout.product_list_row_layout, null);
//assign the interface elements to the holder
holder.setBookCheckBox((CheckBox) (v.findViewById(R.id.checkBox)));
holder.setBookName((TextView) v.findViewById(R.id.name_product));
//holder.setProductLessButton((Button) (v.findViewById(R.id.SubstractButton)));
//holder.setProductAmount((TextView) v.findViewById(R.id.amount_product));
//holder.setProductMoreButton((Button) (v.findViewById(R.id.MoreButton)));
v.setTag(holder);
}
else
{
holder = (Holder) v.getTag();
}
//assign to each row the corresponding data
final Book row = getItem(position);
Typeface font= Typeface.createFromAsset(context.getAssets(), "AidaSerifa-Condensed.ttf");
holder.getBookName().setTypeface(font);
holder.getBookName().setText(row.getTitle());
holder.getBookCheckBox().setTag(row.getTitle());
holder.getBookCheckBox().setChecked(row.isChecked());
/*****************************CHANGE CHECKBOX STATE**************************/
holder.getBookCheckBox().setOnCheckedChangeListener(new OnCheckedChangeListener()
{
@Override
public void onCheckedChanged(CompoundButton v, boolean isChecked)
{
//ensures the originally row associated with this checkbox is modify to prevent that when
//we recycle the view the row changely showed in this row is restarted.Tagg the Row is
//essential before setting the value of the checkbox
if (row.getTitle().equals(v.getTag().toString()))
{
row.setChecked(isChecked);
}
}
});
/*****************************INCREASING AMOUNT BUTTON**************************/
holder.getbBokMoreButton().setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
/*
Integer change,previous;
previous = Integer.parseInt(row.getAmount());
change = previous+1;
Operation op = new Operation();
op.modificar(xmlFile, row.getName(), change.toString(),context);
holder.getProductAmount().setText(change.toString());
Log.d("HOLDER", "amout aumentado");
((ListActivity)context).refreshList();
*/
}
}
);
/*****************************AMOUNT DOWN BUTTON**************************/
holder.getBookLessButton().setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
/*
Integer change,previous;
previous = Integer.parseInt(row.getAmount());
//if the amount is 1 it can´t be reduced
if(previous > 1){
change = previous-1;
Operation op = new Operation();
op.modificar(xmlFile, row.getName(), change.toString(),context);
holder.getProductAmount().setText(change.toString());
Log.d("HOLDER", "amount disminuido");
((ListActivity)context).refreshList();
}else{
Toast.makeText(context,"El producto ya tiene la menor cantidad posible",Toast.LENGTH_LONG).show();
}
*/
}
});
return v;
}
@Override
public int getCount() {
return booksList.size();
}
@Override
public Book getItem(int position) {
return booksList.get(position);
}
@Override
public long getItemId(int position) {
return booksList.indexOf(getItem(position));
}
/**
* Method that returns a holder
* @return holder the actual holder of the row
*/
public Holder getHolder() {
return holder;
}
}
也许这是一个愚蠢的错误,但任何帮助都会感激不尽。
答案 0 :(得分:0)
Intent#getExtras()可以返回null,并致电bundle.getString("LISTNAME")
,这可能是您的NPE的原因
但我不这么认为。
看看你的logcat有以下几行:
05-29 18:39:25.054:D / HOME(14018):creado boton
05-29 18:39:25.054:D / AndroidRuntime(14018):关闭虚拟机
查找代码记录的位置creado boton
我在这里看到了一个日志:
...
Button homeButton = (Button) findViewById(R.id.inicioButton);
Log.d("HOME", "creado boton");
homeButton.setOnClickListener(new OnClickListener() {
...
下一个日志是
...
listView = (ListView) findViewById(R.id.product_list);
Log.d("SELECCIONAR", "creado boton");
listView.setOnItemClickListener(new OnItemClickListener() {
...
但我从未在您的日志中看到SELECCIONAR
,这意味着您的代码永远不会达到这一点。那么我查看这些标记之间的代码,查找onCreate
所发生的对象引用(所以setOnItemClickListener
中没有代码),我看到的唯一代码是homeButton.setOnClickListener
。
所以,我会说你的NPE是homeButton
为空。看起来不太可能,但有一些topics on it。