EditText上载到Android的ListView的内容不被保存 [英] The content of EditText contained into a Android ListView isn't saved

查看:205
本文介绍了EditText上载到Android的ListView的内容不被保存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的项目,我要展现给用户的是包含基本的EditText上一个ListView。

On my project I have to show to the user a ListView which is contained basically of EditText.

这就像一个问卷调查,当他回答这个问题,他可升可跌,并回答下一个问题。 (并返回)

It is like a questionnaire, when he answer to the question he can go down and answer to the next question. (and go back)

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一些特殊的值。我没有找到如何纠正这种行为,这真是着急。

I don't know why but the user go down in the ListView, the content is unsaved and show some special values like others EditText. I didn't find how to correct that behaviour and it's really in a hurry.

基本上,我做了一个TextWatcher该寄存器中的数据到数据库中,还融入了临时HashMap中包含的所有值。该数据被称为回来时GetView被调用。如果我删除初始化时,EditText上被擦除。

Basically I made a TextWatcher which register data into the database and also into a temporary HashMap which contains all values. That data is called back when GetView is called. If I remove that initialisation, the EditText is erased.

注:我在code做了一些测试,以便有可能是不同的问题。

Note : I made some test in my code so there may be different problem.

修改

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

I uploaded a project with the problem : http://dl.free.fr/rbqOhUfJF

下面的步骤来重现问题:

Here the steps to reproduce the problem :

  1. 在启动调试模式下的项目

  1. launch the project in debug mode

写在第一行A,第二B,在第三个C

write in the first row A, in the second B, in the third C

向下滚动,直到C被隐藏

Scroll down until C is hidden

滚动到顶部。结果:有没有更多的文字

scroll up to the top. Result : There is no more text.

如果你仔细看的调试日志,你可以看到符合afterText。我们写在部2一些文本各次,将有与该事件的登记调试行

If you look closely on the debug log you can see line with afterText. Each times we write some text in the part 2, there will be a debug line with the registration of the event.

但在第3阶段,当你隐藏的项目。该活动将与启动

But at the phase 3, when you hide an item. the event will be launched with ""

结果:在第四阶段,它加载了串

Result : in the 4th phase, it loads the "" string

推荐答案

要加快在大多数移动应用的东西(安卓iOS的...)列表的细胞通常回收。这免去记忆特别是对长列表。因此,你必须得到一个新的单元格中显示的数据。当小区位于屏幕外,其布局/视图被破坏。你的情况,你必须保存编辑文本的文本的地方。这就是你正在尝试做的HashMap的是什么。

To speed up things in most mobile apps (Android iOS ...) cells of lists are usually recycled. This spares memory especially for long lists. Therefore you have to get the data of a new displayed cell. When the cell goes outside the screen, its layout/view is destroyed. In your case you have to save the text of the edit text somewhere. That's what you are trying to do with the hashmap.

我没有看到你的code任何特定的错误。

I don't see any particular mistake in your code.

如果问题是关于使用HashMap中的解决办法,我可以证实,对我来说这是由你来保存编辑文本的状态。使用一个HashMap是这样做的一种方式。

If the question is about the "workaround" of using the hashmap, I confirm that for me it is up to you to save the states of the edit text. Using a hashmap is one way of doing it.

顺便说一句的getItem(位置).ID 可以通过 getItemId被替换(位置)这是这里该目的。

By the way getItem(position).id can be replaced by getItemId(position) which is here for that purpose.

不知道这一切的回答你的问题。

Not sure if all this answers your question.

修改

现在,我明白你的问题正确,我可以提供一些code。我必须说,我并不完全满意发现,但至少这是工作的解决方案。

Now that I understood your question correctly I can provide some code. I must say that I am not fully happy with the solution found but at least it is working.

与TextWatcher的问题是,你必须到相应的视图的情况下,没有访问权限。

The problem with the TextWatcher is that you have no access to the context and of the corresponding view.

使用setOnFocusChangeListener解决了这个问题。因此,这里是code,我终于得到了工作。

Using setOnFocusChangeListener solved the problem. So here is the code I finally got working.

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;
    }

}

最后修改

在previous code是工作,但我不喜欢它,因为你要的 addTextChangedListener 而不是 onFocusChange

The previous code is working but I wasn't happy with it because you asked for addTextChangedListenerand not for onFocusChange.

因此​​,这里的解决方案:

So here is the solution :

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());
        }
    }
}

这篇关于EditText上载到Android的ListView的内容不被保存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