Android 如何在列表视图中添加 EditText 并在所有行中动态获取其值?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10929971/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 05:30:35  来源:igfitidea点击:

How to add EditText in listview and get its value dynamically in all the rows?

androidlistviewcheckboxscrollandroid-edittext

提问by Mathew

I have Checkbox and EditText and a Textview in a listView. It gets value for the text view from a list. Checkbox will be checked dynamically. In the same way EditText also can be entered dynamically. Now my problem is, When i scroll the list view (up and down) after entering the text in the Edit text, I could not get the typed value. I check the check box also like that. But using the position, I set it correct. I Could not know How to set the EditText value to the list properly. Please help me. Here is my code:

我在 listView 中有 Checkbox 和 EditText 以及一个 Textview。它从列表中获取文本视图的值。复选框将被动态检查。同样,EditText 也可以动态输入。现在我的问题是,当我在编辑文本中输入文本后滚动列表视图(向上和向下)时,我无法获得键入的值。我也喜欢那个复选框。但是使用该位置,我将其设置正确。我不知道如何将 EditText 值正确设置为列表。请帮我。这是我的代码:

main.xml: (Main xml for launch)

main.xml:(用于启动的主要 xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<ListView
android:id="@+id/my_list"
android:layout_width="fill_parent"
android:layout_height="250px" />
<Button 
android:text="Save" 
android:id="@+id/btnSave" 
android:layout_width="wrap_content" 
android:layout_height="wrap_content"/>

</LinearLayout>

row.xml: (ListView Row)

row.xml: (ListView Row)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >

<TextView
android:id="@+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@+id/label"
android:textSize="30sp"/>

<CheckBox
android:id="@+id/check"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<EditText 
android:text=""
android:id="@+id/txtAddress"
android:layout_width="150px"
android:layout_height="wrap_content"/>
</LinearLayout>

Model.Java: (It is the POJO class)

Model.Java:(是POJO类)

package com.checkboxlistview;

public class Model {

private String name;
private boolean selected;
private String address;

public String getAddress() {
    return address;
}

public void setAddress(String address) {
    this.address = address;
}

public void setName(String name) {
    this.name = name;
}

public Model(String name) {
    this.name = name;
}

public String getName() {
    return name;
}

public boolean isSelected() {
    return selected;
}

public void setSelected(boolean selected) {
    this.selected = selected;
}

}

MyAdapter.Java: (This is used to Hold the view in the list view using the converter and holder)

MyAdapter.Java:(这用于使用转换器和持有人在列表视图中保存视图)

package com.checkboxlistview;

import java.util.List;
import android.app.Activity;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.TextView;

public class MyAdapter extends ArrayAdapter<Model> implements TextWatcher {

private final List<Model> list;
private final Activity context;
int listPosititon;

public MyAdapter(Activity context, List<Model> list) {
    super(context, R.layout.row, list);
    this.context = context;
    this.list = list;
}

static class ViewHolder {
    protected TextView text;
    protected CheckBox checkbox;
    protected EditText address;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    listPosititon = position;
    ViewHolder viewHolder = null;
    if (convertView == null) {
        LayoutInflater inflator = context.getLayoutInflater();
        convertView = inflator.inflate(R.layout.row, null);
        viewHolder = new ViewHolder();
        viewHolder.text = (TextView) convertView.findViewById(R.id.label);
        viewHolder.checkbox = (CheckBox) convertView
                .findViewById(R.id.check);
        viewHolder.address = (EditText) convertView
                .findViewById(R.id.txtAddress);
        viewHolder.checkbox
                .setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
int getPosition = (Integer) buttonView.getTag(); 
//Here we get the position that we have  set for the checkbox using setTag.
list.get(getPosition).setSelected(
buttonView.isChecked()); 
// Set the value of checkbox to maintain its state.
}
});
        viewHolder.address.addTextChangedListener(this);

        convertView.setTag(viewHolder);
        convertView.setTag(R.id.label, viewHolder.text);
        convertView.setTag(R.id.check, viewHolder.checkbox);
        convertView.setTag(R.id.txtAddress, viewHolder.address);
    } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }
    viewHolder.checkbox.setTag(position); // This line is important.

    viewHolder.text.setText(list.get(position).getName());
    viewHolder.checkbox.setChecked(list.get(position).isSelected());
    if (list.get(position).getAddress() != null) {
        viewHolder.address.setText(list.get(position).getAddress() + "");
    } else {
        viewHolder.address.setText("");
    }

    return convertView;
}

