【问题标题】:Error in reading text from dynamically created multiple EditText从动态创建的多个 EditText 读取文本时出错
【发布时间】:2020-04-29 18:12:26
【问题描述】:

我创建了多个动态 EditText 对象(取决于从前一个片段收到的计数)作为 TableRow 的一部分。我想将一个侦听器(或多个侦听器,以可行的为准)附加到每个 EditText 并将用户添加的数据读入 String 数组。但是,当我运行程序时,我只能在最顶层 TableRow 的一个 EditText 中输入文本并阅读该文本。我无法在其他 EditText 中输入任何文本或阅读其内容。我究竟做错了什么?当我尝试创建一个 customTextWatcher 类、尝试简单的 editText.getText().toString()、尝试使用 ArrayList(而不是 String 数组)并通过它重复到 String 数组时,知道这会很有帮助。但是,这个错误继续困扰我!有人可以帮忙吗?将多个 EditText 读入 String 数组的最佳方法是什么?

      public class ForStackOF extends Fragment {

    private String[] globalplNames, localplNames, individualRoundScores;
    private int[] globalplScores, localplScores;
    private Bundle USBundle;
    private TableLayout tempTable;
    private TextWatcher editWatcher;
    private int globalCount, localCount, counter;
    private TextView tempNameView, tempScoreView, firstUpdateView;
    //private EditText tempNewScoreEdit;
    //List<EditText> allEds = new ArrayList<EditText>();
    private EditText[] ed;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
        setRetainInstance(true);
        USBundle = this.getArguments();
        globalCount = USBundle.getIntArray(SCORE).length;
        localCount = globalCount + 1;

        globalplNames = new String[globalCount];
        globalplNames = USBundle.getStringArray(PLAYERS_LIST);

        localplNames = new String[localCount];

        globalplScores = new int[globalCount];
        globalplScores = USBundle.getIntArray(SCORE);

        localplScores = new int[localCount];

        individualRoundScores = new String[localCount];

        ed = new EditText[localCount];

        for (counter = 0, localCount = 0; counter < globalCount; counter++) {
            localplNames[localCount + 1] = globalplNames[counter];
            localplScores[localCount + 1] = globalplScores[counter];
            localCount++;
        }

        localCount = globalCount + 1;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.update_score_fragment, parent, false);
        TableRow.LayoutParams rowParams = new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT);
        TableRow.LayoutParams namecellParams = new TableRow.LayoutParams(0, TableRow.LayoutParams.WRAP_CONTENT, 0.5f);
        TableRow.LayoutParams liveScorecellParams = new TableRow.LayoutParams(0, TableRow.LayoutParams.WRAP_CONTENT, 0.25f);
        TableRow.LayoutParams newScorecellParams = new TableRow.LayoutParams(0, TableRow.LayoutParams.WRAP_CONTENT, 0.25f);

        tempTable = (TableLayout) v.findViewById(R.id.scoreTables);

        for (counter = 0; counter < localCount; counter++) {
            TableRow row = new TableRow(getContext());

            row.setLayoutParams(rowParams);
            row.setWeightSum(1f);

            tempNameView = new TextView(getContext());
            tempNameView.setTextSize(16);
            tempNameView.setLayoutParams(namecellParams);

            tempScoreView = new TextView(getContext());
            tempScoreView.setTextSize(16);
            tempScoreView.setLayoutParams(liveScorecellParams);
            tempScoreView.setGravity(android.view.Gravity.CENTER);

            ed[counter] = new EditText(getContext());
            ed[counter].setTextSize(16);
            ed[counter].setLayoutParams(newScorecellParams);
            ed[counter].setInputType(InputType.TYPE_CLASS_NUMBER);
            ed[counter].setHint("+/-");
            ed[counter].setFocusableInTouchMode(true);
            ed[counter].setGravity(android.view.Gravity.CENTER);
            //allEds.add(tempNewScoreEdit);
            //tempNewScoreEdit.setId(counter);

            firstUpdateView = new TextView(getContext());
            firstUpdateView.setLayoutParams(newScorecellParams);

            if (counter == 0) {
                tempNameView.setText("Player");
                tempScoreView.setText("Existing");
                //firstUpdateView.setGravity(Gravity.CENTER);
                firstUpdateView.setText("This Round");

                row.addView(tempNameView);
                row.addView(tempScoreView);
                row.addView(firstUpdateView);
                tempTable.addView(row, counter);
            } else {
                tempNameView.setText(localplNames[counter]);

                tempScoreView.setText(String.valueOf(localplScores[counter]));

                ed[counter].addTextChangedListener(new CustomTextWatcher(ed[counter], counter));

                row.addView(tempNameView);
                row.addView(tempScoreView);
                row.addView(ed[counter]);
                tempTable.addView(row, counter);
            }
        }

        return v;
    }


    private class CustomTextWatcher implements TextWatcher {
        private EditText mEditText;
        private int editi;

        public CustomTextWatcher(EditText e, int i) {
            mEditText = e;
            editi = i;
        }

        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            //mEditText.setFocusable(true);
        }

        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        public void afterTextChanged(Editable s) {
            for (int k = 0; k < ed.length; k++) {
                if (s.hashCode() == ed[k].getText().hashCode()) {
                    individualRoundScores[editi] = ed[k].getText().toString();
                }
            }
        }
    }
}

