получение целочисленного значения, введенного из динамически созданного текста редактирования в диалоговом окне в Android, вызывает исключение NumberFormatException

Я новичок, так что извините, если это окажется так просто, что я должен был решить сам. Я пару дней думал об этом. Я исследовал тонну и искал много других сообщений здесь, но безуспешно.

У меня есть диалог с DatePicker, кнопками, полями EditText и Spinners. Я могу заполнить все, что мне нужно, от сохраненных элементов в моей БД до диалога. Но когда я пытаюсь ввести числа в некоторые поля EditText, он выдает NumberFormatException. Я могу жестко закодировать значения в переменные для хранения и скрыть свою попытку получить значение в попытке, и она будет работать нормально. Значения сохраняются, и когда я снова открываю диалоговое окно, они заполняют нужные области.

Вот частичный код-

        EditText et = new EditText(getContext()); 
        for(int i=0; i<=etcount; i++){
        placed = -1; //reset for next iteration

        //try to get number from edittext
        et.findViewById(i);
        placed = Integer.parseInt(et.getText().toString());

        awake++;
        /*
        try {
            //et.findViewById(i);
            placed = Integer.parseInt(findViewById(i).toString());
            //placed = Integer.parseInt(et.getText().toString());
        } catch(NumberFormatException nfe) {
           System.out.println("Could not parse " + nfe);
        }*/

Я закомментировал блок try, потому что хотел быстро устранить неполадки.

Переменная etcount инициализируется при onCreate значением -1 до получения значений из БД. Если в БД хранятся значения, они увеличиваются на 1, тогда вызывается код для динамического добавления EditText и Spinner в макет. Также для идентификатора EditText установлено значение etcount. Вот этот код-

//this will be ran when +placement button pressed, or if there are items in db stored
//adds 2 rows to dialog, one for textview to label items, one row for edittext with number
//and spinner with what item it is
private void createTableRow(int numPlaced, int itmPlaced){ 


    etcount++; //used to count how many edittext fields there are so that they can be saved later
    spincount++; //to count how many spinner there are


    tl = (TableLayout)findViewById(R.id.tableLayoutVisit); //the tablelayout name
    //need to create row for textview, then another row for edittext and spinner
    tr1 = new TableRow(this.getContext()); //table row 1, for textview
    tr1.setLayoutParams(new LayoutParams(
            LayoutParams.FILL_PARENT,
            LayoutParams.WRAP_CONTENT));
    TextView tv = new TextView(this.getContext());
    tv.setText("Amount Placed");
    tv.setLayoutParams(new LayoutParams(
            LayoutParams.FILL_PARENT,
            LayoutParams.WRAP_CONTENT));

    tr1.addView(tv); //add textview to tablerow1
    tl.addView(tr1, new TableLayout.LayoutParams( //add row to tablelayout
            LayoutParams.FILL_PARENT,
            LayoutParams.WRAP_CONTENT));


    tr2 = new TableRow(this.getContext()); //tablerow2: edittext and spinner
    tr2.setLayoutParams(new LayoutParams(
            LayoutParams.FILL_PARENT,
            LayoutParams.WRAP_CONTENT));        
    EditText et = new EditText(this.getContext());
    et.setId(etcount);
    et.setInputType(InputType.TYPE_CLASS_NUMBER);
    if(numPlaced!=0){ //if being populated from previous visit  
        et.setText(Integer.toString(numPlaced));
        //et.setText("" +numPlaced);
    }

    //need to have listener to read data
    et.setLayoutParams(new LayoutParams(
            LayoutParams.FILL_PARENT,
            LayoutParams.WRAP_CONTENT));


    Spinner spin = new Spinner(this.getContext());
    spin.setId(spincount);
    spinArray = getContext().getResources().getStringArray(R.array.itemplaced);
    ArrayAdapter adapter = new ArrayAdapter(getContext(),
            android.R.layout.simple_spinner_item, spinArray);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);


    spin.setAdapter(adapter);
    if(itmPlaced!=-1){
        spin.setSelection(itmPlaced); //assign correct value 
    }
    spin.setLayoutParams(new LayoutParams(
            LayoutParams.FILL_PARENT,
            LayoutParams.WRAP_CONTENT));
    tr2.addView(et);
    tr2.addView(spin);


    tl.addView(tr2, new TableLayout.LayoutParams( //add row to tablelayout
            LayoutParams.FILL_PARENT,
            LayoutParams.WRAP_CONTENT));

}

Я передаю его (0,-1), если это новый элемент и в настоящее время не хранится в БД. Также вы, наверное, заметили, что я заставил его принять TYPE_CLASS_NUMBER. Но я не думаю, что проблема там. Опять же, если я жестко закодирую значения, они будут сохранены в БД, и в следующий раз, когда я открою его, он динамически создаст строку EditText/Spinner в макете и заполнит EditText значением в БД.

