¿Por qué mi clase BaseAdapter no incrementa la posición en getView?
Editar: Mi problema parece como BaseAdapter
simplemente no publicar más de 1 Spinner. Si cambio el tamaño de la matriz a 0, no pondré nada, pero cualquier cosa más de 1 lo está truncando. Nunca pasa la posición 0 de getView()
y nunca shwows más de 1. He estado en él durante horas. ¿Hay alguna razón para esto?
Tengo un problema con la adición de Spinners
dinámicamente en un ListView
utilizando un BaseAdapter
. Lo probé antes como una prueba para asegurarse de que se podía hacer correctamente en una clase de prueba, e itera las posiciones correctamente. Pero ahora lo estoy haciendo de nuevo y su fracaso. Lo que quiero decir con el fracaso es en lugar de getView()
creación de la nueva Spinner
, nunca sale de la posición 0. Todavía se ejecuta. Simplemente no añade más Spinner
s. Este es mi código:
- El adaptador personalizado de Android no funciona correctamente para la lista de chat
- ArrayAdapter en android para crear listview simple
- Establecer el elemento seleccionado por defecto del cuadro de diálogo de alerta de ListView en Android
- Cómo llamar a notifyDataSetChanged () desde un adaptador genérico
- Adaptador ListView personalizado Android
Código del adaptador principal
public class RemindersAdapter extends BaseAdapter{ Spinner[] shownReminders = new Spinner[1]; TextView[] removeReminders = new TextView[1]; String[] reminders = new String[1]; //this hlds the values of the coresponding spinner RemindersAdapter mAdapter; @Override public int getCount() { return shownReminders.length; } @Override public Object getItem(int position) { return shownReminders[position]; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View view, ViewGroup parent) { Log.d("TAG", "A NEW SPINNER AND TEXTVIEW IS CREATED HERE WITH POSITION"+position); if(view == null) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); view = inflater.inflate(R.layout.reminder_spinner, parent, false); } Spinner reminderSpinner = (Spinner)view.findViewById(R.id.reminder_spinner); reminderSpinner.setTag(String.valueOf(position)); ArrayAdapter<CharSequence> reminderAdapter = ArrayAdapter.createFromResource( parent.getContext(), R.array.reminders_array, android.R.layout.simple_spinner_item); reminderAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); reminderSpinner.setAdapter(reminderAdapter); reminderSpinner.setOnItemSelectedListener(new MyOnReminderSelectedListener()); shownReminders[position] = reminderSpinner; TextView remove = (TextView)view.findViewById(R.id.remove_reminder); remove.setTag(String.valueOf(position)); removeReminders[position] = remove; remove.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d("The Array positioning of this remove view is: ", ""+v.getTag()); } }); return view; } public void addReminder() { Log.d("addReminder METHOD", "The Add Reminder method is running"); Spinner[] temp = new Spinner[shownReminders.length+1]; TextView[] temp2 = new TextView[removeReminders.length+1]; String [] temp3 = new String[reminders.length+1]; for(int i = 0; i < shownReminders.length; i++) { temp[i] = shownReminders[i]; temp2[i] = removeReminders[i]; temp3[i] = reminders[i]; } shownReminders = temp; removeReminders = temp2; reminders = temp3; mAdapter.notifyDataSetChanged();//this just makes the adapter refresh itself } public void giveYourself(RemindersAdapter adapter) { mAdapter = adapter; } public class MyOnReminderSelectedListener implements OnItemSelectedListener{ @Override public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) { int position = Integer.parseInt(parent.getTag().toString()); //gets the position of the Spinner and puts it in the same index in the reminders array reminders[position] = parent.getItemAtPosition(pos).toString(); for(int i =0; i < reminders.length; i++) Toast.makeText(parent.getContext(), i+": "+reminders[i], Toast.LENGTH_SHORT).show(); } @Override public void onNothingSelected(AdapterView<?> arg0) { // Do nothing for now } }//end of MyOnReminderSelectedListener innerclass }//end of Class
Lo que se ejecuta en la actividad
reminderList = (ListView)findViewById(R.id.reminders_list); reminderAdapter = new RemindersAdapter(); reminderAdapter.giveYourself(reminderAdapter); reminderList.setAdapter(reminderAdapter); TextView addReminder = (TextView)findViewById(R.id.add_reminder); addReminder.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d("TAG", "The onClick is running !"); reminderAdapter.addReminder(); } });
Estoy en una pérdida porque mi código se ve exactamente como mi código de prueba, con algunas modificaciones para que funcione con mi aplicación. Pero la información utilizada por el Adapter
es casi la misma. Voy a publicar el código de prueba, así que ustedes pueden ver el código que funciona.
Código de prueba
public class RemindersAdapter extends BaseAdapter{ Spinner[] shownReminders = new Spinner[1]; ArrayList<TextView> removeSpinner = new ArrayList<TextView>(); Context mContext; public RemindersAdapter(Context context) { mContext = context; } @Override public int getCount() { // TODO Auto-generated method stub return shownReminders.length; } @Override public Object getItem(int position) { // TODO Auto-generated method stub return shownReminders[position]; } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(int position, View view, ViewGroup parent) { Log.d("TAG", "Number of times this is running"+position); Log.d("TAG", "Address of the Spinner Object"+shownReminders[position]); if(view == null) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); view = inflater.inflate(R.layout.reminder_spinner, parent, false); } Spinner reminderSpinner = (Spinner)view.findViewById(R.id.reminders_spinner); reminderSpinner.setTag("1"); ArrayAdapter<CharSequence> reminderAdapter = ArrayAdapter.createFromResource( parent.getContext(), R.array.reminders_array, android.R.layout.simple_spinner_item); reminderAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); reminderSpinner.setAdapter(reminderAdapter); reminderSpinner.setOnItemSelectedListener(new MyOnReminderSelectedListener()); shownReminders[position] = reminderSpinner; TextView remove = (TextView)view.findViewById(R.id.remove_reminder); remove.setTag(position); removeSpinner.add(remove); remove.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int pos = Integer.parseInt(v.getTag().toString()); removeSpinner.remove(pos); Spinner[] temp = new Spinner[shownReminders.length-1]; for(int i =0; i < shownReminders.length; i++) { if(i == pos || i > pos) { temp[i-1] = shownReminders[i]; } else { temp[i] = shownReminders[i]; } } //Here i should refresh somewhow } }); return view; } public void addReminder() { Spinner[] temp = new Spinner[shownReminders.length+1]; for(int i = 0; i < shownReminders.length; i++) { temp[i] = shownReminders[i]; } shownReminders = temp; } /* * Listener for when the reminder spinner gets a value the user entered * */ public class MyOnReminderSelectedListener implements OnItemSelectedListener{ @Override public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) { //does nothing for now } @Override public void onNothingSelected(AdapterView<?> arg0) { // Do nothing for now } }//end of MyOnReminderSelectedListener innerclass
También tengo una pregunta sobre por qué el adaptador se ejecuta tanto. Por ejemplo, usando el registro, noté que llama a getView()
dos veces sin razón aparente. Su extraño que tiene este comportamiento. Supongo que no entiendo bien a BaseAdapter
. Gracias por adelantado.
- Cómo definir ColorStateList para TextView?
- ¿Cómo trabajar, cuando listview dentro del scrollview?
- Cómo obtener el contexto en getView del adaptador para listview
- Desactivar el encabezado ListView de Android
- ¿Cómo puedo obtener notifyDatasetChanged () para trabajar con un ListAdapter?
- Cómo acceder a archivos de vídeo de la carpeta de tarjetas SD en la aplicación de Android
- Custom ListView con cabecera con pin, causando Jank al ajustar el relleno
- Problema de menú emergente en Android ListView
Un adaptador llamará getView cuando listView necesite un nuevo elemento para mostrarlo. Por lo tanto, si su listView no tiene scroll, no se creará ningún elemento nuevo, y no se realizará ninguna llamada a getView.
Pero no debe almacenar todos los objetos spinner, ni crear nuevos objetos en getView. Eso es porque va a ser lento y tal vez desperdicio de memoria.
Este error ocurrirá si coloca un ListView dentro de ScrollView. ListView se hace desplazamiento vertical por lo que no debe ser puesto en un ScrollView.
- Cómo eliminar el fondo oscuro transparente fuera del cuadro de diálogo
- No se puede iniciar el emulador de Android en Mac