【问题讨论】:

    标签: java android android-edittext


    【解决方案1】:

    我在我的演示项目中使用这种类型的动态添加Edittext,如下所示:

    更新

    我将代码更改为与您的代码相似,以便找到错误。您还可以看到我的完整代码和布局。它与您的代码相同,我可以输入任何EditText,也可以阅读。如果您仍然发现错误,请提供一些布局信息。

    DEmo.java 为:

    public class DEmo extends AppCompatActivity {
     int[] SCORE = {1, 4, 6, 5, 3};
        String[] PLAYERS_LIST = {"aa", "bb", "cc", "dd", "ee"};
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.demo);
    
            Bundle bundle = new Bundle();
            bundle.putIntArray("SCORE", SCORE);
            bundle.putStringArray("PLAYERS_LIST", PLAYERS_LIST);
    
            Fragment fragment = new fragment();
            fragment.setArguments(bundle);
    
            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
            transaction.replace(R.id.ly, fragment, "Fragment");
            transaction.commitAllowingStateLoss();
    
    
        }
    }
    

    demo.xml:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <FrameLayout
            android:id="@+id/ly"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" />
    </LinearLayout>
    

    我的 fragment.java 如下:

    
    public class fragment extends Fragment {
        private String[] globalplNames, localplNames, individualRoundScores;
        private int[] globalplScores, localplScores;
        private Bundle USBundle;
        private TableLayout tempTable;
        private TextWatcher editWatcher;
        private int globalCount, localCount, counter;
        private TextView tempNameView, tempScoreView, firstUpdateView;
        //private EditText tempNewScoreEdit;
        //List<EditText> allEds = new ArrayList<EditText>();
        private EditText[] ed;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setHasOptionsMenu(true);
            setRetainInstance(true);
            USBundle = this.getArguments();
            globalCount = USBundle.getIntArray("SCORE").length;
            localCount = globalCount + 1;
    
            globalplNames = new String[globalCount];
            globalplNames = USBundle.getStringArray("PLAYERS_LIST");
    
            localplNames = new String[localCount];
    
            globalplScores = new int[globalCount];
            globalplScores = USBundle.getIntArray("SCORE");
    
            localplScores = new int[localCount];
    
            individualRoundScores = new String[localCount];
    
            ed = new EditText[localCount];
    
            for (counter = 0, localCount = 0; counter < globalCount; counter++) {
                localplNames[localCount + 1] = globalplNames[counter];
                localplScores[localCount + 1] = globalplScores[counter];
                localCount++;
            }
    
            localCount = globalCount + 1;
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
            View v = inflater.inflate(R.layout.fragment_view, parent, false);
            TableRow.LayoutParams rowParams = new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT);
            TableRow.LayoutParams namecellParams = new TableRow.LayoutParams(0, TableRow.LayoutParams.WRAP_CONTENT, 0.5f);
            TableRow.LayoutParams liveScorecellParams = new TableRow.LayoutParams(0, TableRow.LayoutParams.WRAP_CONTENT, 0.25f);
            TableRow.LayoutParams newScorecellParams = new TableRow.LayoutParams(0, TableRow.LayoutParams.WRAP_CONTENT, 0.25f);
    
            tempTable = (TableLayout) v.findViewById(R.id.ly);
    
            for (counter = 0; counter < localCount; counter++) {
                TableRow row = new TableRow(getContext());
    
                row.setLayoutParams(rowParams);
                row.setWeightSum(1f);
    
                tempNameView = new TextView(getContext());
                tempNameView.setTextSize(16);
                tempNameView.setLayoutParams(namecellParams);
    
                tempScoreView = new TextView(getContext());
                tempScoreView.setTextSize(16);
                tempScoreView.setLayoutParams(liveScorecellParams);
                tempScoreView.setGravity(android.view.Gravity.CENTER);
    
                ed[counter] = new EditText(getContext());
                ed[counter].setTextSize(16);
                ed[counter].setLayoutParams(newScorecellParams);
                ed[counter].setInputType(InputType.TYPE_CLASS_NUMBER);
                ed[counter].setHint("+/-");
                ed[counter].setFocusableInTouchMode(true);
                ed[counter].setGravity(android.view.Gravity.CENTER);
                //allEds.add(tempNewScoreEdit);
                //tempNewScoreEdit.setId(counter);
    
                firstUpdateView = new TextView(getContext());
                firstUpdateView.setLayoutParams(newScorecellParams);
    
                if (counter == 0) {
                    tempNameView.setText("Player");
                    tempScoreView.setText("Existing");
                    //firstUpdateView.setGravity(Gravity.CENTER);
                    firstUpdateView.setText("This Round");
    
                    row.addView(tempNameView);
                    row.addView(tempScoreView);
                    row.addView(firstUpdateView);
                    tempTable.addView(row, counter);
                } else {
                    tempNameView.setText(localplNames[counter]);
    
                    tempScoreView.setText(String.valueOf(localplScores[counter]));
    
                    ed[counter].addTextChangedListener(new CustomTextWatcher(ed[counter], counter));
    
                    row.addView(tempNameView);
                    row.addView(tempScoreView);
                    row.addView(ed[counter]);
                    tempTable.addView(row, counter);
                }
            }
    
            return v;
        }
    
    
        private class CustomTextWatcher implements TextWatcher {
            private EditText mEditText;
            private int editi;
    
            public CustomTextWatcher(EditText e, int i) {
                mEditText = e;
                editi = i;
            }
    
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                //mEditText.setFocusable(true);
            }
    
            public void onTextChanged(CharSequence s, int start, int before, int count) {
    
            }
    
            public void afterTextChanged(Editable s) {
                for (int k = 0; k < ed.length; k++) {
                    if (s.hashCode() == ed[k].getText().hashCode()) {
                        individualRoundScores[editi] = ed[k].getText().toString();
                    }
                }
            }
        }
    
    
    }
    

    fragment_view.xml

     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical" android:layout_width="match_parent"
        android:layout_height="match_parent"
     >
    
        <TableLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:id="@+id/ly"/>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="readtext"
            android:text="done"/>
    
     </LinearLayout>
    

    希望对你有帮助

    【讨论】:

    • 感谢您的回复。我已经尝试过这种哈希码方法。您的代码看起来类似于我的 hashcode 方法。但是,问题仍然存在。我无法在 2nd/3rd 中输入任何文本……以此类推,也无法从这些 EditText 视图中读取任何内容。
    • 您能告诉我您尝试从 EditText 视图和显示/打印中读取的位置吗?
    • individualRoundScores[editi] = ed[k].getText().toString(); afterTextChanged 中的这一行用于将文本读取到字符串数组 individualRoundScores。
    • @whatsinaname 你解决了你的问题吗?我更新了我的答案。
    • 是的,我能够在不更改任何代码的情况下解决它。不知何故,AVD 无法正常工作,并且不允许我 EditText 读取或接受任何值。现在,它已经开始正常工作了。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2018-02-16
    • 1970-01-01
    • 2012-12-21
    • 2014-07-28
    • 2017-10-14
    • 2021-01-18
    • 1970-01-01
    • 2011-08-20
    相关资源
    最近更新 更多