Итак... что-то не так с первым разделом, я думаю, et.findViewById(i); или размещено = Integer.parseInt(et.getText().toString());. Значение "etcount" должно быть -1, если ничего не заполняется из БД, и 0 и т.д.(etcount++) каждый раз, когда что-то заполняется из БД.

Извините, если это многословно, хотел быть конкретным. Надеюсь, этой информации достаточно! Любая помощь будет здорово!!! Заранее спасибо.


person cyberDust    schedule 23.12.2011    source источник


Ответы (2)


Попробуй это:

    EditText et = new EditText(this);

    for (int i = 0; i <= etcount; i++) {
        placed = -1;
        et = (EditText) this.findViewById(i);
        placed = Integer.parseInt(et.getText().toString());
        //...
    }

Мне кажется, я нашел ошибку. Основная проблема в вашем коде в том, что вы не присваиваете уникальные значения в методах setId. В вашем случае некоторые editTexts и спины могут иметь одинаковые идентификаторы. Это не правильно. Каждый элемент должен иметь уникальный идентификатор. Это первое, что вы должны исправить в своем коде.

После этого вы можете использовать мой подход. Но мне кажется, что-то не так в этом подходе. Это не красиво ) Попробуйте найти лучшие практики в этой области.

person Yury    schedule 23.12.2011
comment
Спасибо Юрий! Итак, я изменил эти вещи, но не кости ... все то же самое. Мне интересно, если EditText et = new EditText(this.getContext()); и et.setId(etcount); Код при создании строки фактически назначает уникальный идентификатор каждому созданному EditText. Кажется, он не нулевой ... но, может быть, он тянет какой-то другой ресурс и не находит правильный EditText? Может быть, мне следует сохранить каждый созданный EditText в другую переменную, какой-то ресурс типа массива? Я мог бы попробовать это, когда я вернусь домой с работы!! Спасибо за советы!! - person cyberDust; 23.12.2011
comment
Смотрите мои комментарии в моем ответе. - person Yury; 23.12.2011
comment
Спасибо Юрий!! Извините, не знаю, как я это пропустил... Но у них есть уникальные идентификаторы, вращение установлено в onCreate на 99, текст редактирования равен -1. При первом добавлении edittext и spinner они увеличиваются до 100 и 0 соответственно... Имеет ли это смысл? - person cyberDust; 23.12.2011
comment
Я думаю да. В любом случае сообщите нам свои выводы и если вам все еще нужна наша помощь. - person Yury; 24.12.2011
comment
Ok!! Сейчас это работает. Я использовал etcount, чтобы дать уникальный идентификатор EditText, как мой код выше, и каждый раз увеличивал его. Я потратил больше времени на отладку, и ваш код выше сработал! Кастинг EditText нашел правильный EditText, и код parseInt сработал. Я столкнулся с другой ошибкой, когда использовал ваш код, хотя и из-за другого назначения переменных, но это была отдельная проблема в другой области кода, поэтому я подумал, что ваш ответ не работает, извините... Проблема заключалась в том, чтобы получить правильный EditText и получение значения. Спасибо!!! Я отмечу этот ответ, так как ваш ответ работает! - person cyberDust; 24.12.2011

Несколько предложений с моей стороны: 1) попробуйте проверить, не дает ли метод getText пустую строку "" или null. 2) разместить свой EditText et; к переменной класса, а не к локальному экземпляру. пример общедоступного класса ExampleActivity extends Activity { EditText et;//разместите его здесь, а не в методах oncreate.

}// или сделать его окончательным, если он определен в oncreate.

судя по вашему коду, в вашем цикле for(int i=0; i‹=etcount; i++){placed = -1; //сброс для следующей итерации

    //try to get number from edittext  // which edit text you are trying to access. am sure it is  returning null to you.
    et.findViewById(i);
    placed = Integer.parseInt(et.getText().toString());
person AAnkit    schedule 23.12.2011
comment
Эй, спасибо за ответ!! Я переместил объявление EditText в переменную класса прямо внутри класса перед onCreate или другими методами. Но вроде отвечает тем же. Я также попытался добавить et.getText().toString()!=null и et.getText()!=null, а также оба с with вместо null, и увеличил переменную внутри оператора IF на основе результата, и он увеличивается. Итак, et.getText(), похоже, не возвращает значение null... - person cyberDust; 23.12.2011
comment
et.findViewById (я); // эта строка извлекает представление, но не присваивает et. сделать это et = et.findViewById(i); - person AAnkit; 24.12.2011