定制支架适配器错误

时间:2015-05-29 16:59:47

标签: android baseadapter android-viewholder

我尝试使用复选框作为更大的应用程序的一部分来实现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;
}

}

也许这是一个愚蠢的错误,但任何帮助都会感激不尽。

1 个答案:

答案 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