@Override
public void afterTextChanged(Editable s) {
    list.get(listPosititon).setAddress(s.toString());
}

@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
        int arg3) {
    // TODO Auto-generated method stub

}

@Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
    // TODO Auto-generated method stub

}
}

MainActivity.java (This is the activity):

MainActivity.java(这是活动):

package com.checkboxlistview;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends Activity { 
 ListView listView;
 Button btnSave;
    ArrayAdapter<Model> adapter;
    List<Model> list = new ArrayList<Model>();

    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.main);

        listView = (ListView) findViewById(R.id.my_list);
        btnSave = (Button)findViewById(R.id.btnSave);
        adapter = new MyAdapter(this,getModel());
        listView.setAdapter(adapter);
        btnSave.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                for (int i = 0; i < list.size(); i++) {
                    Toast.makeText(getBaseContext(), "Name : "+list.get(i).getName() +" Selected: "+list.get(i).isSelected(), Toast.LENGTH_SHORT).show();

                }
            }
        });
    }


    private List<Model> getModel() {
        list.add(new Model("Linux"));
        list.add(new Model("Windows7"));
        list.add(new Model("Suse"));
        list.add(new Model("Eclipse"));
        list.add(new Model("Ubuntu"));
        list.add(new Model("Solaris"));
        list.add(new Model("Android"));
        list.add(new Model("iPhone"));
        list.add(new Model("Java"));
        list.add(new Model(".Net"));
        list.add(new Model("PHP"));
        return list;
    }
}

There is no error in the code. It runs well. I could maintain the checkbox position and display at the same position even I scroll up and down. But I could not get and set the EditText value properly. Please Help me out. Thanks in advance.

代码中没有错误。它运行良好。即使我上下滚动,我也可以保持复选框位置并显示在同一位置。但我无法正确获取和设置 EditText 值。请帮帮我。提前致谢。

采纳答案by Munish Kapoor

you can achieve this using the custom list view.

您可以使用自定义列表视图来实现这一点。

find the example of listview with edittext is here

找到带有edittext的列表视图的例子是here

回答by Vikas

Just keep viewHolder.address.setTag(position) and it works perfect cheers.

只要保持 viewHolder.address.setTag(position) 和它完美的欢呼。

Adapter Class:

适配器类:

package com.qzick.adapter;

import java.util.ArrayList;
import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.TextView;

import com.example.qzick.R;
import com.qzick.model.Get_All_Class_Model;

public class Get_Class_Adapter extends BaseAdapter {
    protected ArrayList<Get_All_Class_Model> get_class_details;
    LayoutInflater inflater;
    Context context;
    private int x = 1;

