当前位置: 首页 > 面试题库 >

Android ListView中包含的EditText的内容未保存

尹善
2023-03-14
问题内容

在我的项目中,我必须向用户显示一个ListView,它基本上包含EditText。

就像问卷一样,当他回答问题时,他可以下去回答下一个问题。(然后返回)

public class onAdapter extends BaseAdapter {
    List<PointVerification> mObjects;
    Context mContext;
    LayoutInflater mInflater;

    HashMap<Integer, List<ChoixPointVerification>> mChoix;
    HashMap<Integer, ReponsePointVerification> mReponses;
    HashMap<Integer, String> mReponsesActuel;
    Integer mPositionSelectionne;
    Integer mIdIntervention;


    /**
     * Constructeur
     * @param context

     * @param listePointsVerification Liste des points de vérification à afficher.
     * @param listeChoixPointsVerification liste des choix de points de vérification pour chaque point de vérification.
     * @param listeReponsesPointsVerification réponses déjà fournies pour chaque point de vérification
     * @param idIntervention Identifiant de l'intervention
     */
    public onAdapter(
            Context context,

            Integer idIntervention, 
            List<PointVerification> listePointsVerification,
            List<ChoixPointVerification>> listeChoixPointsVerification,
            ReponsePointVerification> listeReponsesPointsVerification) {

        this.mInflater = LayoutInflater.from(context);
        this.mContext = context;
        this.mObjects = listePointsVerification;

        this.mChoix = listeChoixPointsVerification;
        this.mReponses = listeReponsesPointsVerification;
        this.mIdIntervention = idIntervention;


        // préparation des réponses par position
        this.mReponsesActuel = new HashMap<Integer, String>();
    }


    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row;

        final Integer idPointVerification = getItem(position).id;

        if (convertView == null)
        {
            row = mInflater.inflate(R.layout.intervention_reponses_controle_nombre, null);

            EditText edValeur = (EditText) row.findViewById(R.id.edValeur);
            // Ajout de l'évènement lorsque l'on change la valeur
            // evènement d'enregistrement
            edValeur.addTextChangedListener(new TextWatcher()

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

                @Override
                public void beforeTextChanged(CharSequence s, int start, int count,
                        int after) {
                }

                @Override
                public void afterTextChanged(Editable s) {
                    // This hashmap is a try workaround to the bug
                    // i register all modifications into this hashmap
                    mReponsesActuel.put(
                            idPointVerification,
                            s.toString());

                    // SAVE PROCEDURE
                    // REMOVED FOR THE EXAMPLE
                    // BUT I UPDATE MY DATABASE
                }
            });
        }
        else
        {
            row = convertView;
        }

        EditText edValeur = (EditText) row.findViewById(R.id.edValeur);

        // update of the text
        // it is the contained in the hashmap
        if (mReponsesActuel.containsKey(idPointVerification)) {
            String valeur = mReponsesActuel.get(idPointVerification);
            edValeur.setText(valeur);
        // otherwhise i will look into the database
        } else if (mReponses != null && mReponses.containsKey(idPointVerification)
                && mReponses.get(idPointVerification).valeur != null) {
            edValeur.setText(mReponses.get(idPointVerification).valeur);
        }
        else
        {
            edValeur.setText("");
        }

        return row;
    }
}

我不知道为什么,但是用户进入ListView,内容未保存,并显示一些特殊值,如其他EditText。我没有找到纠正该行为的方法,这真的很着急。

基本上,我做了一个TextWatcher,将数据注册到数据库中,还注册到了包含所有值的临时HashMap中。调用GetView时会回叫该数据。如果删除该初始化,则EditText将被擦除。

注意:我在代码中做了一些测试,所以可能存在其他问题。

编辑

我上传了一个有问题的项目:http :
//dl.free.fr/rbqOhUfJF

这里是重现该问题的步骤:

  1. 以调试模式启动项目

  2. 写在第一行A,第二行B,第三行C

  3. 向下滚动直到C隐藏

  4. 向上滚动到顶部。结果:没有更多文本。

