Bom dia!
Estou carregando um EditText em uma ListView, até ai tudo bem.
Quando digito alguma coisa nesse EditText e rolo a ListView, o valor digitado no EditText vai para outra posição da ListView.
Alguém poderia me ajudar a resolver isso?
Desde já agradeço!
Abraço!
Poste seu código para podermos ajudar.
Quando o getView é chamado, ele pode retornar para voce uma View no “convertView”, essa é uma View que já está no Layout mas está fora da area de scrollagem, então o Adapter o reaproveita para exibir um novo item.
Voce tem que sempre limpar setar estado da View no getView.
Eis o código do meu Adapter:
[code]public class ListAdapterPedidos extends BaseAdapter{
private Context context;
private List<Sapatos> lista;
private ViewHolder holder;
ArrayList<String> teste = new ArrayList<String>();
static class ViewHolder{
private ImageView img;
private EditText edt;
}
public ListAdapterPedidos(Context context, List<Sapatos> lista)
{
this.context = context;
this.lista = lista;
}
public int getCount()
{
return lista.size();
}
public Object getItem(int position)
{
return lista.get(position);
}
public long getItemId(int position)
{
return position;
}
public View getView(final int position, View convertView, ViewGroup parent){
final Sapatos sapato = lista.get(position);
if (convertView == null){
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.list_pedidos, null);
holder.img = (ImageView) convertView.findViewById(R.id.imgPed);
holder.edt = (EditText)convertView.findViewById(R.id.editText1);
final LinearLayout layout;
layout = (LinearLayout)convertView.findViewById(R.id.LayoutPed);
convertView.setTag(holder);
} else{
holder = (ViewHolder) convertView.getTag();
}
holder.img.setImageResource(sapato.getImagem());
return convertView;
}
[/code]
Marky,
Como assim, limpar setar estado da View no getView?
Voce tem que sempre limpar o estado da View e setar o novo pelo getView.
O currentView reaproveita uma View previamente utilizada por questões de performance. Portanto se você tinha um determinado valor naquela View, ao rolar a lista a View será reaproveitada e caso você não a limpe os valores antigos estarão lá. No seu código você já faz:
holder.img.setImageResource(sapato.getImagem());
Mas repare que em momento algum você limpa/reatribui algum valor ao seu EditText. Ficaria algo assim:
public View getView(final int position, View convertView, ViewGroup parent){
final Sapatos sapato = lista.get(position);
if (convertView == null){
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.list_pedidos, null);
holder.img = (ImageView) convertView.findViewById(R.id.imgPed);
holder.edt = (EditText)convertView.findViewById(R.id.editText1);
final LinearLayout layout;
layout = (LinearLayout)convertView.findViewById(R.id.LayoutPed);
convertView.setTag(holder);
} else{
holder = (ViewHolder) convertView.getTag();
}
holder.img.setImageResource(sapato.getImagem());
holder.edt.setText(""); //adicionei somente esta linha
return convertView;
}
Para uma ListView de visualização apenas (sem edição) isso já seria suficiente. Entretanto, usando elementos editáveis, acho que você vai perder o que botou no EditText caso você role a lista e depois volte pra linha anterior. Pra resolver isso, uma sugestão, é adicionar um TextWatcher nos seus EditText. Toda vez que o valor do EditText é alterado você o armazena em algum lugar. Depois no getView basta usar este valor.
Falou.
Esse TextWatcher eu tenho que colocar nesta classe aqui?
[code]public class Pedidos extends Activity{
ListView listview;
@Override
public void onCreate(Bundle icicle){
super.onCreate(icicle);
setContentView(R.layout.pedidos);
listview = (ListView)findViewById(R.id.listPed);
final ArrayList<Sapatos> lista = new ArrayList<Sapatos>();
lista.add(new Sapatos(0));
lista.add(new Sapatos(1));
lista.add(new Sapatos(2));
lista.add(new Sapatos(3));
lista.add(new Sapatos(4));
lista.add(new Sapatos(5));
lista.add(new Sapatos(6));
lista.add(new Sapatos(7));
ListAdapterPedidos adapter = new ListAdapterPedidos(this, lista);
listview.setAdapter(adapter);
}
[/code]
Tem que adicionar o TextWatcher no teu EditText. Quando tu pega a referência dele, pode chamar o addTextChangedListener passando o TextWatcher. Algo assim:
...
holder.edt.setText(""); //adicionei somente esta linha
holder.edt.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
//logica aqui...
}
public void beforeTextChanged(CharSequence s, int start, int count, int after){
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
});
//...
Falou.
Wagner,
adicionei um TextWatcher e preenchi o valor digitado em um ArrayList, e depois eu tento fazer com que o EditText receba o valor do ArrayList na posição em que se encontra.
Ao fazer isso ele devia adicionar o valor na posição correta, mas ele adiciona em várias posições. Sabe o que pode ser?
Ex:
Digito o valor 2 no EditText da primeira posição da lista. Ele deveria adicionar esse valor na primeira posição da lista, mas ele adiciona em várias posições o valor 2.
Está assim meu código:
public View getView(final int position, View convertView, ViewGroup parent){
// Recupera o Sapato da posição atual
sapato = lista.get(position);
if (convertView == null){
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.list_pedidos, null);
holder.img = (ImageView) convertView.findViewById(R.id.imgPed);
holder.edt = (EditText)convertView.findViewById(R.id.editTextt);
final LinearLayout layout;
layout = (LinearLayout)convertView.findViewById(R.id.LayoutPed);
convertView.setTag(holder);
} else{
holder = (ViewHolder) convertView.getTag();
}
holder.img.setImageResource(sapato.getImagem());
if(teste.size() > 0){
holder.edt.setText(teste.get(position));
}
else
holder.edt.setText("");
holder.edt.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
}
@Override
public void afterTextChanged(Editable s) {
if (s != null){
teste.add(s.toString());
}
}
});
return convertView;
Desde já agradeço!
Abraço!
Tentei de um jeito aqui e fico um pouco melhor, mais anda esta gravando na posição errada.
Se eu digita um valor na primeira linga do ListView ele grava na ultima posição que aparece, se eu for rolando a listview e digita um novo valor ele sempre grava na ultima posição da list view que aparece na tela.
Ficou assim meu código:
...
if(sapato.getValor() != null){
holder.edt.setText(sapato.getValor());
Log.i("CHB", "Valor do EditText: " + sapato.getValor());
}
else
holder.edt.setText("");
holder.edt.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
}
@Override
public void afterTextChanged(Editable s) {
if (s != null){
sapato.setValor(s.toString());
//teste.add(s.toString());
Log.i("CHB", "TEXTO: " + s.toString());
}
}
});
Log.i("POSICAO", "Posicao: " + position);
return convertView;
}
Galera,
Estou com problemas com o EditText dentro do ListView.
O meu problema é o seguinte. O foco sempre começa no ultimo registro.
E quando vou editar ele deixa eu editar somente 3 devido ao campo de visao que eu tenho no tablet.
Alguem sabe como resolver isso?
Att
Vinicius
Eu tentaria com o setNextFocusDownId ou setNextForwardFocusId para honeycomb>
Passei os valores nos metodos e continuou a mesma coisa.
Att
Cara ele salva na mesma posicao pois seu int esta setado como final !
assim, ele pode ser instanciado apenas uma vez, e sempre sera aquele valor!
tente alterar pra ver !
Abarços!
Ok. vou testar. O projeto esta parado mesmo.