    public Get_Class_Adapter(Context context,
            ArrayList<Get_All_Class_Model> get_class_details) {
        this.get_class_details = get_class_details;
        this.inflater = LayoutInflater.from(context);
        this.context = context;

    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return get_class_details.size();
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return get_class_details.get(position);
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        final ViewHolder holder;
        if (convertView == null) {
            holder = new ViewHolder();
            convertView = this.inflater.inflate(
                    R.layout.activity_adapter_class_ll, parent, false);

            holder.textclass = (TextView) convertView
                    .findViewById(R.id.text_class_ll);

            holder.txtid = (TextView) convertView.findViewById(R.id.text_id_ll);

            holder.checkclass = (CheckBox) convertView
                    .findViewById(R.id.check_class_LL);

            holder.edtsection = (EditText) convertView
                    .findViewById(R.id.edttxt_addsection_ll);

            holder.checkclass
                    .setOnCheckedChangeListener(new OnCheckedChangeListener() {

                        @Override
                        public void onCheckedChanged(CompoundButton buttonView,
                                boolean isChecked) {

                            int getPosition = (Integer) buttonView.getTag();

                            get_class_details.get(getPosition).setChecked(
                                    buttonView.isChecked());

                            notifyDataSetChanged();
                        }
                    });

            convertView.setTag(holder);
            convertView.setTag(R.id.check_class_LL, holder.checkclass);
            convertView.setTag(R.id.edttxt_addsection_ll, holder.edtsection);

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

        holder.checkclass.setTag(position);
        holder.edtsection.setTag(position);

        holder.edtsection.addTextChangedListener(new TextWatcher() {

            @Override
            public void onTextChanged(CharSequence s, int start, int before,
                    int count) {
                int pos = (Integer) holder.edtsection.getTag();

                get_class_details.get(pos).setEdtsections(s.toString());

            }

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

            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

        holder.txtid.setText(get_class_details.get(position).getId());
        holder.textclass.setText(get_class_details.get(position).getText());
        holder.edtsection.setText(get_class_details.get(position)
                .getEdtsections());

        holder.textclass.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                x++;

                if (x % 2 == 0) {
                    holder.checkclass.setChecked(false);

                } else {
                    holder.checkclass.setChecked(true);
                }

            }
        });

        holder.checkclass.setChecked(get_class_details.get(position)
                .isChecked());
        return convertView;
    }

    private class ViewHolder {
        TextView textclass, txtid;`enter code here`
        CheckBox checkclass;
        EditText edtsection;
    }
}

回答by Rahul Ogale

Easy and beautiful solution to handle EditText with listView: (Does not require holder or RecycleView or anything else)

使用 listView 处理 EditText 的简单而漂亮的解决方案:(不需要持有人或 RecycleView 或其他任何东西)

Brief explaination:

简要说明:

1) In getView method when you inflate the view, apply the myTextWatcher the editText. Pass this EditText to the myTextWatcher()

1) 在 getView 方法中,当您膨胀视图时,将 myTextWatcher 应用到 editText。将此 EditText 传递给 myTextWatcher()

2) Inside getView Method find that EditText and set position as editText.setTag [Each time. not only when the view was inflated.]

2) 在 getView 方法中找到 EditText 并将位置设置为 editText.setTag [每次。不仅是在视图被夸大时。]

3) Define MyTextWatcher. It should have reference to EditText on which it is applied.

3) 定义 MyTextWatcher。它应该引用它所应用的 EditText。

4) myTextWatcher.onTextChanged() will read the tag set to the editText and do the required work

4) myTextWatcher.onTextChanged() 将读取设置为 editText 的标签并执行所需的工作

Modify your getView() method of Adapter class:

修改 Adapter 类的 getView() 方法:

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

        if(convertView==null){
            convertView = LayoutInflater.from(getContext()).inflate(R.layout.single_row_layout,parent,false);
            EditText et = convertView.findViewById(R.id.idEditText);
            et.addTextChangedListener(new MyTextWatcher(et));
        }

    //This is again required to find reference to EditText... so that 'position' can be applied on to it as 'tag' EACH time.    
    EditText editText = (EditText) convertView.findViewById(R.id.idEditText);;

    //This tag will be used inside onTextChanged()
    editText.setTag(position);

}

Define your MyTextWatcher class as:

将您的 MyTextWatcher 类定义为:

private class MyTextWatcher implements TextWatcher{
    //int position;
    EditText et;
    public MyTextWatcher(EditText editText){
        this.et = editText;
    }

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

    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        if(et.getTag()!=null){
            // This is required to ensure EditText is edited by user and not through program
            if(et.hasFocus()){
                 int position = (int)et.getTag();
                 String newText = et.getText()+"";
                 //Implement your actions here........
                 //you can get require things/ views from listView.getChildAt(position).. 
            }

        }

    }

    @Override
    public void afterTextChanged(Editable s) {

    }
}