Android java.lang.IndexOutOfBoundsException:无效的索引5,大小为5错误

时间:2018-06-28 06:18:59

标签: java android android-studio

由于我对使用android java不太熟悉。我很难解决此错误:java.lang.IndexOutOfBoundsException:无效的索引5,大小为5。代码检查其Spinner或EditText。

错误来自dynamicEditText [i]的代码:

if (fields.get(j).equalsIgnoreCase(fieldName)){ 

错误代码来自此函数createDynamicForm(String layerName):

                /*
                Check if the Field is a spinner or not.
                 */
                if (wfDatabase.checkIfDropDown(fieldName, layerName)) {

                    /*
                 Create and display label of the spinner through textView
                  */
                    //TextV.setText(fieldDisplayName.get(i));
                    dynamicTextView[i] = new TextView(getApplicationContext());
                    dynamicTextView[i].setLayoutParams(textViewParams);
                    dynamicTextView[i].setTextColor(Color.RED);
                    dynamicTextView[i].setText(fieldDisplayName.get(i));

                    /*
                    Creates a spinner inside the LinearLayout.
                    Initialize dynamicSpinner then set the LayoutParams and background of the spinner.
                     */
                    dynamicSpinner[i] = new Spinner(getApplicationContext());
                    dynamicSpinner[i].setLayoutParams(spinnerParams);
                    dynamicSpinner[i].setBackground(this.getResources().getDrawable(R.drawable.dropdown));
                    /*
                    Get the dropdown values inside the DropdownValues table then set it inside the dropDown arraylist.
                    Also adding the Display name from fieldDisplay to the first element of dropDown arraylist.
                     */

                    ArrayList<String> dropDown = new ArrayList<>();
                    //dropDown.add("Options...");
                    dropDown.add(fieldDisplayName.get(i));
                    dropDown.addAll(wfDatabase.getDropdownList(fieldName, layerName));
                    /*
                    Sets the adapter for the dynamicSpinner also the codes below prevent the user to user first element inside the
                    dropDown arraylist.(Display Name of the Field is the first element.)
                     */
                    ArrayAdapter adapter = new ArrayAdapter(
                            this, R.layout.spinner_item, dropDown){
                        @Override
                        public boolean isEnabled(int position){
                            if(position == 0 )
                            {
                                // Disable the first item from Spinner
                                // First item will be use for hint
                                return false;
                            }
                            else
                            {
                                return true;
                            }
                        }

                        @Override
                        public View getDropDownView(int position, View convertView,
                                                    ViewGroup parent) {
                            View view = super.getDropDownView(position, convertView, parent);
                            TextView tv = (TextView) view;
                            if(position == 0){
                                // Set the hint text color gray
                                tv.setTextColor(Color.GRAY);

                            }
                            else {
                                tv.setTextColor(Color.BLACK);
                            }
                            return view;

                        }
                    };
                    adapter.setDropDownViewResource(R.layout.spinner_item);
                    dynamicSpinner[i].setAdapter(adapter);

                    if (fields.size() != 0 && values.size() != 0 ) {

                        /*
                    Check if the fieldName is the same as the value inside the fields arraylist.
                    Then get the index of fields that matches the fieldName.
                    Then check the index of the values using the index that was taken from fields.
                    If values.get() is null: the first element will be the default item selected.
                    If not null: the selected item will be will be set.
                    */

                        for (int l = 0; l < fields.size() ; l++) {
                            if (fields.get(l).equalsIgnoreCase(fieldName)) {
                                field_index = l;
                                //prompt a test on the Item selected
                                if (!values.get(field_index).equalsIgnoreCase("NULL")) {
                                    dynamicSpinner[i].setSelection(adapter.getPosition( wfDatabase.getDropdownFALIAS(fieldName, layerName, values.get(field_index))));


                                }

                            }

                        }
                    }
                    /*
                    Add the TextView to the LinearLayout.
                    */
                    ll.addView(dynamicTextView[i]);




                /*
                Add the dynamicSpinner to the LinearLayout.
                 */


                    ll.addView(dynamicSpinner[i]);

                }
                /*
                If the Field is not a drop down it will create an EditText.
                 */
                else {
                    /*
                    Initialize dynamicEditText and set the color of the hint , textSize, textColor and
                    set the hint to the Display Name of the Field.
                     */
                    dynamicEditText[i] = new EditText(getBaseContext());
                    dynamicEditText[i].setLayoutParams(editViewParams);
                    dynamicEditText[i].setPadding(20,0,0,5);
                    dynamicEditText[i].setHintTextColor(Color.GRAY);
                    dynamicEditText[i].setTextSize(13);
                    dynamicEditText[i].setTextColor(Color.BLACK);
                    dynamicEditText[i].setHint(fieldDisplayName.get(i));

                    if (fields.size() != 0 && values.size() != 0) {
                    /*
                    Check if the fieldName is the same as the value inside the fields arraylist.
                    Then get the index of fields that matches the fieldName.
                    Then check the index of the values using the index that was taken from fields.
                    If values.get() is null: then the hint will be displayed.
                    If not null: dynamicEditText will get the value of values.get().
                     */
                        for (int j = 0; j < field_count; j++) {
                            if (fields.get(j).equalsIgnoreCase(fieldName)){
                                value_index = j;
                                if (!values.get(value_index).equalsIgnoreCase("NULL"))
                                    dynamicEditText[i].setText(values.get(value_index));

                            }
                        }
                    }
                    /*
                    Check if the Format of the Field is TXT or text in the SQLite.
                     */
                    if (wfDatabase.getFieldFormat(fieldDisplayName.get(i), layerName).equalsIgnoreCase("TXT")) {
                    /*
                    If the Format is TXT.
                    Check if the Field is only READONLY.
                    If yes disable the dynamicEditText
                    else just setHint using the fieldDisplayName.
                     */
                        if (wfDatabase.isReadOnly(fieldDisplayName.get(i), layerName).compareTo("Y") == 0) {
                            dynamicEditText[i].setHint(fieldDisplayName.get(i)+"(VIEW ONLY)");
                            dynamicEditText[i].setEnabled(false);
                            dynamicEditText[i].setInputType(0);
                        }
                        else{
                            dynamicEditText[i].setHint(fieldDisplayName.get(i));
                        }
                        /*
                        Set the dynamicEditText background
                        then add it to the LinearLayout.
                         */
                        dynamicEditText[i].setBackground(this.getResources().getDrawable(R.drawable.edittext));
                        ll.addView(dynamicEditText[i]);
                    }
                    /*
                    Check if the Format of the Field is NUM or number in SQLite.
                     */
                    else if (wfDatabase.getFieldFormat(fieldDisplayName.get(i), layerName).equalsIgnoreCase("NUM")) {
                        /*
                        If Yes then set the inputType of the dynamicEditText to Nummber or Decimals only.
                         */
                        dynamicEditText[i].setInputType(InputType.TYPE_CLASS_NUMBER |
                                InputType.TYPE_NUMBER_FLAG_DECIMAL);
                    /*
                    Check if the Field is only READONLY.
                    If yes disable the dynamicEditText
                    else just setHint using the fieldDisplayName.
                     */
                        if (wfDatabase.isReadOnly(fieldDisplayName.get(i), layerName).compareTo("Y") == 0) {
                            dynamicEditText[i].setHint(fieldDisplayName.get(i)+"(VIEW ONLY)");
                            dynamicEditText[i].setEnabled(false);
                            dynamicEditText[i].setInputType(0);
                        }
                        else{
                            dynamicEditText[i].setHint(fieldDisplayName.get(i));
                        }
                        /*
                        Set the dynamicEditText background
                        then add it to the LinearLayout.
                         */
                        dynamicEditText[i].setBackground(this.getResources().getDrawable(R.drawable.edittext));
                        ll.addView(dynamicEditText[i]);

                    }

                }

            }

        }
        /*
        Add the LinearLayout to the ScrollView.
         */
        sv.addView(ll);
        /*
        Add the ScrollView to the LinearLayout that is created in the form.xml.
         */
        relativeLayout.addView(sv);

    }public void createDynamicForm(String layerName){
        /*
        Get the number of fields of the layer selected in layerSpinner.
        Then initialize the size of dynamicEditText,dynamicTextView,dynamicSpinner
        to the number of the fields.
         */
        int field_count = wfDatabase.numberOfField(layerName);
        dynamicEditText = new EditText[field_count];
        dynamicTextView = new TextView[field_count];
        dynamicSpinner = new Spinner[field_count];
        ArrayList<String> fieldDisplayName;
        /*
        Get the Field Values then pass it to fieldDisplayName.
         */
        fieldDisplayName = wfDatabase.getFields(layerName);
        /*
        Displays the field title above the chosen option on the spinner
         */
      //final TextView textview1 = new TextView(this);
      //textview1.setText("Value");

        /*
        Uses the stringTokenizer() function below to separate the Facility values/fields in the SQLite
        then pass the string array to values and fields.
         */
        values = stringTokenizer(wfDatabase.getFacilityDataValues(jobno, fid, layerName));
        fields = stringTokenizer(wfDatabase.getFacilityFields(jobno, layerName,fid));
        Log.e("Value", values.size() + "");
        Log.e("Field", fields.size() + "");






        /*
        Creates a ScrollView that will contain the LinearLayout below and initialize it also set the LayoutParams then set the background.
         */
        ScrollView sv = new ScrollView(FormActivity.this);
        sv.setLayoutParams(new ScrollView.LayoutParams(
                ScrollView.LayoutParams.MATCH_PARENT,
                ScrollView.LayoutParams.WRAP_CONTENT));
        sv.setBackgroundColor(Color.WHITE);



        /*
        Creates a LinearLayout that will contain all of the edittext and spinner created below.
        Initialize and also set the LayoutParams of the LinearLayout.
         */
        LinearLayout ll = new LinearLayout(FormActivity.this);
        LinearLayout.LayoutParams lParamsMW = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.MATCH_PARENT);
        ll.setLayoutParams(new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT));
        ll.setOrientation(LinearLayout.VERTICAL);
        ll.setLayoutParams(lParamsMW);
        /*
        Creating the LayoutParams of the edittext and spinner that will be created.
         */
        LinearLayout.LayoutParams editViewParams = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT
        );
        LinearLayout.LayoutParams textViewParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT
        );
        LinearLayout.LayoutParams spinnerParams = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT
        );


        textViewParams.setMargins(5,15,5,0);
        spinnerParams.setMargins(5, 0, 5, 5);
        editViewParams.setMargins(5, 0, 5, 0);

        //Create TextView for the label
        //TextView TextV = new TextView(FormActivity.this);
        //TextV.setLayoutParams(textViewParams);
        //TextV.setTextColor(Color.RED);

        /*
        Check if the field_count is greater than 0.
         */
        if (field_count > 0) {
            for (int i = 0; i < field_count; i++) {
                /*
                value_index and field_index will be used later to locate the index.
                 */
                int value_index;
                int field_index;

                /*
                fieldName will get the Display name of the field inside the sqlite.
                 */
                String fieldName = wfDatabase.getFieldName(fieldDisplayName.get(i), layerName);



                /*
                Check if the Field is a spinner or not.
                 */
                if (wfDatabase.checkIfDropDown(fieldName, layerName)) {

                    /*
                 Create and display label of the spinner through textView
                  */
                    //TextV.setText(fieldDisplayName.get(i));
                    dynamicTextView[i] = new TextView(getApplicationContext());
                    dynamicTextView[i].setLayoutParams(textViewParams);
                    dynamicTextView[i].setTextColor(Color.RED);
                    dynamicTextView[i].setText(fieldDisplayName.get(i));

                    /*
                    Creates a spinner inside the LinearLayout.
                    Initialize dynamicSpinner then set the LayoutParams and background of the spinner.
                     */
                    dynamicSpinner[i] = new Spinner(getApplicationContext());
                    dynamicSpinner[i].setLayoutParams(spinnerParams);
                    dynamicSpinner[i].setBackground(this.getResources().getDrawable(R.drawable.dropdown));
                    /*
                    Get the dropdown values inside the DropdownValues table then set it inside the dropDown arraylist.
                    Also adding the Display name from fieldDisplay to the first element of dropDown arraylist.
                     */

                    ArrayList<String> dropDown = new ArrayList<>();
                    //dropDown.add("Options...");
                    dropDown.add(fieldDisplayName.get(i));
                    dropDown.addAll(wfDatabase.getDropdownList(fieldName, layerName));
                    /*
                    Sets the adapter for the dynamicSpinner also the codes below prevent the user to user first element inside the
                    dropDown arraylist.(Display Name of the Field is the first element.)
                     */
                    ArrayAdapter adapter = new ArrayAdapter(
                            this, R.layout.spinner_item, dropDown){
                        @Override
                        public boolean isEnabled(int position){
                            if(position == 0 )
                            {
                                // Disable the first item from Spinner
                                // First item will be use for hint
                                return false;
                            }
                            else
                            {
                                return true;
                            }
                        }

                        @Override
                        public View getDropDownView(int position, View convertView,
                                                    ViewGroup parent) {
                            View view = super.getDropDownView(position, convertView, parent);
                            TextView tv = (TextView) view;
                            if(position == 0){
                                // Set the hint text color gray
                                tv.setTextColor(Color.GRAY);

                            }
                            else {
                                tv.setTextColor(Color.BLACK);
                            }
                            return view;

                        }
                    };
                    adapter.setDropDownViewResource(R.layout.spinner_item);
                    dynamicSpinner[i].setAdapter(adapter);

                    if (fields.size() != 0 && values.size() != 0 ) {

                        /*
                    Check if the fieldName is the same as the value inside the fields arraylist.
                    Then get the index of fields that matches the fieldName.
                    Then check the index of the values using the index that was taken from fields.
                    If values.get() is null: the first element will be the default item selected.
                    If not null: the selected item will be will be set.
                    */

                        for (int l = 0; l < fields.size() ; l++) {
                            if (fields.get(l).equalsIgnoreCase(fieldName)) {
                                field_index = l;
                                //prompt a test on the Item selected
                                if (!values.get(field_index).equalsIgnoreCase("NULL")) {
                                    dynamicSpinner[i].setSelection(adapter.getPosition( wfDatabase.getDropdownFALIAS(fieldName, layerName, values.get(field_index))));


                                }

                            }

                        }
                    }
                    /*
                    Add the TextView to the LinearLayout.
                    */
                    ll.addView(dynamicTextView[i]);




                /*
                Add the dynamicSpinner to the LinearLayout.
                 */


                    ll.addView(dynamicSpinner[i]);

                }
                /*
                If the Field is not a drop down it will create an EditText.
                 */
                else {
                    /*
                    Initialize dynamicEditText and set the color of the hint , textSize, textColor and
                    set the hint to the Display Name of the Field.
                     */
                    dynamicEditText[i] = new EditText(getBaseContext());
                    dynamicEditText[i].setLayoutParams(editViewParams);
                    dynamicEditText[i].setPadding(20,0,0,5);
                    dynamicEditText[i].setHintTextColor(Color.GRAY);
                    dynamicEditText[i].setTextSize(13);
                    dynamicEditText[i].setTextColor(Color.BLACK);
                    dynamicEditText[i].setHint(fieldDisplayName.get(i));

                    if (fields.size() != 0 && values.size() != 0) {
                    /*
                    Check if the fieldName is the same as the value inside the fields arraylist.
                    Then get the index of fields that matches the fieldName.
                    Then check the index of the values using the index that was taken from fields.
                    If values.get() is null: then the hint will be displayed.
                    If not null: dynamicEditText will get the value of values.get().
                     */
                        for (int j = 0; j < field_count; j++) {
                            if (fields.get(j).equalsIgnoreCase(fieldName)){
                                value_index = j;
                                if (!values.get(value_index).equalsIgnoreCase("NULL"))
                                    dynamicEditText[i].setText(values.get(value_index));

                            }
                        }
                    }
                    /*
                    Check if the Format of the Field is TXT or text in the SQLite.
                     */
                    if (wfDatabase.getFieldFormat(fieldDisplayName.get(i), layerName).equalsIgnoreCase("TXT")) {
                    /*
                    If the Format is TXT.
                    Check if the Field is only READONLY.
                    If yes disable the dynamicEditText
                    else just setHint using the fieldDisplayName.
                     */
                        if (wfDatabase.isReadOnly(fieldDisplayName.get(i), layerName).compareTo("Y") == 0) {
                            dynamicEditText[i].setHint(fieldDisplayName.get(i)+"(VIEW ONLY)");
                            dynamicEditText[i].setEnabled(false);
                            dynamicEditText[i].setInputType(0);
                        }
                        else{
                            dynamicEditText[i].setHint(fieldDisplayName.get(i));
                        }
                        /*
                        Set the dynamicEditText background
                        then add it to the LinearLayout.
                         */
                        dynamicEditText[i].setBackground(this.getResources().getDrawable(R.drawable.edittext));
                        ll.addView(dynamicEditText[i]);
                    }
                    /*
                    Check if the Format of the Field is NUM or number in SQLite.
                     */
                    else if (wfDatabase.getFieldFormat(fieldDisplayName.get(i), layerName).equalsIgnoreCase("NUM")) {
                        /*
                        If Yes then set the inputType of the dynamicEditText to Nummber or Decimals only.
                         */
                        dynamicEditText[i].setInputType(InputType.TYPE_CLASS_NUMBER |
                                InputType.TYPE_NUMBER_FLAG_DECIMAL);
                    /*
                    Check if the Field is only READONLY.
                    If yes disable the dynamicEditText
                    else just setHint using the fieldDisplayName.
                     */
                        if (wfDatabase.isReadOnly(fieldDisplayName.get(i), layerName).compareTo("Y") == 0) {
                            dynamicEditText[i].setHint(fieldDisplayName.get(i)+"(VIEW ONLY)");
                            dynamicEditText[i].setEnabled(false);
                            dynamicEditText[i].setInputType(0);
                        }
                        else{
                            dynamicEditText[i].setHint(fieldDisplayName.get(i));
                        }
                        /*
                        Set the dynamicEditText background
                        then add it to the LinearLayout.
                         */
                        dynamicEditText[i].setBackground(this.getResources().getDrawable(R.drawable.edittext));
                        ll.addView(dynamicEditText[i]);

                    }

                }

            }

        }
        /*
        Add the LinearLayout to the ScrollView.
         */
        sv.addView(ll);
        /*
        Add the ScrollView to the LinearLayout that is created in the form.xml.
         */
        relativeLayout.addView(sv);

    }

2 个答案:

答案 0 :(得分:3)

就像您在代码中的其他地方所做的一样,最好使用List的大小作为其上限

for (int j = 0; j < fields.size(); j++) {
    if (fields.get(j).equalsIgnoreCase(fieldName)){
    ....
}

数组/列表从元素零开始

答案 1 :(得分:2)

您的索引绑定检查不一致。

    for (int j = 0; j < field_count; j++) {
        if (fields.get(j).equalsIgnoreCase(fieldName)){

    for (int l = 0; l < fields.size() ; l++) {
        if (fields.get(l).equalsIgnoreCase(fieldName)) {

第一个可能引发异常,而后者则不会。在第一种情况下也要使用fields.size()。