如果仔细查看调试日志,则可以看到与afterText对应的行。每次我们在第2部分中写入一些文本时,都会在事件的注册处出现一条调试行。

但是在第3阶段,当您隐藏一个项目时。活动将以“”启动

结果:在第四阶段,它将加载“”字符串


问题答案:

为了加快大多数移动应用程序(Android iOS
…)的运行速度,通常会回收列表单元格。这样可以节省内存,尤其是对于较长的列表。因此,您必须获取新显示的单元格的数据。当单元超出屏幕时,其布局/视图将被破坏。在您的情况下,您必须将编辑文本的文本保存在某处。这就是您要对哈希图执行的操作。

我看不到您的代码中有任何特别的错误。

如果问题是关于使用哈希图的“解决方法”,那么我确认对我而言,保存编辑文本的状态取决于您。使用哈希图是一种实现方式。

顺便说一下,getItem(position).id可以getItemId(position)为此替换此处。

不确定是否所有这些都能回答您的问题。

编辑

现在,我已经正确理解了您的问题,我可以提供一些代码。我必须说,我对找到的解决方案不完全满意,但至少可以正常使用。

TextWatcher的问题在于您无权访问上下文和相应的视图。

使用setOnFocusChangeListener解决了该问题。所以这是我终于开始工作的代码。

public final class PointVerificationAdapter extends BaseAdapter {
    List<BasicNameValuePair> mObjects;
    Context mContext;
    LayoutInflater mInflater;
    HashMap<Integer, String> mReponsesActuel;
    ArrayList<String> myItems = new ArrayList<String>();

    public PointVerificationAdapter(
            Context context,
            List<BasicNameValuePair> listObjets
            ) {

        this.mInflater = LayoutInflater.from(context);
        this.mContext = context;
        this.mObjects = listObjets;

        for (int i = 0; i < 30; i++) {
            myItems.add(Integer.toString(i));
        }
    }

    @Override
    public int getCount() {
        return mObjects.size();
    }

    @Override
    public BasicNameValuePair getItem(int position) {
        return mObjects.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    static class ViewHolder {
        EditText yourEditText;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder holder = null;

        if (convertView == null)
        {
            holder = new ViewHolder();
            convertView = mInflater.inflate(R.layout.intervention_reponses_controle_nombre, parent, false);
            convertView.setId(position);
            holder.yourEditText = (EditText) convertView.findViewById(R.id.edValeur);

            convertView.setTag(holder);
        }
        else
        {
            holder = (ViewHolder) convertView.getTag();
        }

        ((TextView) convertView.findViewById(R.id.tvNom)).setText(Integer.toString(position));

        holder.yourEditText.setText(myItems.get(position));
        holder.yourEditText.setId(position);
        holder.yourEditText.setOnFocusChangeListener(new OnFocusChangeListener() {
            public void onFocusChange(View view, boolean hasFocus) {
                if (!hasFocus){
                    final int position = view.getId();
                    final EditText editText = (EditText) view;
                    myItems.set(position, editText.getText().toString());
                }
            }
        });

        return convertView;
    }

}

最终编辑

之前的代码可以工作,但我对此不满意,因为您要求addTextChangedListener而不是onFocusChange

所以这是解决方案:

public final class PointVerificationAdapter extends BaseAdapter {
    List<BasicNameValuePair> mObjects;
    Context mContext;
    LayoutInflater mInflater;
    HashMap<Integer, String> mReponsesActuel;
    ArrayList<String> myItems = new ArrayList<String>();

    public PointVerificationAdapter(
            Context context,
            List<BasicNameValuePair> listObjets
            ) {

        this.mInflater = LayoutInflater.from(context);
        this.mContext = context;
        this.mObjects = listObjets;

        for (int i = 0; i < 30; i++) {
            myItems.add(Integer.toString(i));
        }
    }

    @Override
    public int getCount() {
        return mObjects.size();
    }

    @Override
    public BasicNameValuePair getItem(int position) {
        return mObjects.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    static class ViewHolder {
        EditText yourEditText;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder holder = null;

        if (convertView == null)
        {
            holder = new ViewHolder();
            convertView = mInflater.inflate(R.layout.intervention_reponses_controle_nombre, parent, false);
            convertView.setId(position);
            holder.yourEditText = (EditText) convertView.findViewById(R.id.edValeur);
            holder.yourEditText.setId(position);
            holder.yourEditText.addTextChangedListener(new GenericTextWatcher(holder.yourEditText));
            convertView.setTag(holder);
        }
        else
        {
            holder = (ViewHolder) convertView.getTag();
            holder.yourEditText.setId(position);
        }

        ((TextView) convertView.findViewById(R.id.tvNom)).setText(Integer.toString(position));

        holder.yourEditText.setText(myItems.get(position));

        return convertView;
    }

    private class GenericTextWatcher implements TextWatcher{

        private View view;
        private GenericTextWatcher(View view) {
            this.view = view;
        }

        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}

        public void afterTextChanged(Editable editable) {
            final int position = view.getId();
            final EditText editText = (EditText) view;
            myItems.set(position, editText.getText().toString());
        }
    }
}


 类似资料:
  • 我有一个带有的列表项,我不知道会有多少项。当我在中输入一些文本,然后向下滚动时,我遇到了一个问题,当我再次向上滚动后,我的第一个 中没有文本。 我想知道我应该写什么,在哪里写代码,这样当用户在中键入或完成键入(我想用一个>来完成)时,文本会保存到一个文件中(我将它保存在外部存储的.txt文件中) 我应该在活动的方法中,还是在适配器类或其他地方这样做? 下面是一些代码 如果没有这个“addtextC

  • 本文向大家介绍Android实现EditText内容保存为Bitmap的方法,包括了Android实现EditText内容保存为Bitmap的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Android实现EditText内容保存为Bitmap的方法。分享给大家供大家参考,具体如下: 主要代码如下: 更多关于Android控件相关内容感兴趣的读者可查看本站专题:《Android控件用

  • 以下是我用来实现上述布局的代码: 我省略了用于样式设置的代码。你可以在钢笔里看到所有的东西。 上述方法有效,但当区域的内容溢出时,会使整个页面滚动。我只希望内容区域本身滚动,因此我将添加到div。 现在的问题是,柱本身并没有超出其父高度,因此边界也在那里被切断。 这是显示滚动问题的笔。 如何将区域设置为独立滚动,同时使其子项延伸到框的高度之外?

  • 嗨,我正在编写一个简单的物理引擎,以便更好地理解对象碰撞和Java图形,到目前为止,我已经成功地编写了代码,将JPanel添加到JFrame中,并允许它们显示一些正确的大小,但当我查看实际程序时,JPanel似乎是正确的大小,但它不是从窗口的上角开始的,而是从框架的左上角开始的。我似乎有这个问题很多,我想要的东西在(0,0)和开始在框架的上角,而不是面板。下面是我的代码: 我有一个引擎类,它扩展了

  • 问题 阻止类似按钮的内容会导致我的flex项目展开并溢出flexbox容器。 预期行为 在本例中,按钮应与按钮文本并排,并用省略号隐藏。flex项的宽度应基于兄弟项而非内容,并在容器更改宽度和添加或删除flex项时保持在容器内的响应性。另一个警告是,对于我的特定场景,我不能在flex项或buttons父div上使用overflow:hidden。 这是小提琴手。 例Html 示例CSS 编辑:现在

  • 问题内容: 我汇总了一个简单的测试项目,该项目显示了一个包含EditText的PopupWindow(在Android 2.2上)。如我所料,当我点击EditText时,将显示软键盘。但是,软键盘覆盖了EditText,因此无法平移屏幕以使EditText保持应有的状态。我的代码: TestAdjustPanActivity.java: main.xml: popup.xml: …并且我的Andr