如何使适配器不 return convertView?
How to make an Adapter to not return convertView?
我有一个扩展 ArrayAdapter 的适配器。我给适配器一个 ArrayList,例如,有 9 个对象,我希望它不在 ListView 中显示第五个对象。
有办法吗?我尝试在返回之前设置 convertView = null
但它抛出 NullPointerException
.
这是相关代码,它使视图不接受值,但无论如何都会将其添加到列表视图中:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
/*@SuppressLint("ViewHolder") */public class AdapterActions extends ArrayAdapter<Action>{
// our ViewHolder.
// caches our TextView
static class ViewHolderItem {
TextView codigo;
TextView accion;
TextView evento;
Switch UnSwitch;
boolean isChecked1;
}
Activity context;
ArrayList<Action> listaActions;
@SuppressLint("UseSparseArrays") Map <Integer, Boolean> map = new HashMap<Integer, Boolean>();
// Le pasamos al constructor el contexto y la lista de contactos
public AdapterActions(Activity context, ArrayList<Action> listaActions) {
super(context, R.layout.layout_adapter_actions, listaActions);
this.context = context;
this.listaActions = listaActions;
}
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolderItem viewHolder;
// Rescatamos cada item del listview y lo inflamos con nuestro layout
//View item = convertView;
//item = context.getLayoutInflater().inflate(R.layout.layout_adapter_actions, null);
// well set up the ViewHolder
viewHolder = new ViewHolderItem();
if(convertView==null){
// inflate the layout
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
convertView = inflater.inflate(R.layout.layout_adapter_actions, parent, false);
// well set up the ViewHolder
viewHolder.codigo = (TextView) convertView.findViewById(R.id.codigo);
viewHolder.accion = (TextView) convertView.findViewById(R.id.accion);
viewHolder.evento = (TextView) convertView.findViewById(R.id.evento);
viewHolder.UnSwitch = (Switch) convertView.findViewById(R.id.activa);
convertView.setLongClickable(true);
// store the holder with the view.
convertView.setTag(viewHolder);
}else{
// we've just avoided calling findViewById() on resource everytime
// just use the viewHolder
viewHolder = (ViewHolderItem) convertView.getTag();
}
Action a = new Action(-99, 1, 1, true);
AccionDefinida LaAccion = new AccionDefinida(0, 0, "", "");
EventoDefinido ElEvento = new EventoDefinido(0, 0, "", "");
//ACTIONS
ActionsSQLite base = new ActionsSQLite(context, "Actions", null,1);
SQLiteDatabase db1 = base.getReadableDatabase();
db1 = context.openOrCreateDatabase("Actions",SQLiteDatabase.OPEN_READONLY, null);
String query = "SELECT * FROM Actions WHERE Id = " + String.valueOf(position + 1);
Cursor c1 = db1.rawQuery(query, null);
try{
if(c1!=null){
int i = c1.getColumnIndexOrThrow("Id");
int j = c1.getColumnIndexOrThrow("IdAccionDefinida");
int k = c1.getColumnIndexOrThrow("IdEventoDefinido");
int l = c1.getColumnIndexOrThrow("Activa");
boolean esActiva;
//Nos aseguramos de que existe al menos un registro
while(c1.moveToNext()){
if (c1.getInt(l) == 0){
esActiva = false;
} else
{
esActiva = true;
}
//Recorremos el cursor hasta que no haya más registros
a = new Action(c1.getInt(i), c1.getInt(j), c1.getInt(k), esActiva);
}
}
else
Toast.makeText(context.getApplicationContext(),
"No hay nada :(", Toast.LENGTH_LONG).show();
}
catch (Exception e){
Log.i("bdActions", "Error al abrir o crear la base de datos" + e);
}
if(db1!=null){
db1.close();
}
if(a.getId() != -99)
{
//EVENTOS
EventosDefinidosSQLite base2 = new EventosDefinidosSQLite(this.context, "EventosDefinidos", null, 1);
SQLiteDatabase db2 = base2.getReadableDatabase();
db2 = context.openOrCreateDatabase("EventosDefinidos",SQLiteDatabase.OPEN_READONLY, null);
String query2 = "SELECT * FROM EventosDefinidos WHERE Id = " + a.getIdEventoDefinido();
Cursor c2 = db2.rawQuery(query2, null);
try{
if(c2!=null){
int h = c2.getColumnIndexOrThrow("Id");
int k = c2.getColumnIndexOrThrow("IdEvento");
int i = c2.getColumnIndexOrThrow("Nombre");
int j = c2.getColumnIndexOrThrow("Aux");
//Nos aseguramos de que existe al menos un registro
while(c2.moveToNext()){
//Recorremos el cursor hasta que no haya más registros
ElEvento = new EventoDefinido(c2.getInt(h), c2.getInt(k), c2.getString(i), c2.getString(j));
}
}
else
Toast.makeText(context.getApplicationContext(),
"No hay nada :(", Toast.LENGTH_LONG).show();
}
catch (Exception e){
Log.i("bdEventos", "Error al abrir o crear la base de datos" + e);
}
if(db2!=null){
db2.close();
}
//ACCIONES
AccionesDefinidasSQLite base3 = new AccionesDefinidasSQLite(context, "AccionesDefinidas", null,1);
SQLiteDatabase db3 = base3.getReadableDatabase();
db3 = context.openOrCreateDatabase("AccionesDefinidas", SQLiteDatabase.OPEN_READONLY, null);
String query3 = "SELECT * FROM AccionesDefinidas WHERE Id = " + String.valueOf(a.getIdAccionDefinida());
Cursor c3 = db3.rawQuery(query3, null);
try{
if(c3!=null){
int h = c3.getColumnIndexOrThrow("Id");
int k = c3.getColumnIndexOrThrow("IdAccion");
int i = c3.getColumnIndexOrThrow("Nombre");
int j = c3.getColumnIndexOrThrow("Aux");
//Nos aseguramos de que existe al menos un registro
while(c3.moveToNext()){
//Recorremos el cursor hasta que no haya más registros
LaAccion = new AccionDefinida(c3.getInt(h), c3.getInt(k), c3.getString(i), c3.getString(j));
}
}
else
Toast.makeText(context.getApplicationContext(),
"No hay nada :(", Toast.LENGTH_LONG).show();
}
catch (Exception e){
Log.i("bdAcciones", "Error al abrir o crear la base de datos" + e);
}
if(db3!=null){
db3.close();
}
// object item based on the position
// assign values if the object is not null
if(a != null) {
// get the TextView from the ViewHolder and then set the text (item name) and tag (item ID) values
viewHolder.codigo.setText(String.valueOf(a.getId()));
viewHolder.codigo.setTag(a.getId());
viewHolder.accion.setText(LaAccion.getNombre());
viewHolder.evento.setText(ElEvento.getNombre());
viewHolder.UnSwitch.setChecked(a.getActiva());
Log.e("Position+1: "+ String.valueOf(position+1), "Id: "+ String.valueOf(a.getId()));
}
viewHolder.isChecked1 = viewHolder.UnSwitch.isChecked();
map.put(position, viewHolder.isChecked1);
viewHolder.UnSwitch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e("OnClick", "Se clickeó");
listaActions.get(position).setActiva(map.get(position));
Log.e("Listener del switch", "Modificó la action en la lista de la ActividadPrincipal");
int isActiva;
if(map.get(position) == true)
{
isActiva = 0;
Log.e("Listener del switch", "isActiva = 1");
map.put(position, false);
} else
{
isActiva = 1;
Log.e("Listener del switch", "isActiva = 0");
map.put(position, true);
}
String query = "UPDATE Actions SET Activa = " + String.valueOf(isActiva) + " WHERE Id = " + String.valueOf(position+1);
Log.e("Consulta:", query);
Log.e("Listener del switch", "query creado");
Log.e("La position debería ser", String.valueOf(position+1));
Log.e("Y el valor del map.get(position) es", String.valueOf(map.get(position)));
ActionsSQLite helper1 = new ActionsSQLite(context, "Actions", null, 1);
Log.e("Listener del switch", "Creo el helper");
SQLiteDatabase db = helper1.getWritableDatabase();
Log.e("Listener del switch", "obtenida la base escribible");
db.execSQL(query);
Log.e("Listener del switch", "Query ejecutado");
}
});
} else
{
convertView = null;
}
return convertView;
}
}
一旦您告诉 ArrayAdapter 您有(例如)9 个项目,那么您的 getView 函数需要能够为所有 9 个项目创建视图。如果您实际上不希望这些项目之一显示在适配器中,则需要将其从适配器中删除,这样 Android 就不会调用 getView 来显示该项目。
有几种方法可以解决这个问题。最简单的方法是像您目前正在做的那样构造您的适配器,然后为您不想包含的操作调用 remove(action)。
另一种选择是覆盖 BaseAdapter 而不是 ArrayAdapter。然后你可以有更复杂的代码来动态地计算出你想要显示多少项目。 BaseAdapter 更灵活,但实现起来仍然很简单。
有道理吗?
我有一个扩展 ArrayAdapter 的适配器。我给适配器一个 ArrayList,例如,有 9 个对象,我希望它不在 ListView 中显示第五个对象。
有办法吗?我尝试在返回之前设置 convertView = null
但它抛出 NullPointerException
.
这是相关代码,它使视图不接受值,但无论如何都会将其添加到列表视图中:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
/*@SuppressLint("ViewHolder") */public class AdapterActions extends ArrayAdapter<Action>{
// our ViewHolder.
// caches our TextView
static class ViewHolderItem {
TextView codigo;
TextView accion;
TextView evento;
Switch UnSwitch;
boolean isChecked1;
}
Activity context;
ArrayList<Action> listaActions;
@SuppressLint("UseSparseArrays") Map <Integer, Boolean> map = new HashMap<Integer, Boolean>();
// Le pasamos al constructor el contexto y la lista de contactos
public AdapterActions(Activity context, ArrayList<Action> listaActions) {
super(context, R.layout.layout_adapter_actions, listaActions);
this.context = context;
this.listaActions = listaActions;
}
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolderItem viewHolder;
// Rescatamos cada item del listview y lo inflamos con nuestro layout
//View item = convertView;
//item = context.getLayoutInflater().inflate(R.layout.layout_adapter_actions, null);
// well set up the ViewHolder
viewHolder = new ViewHolderItem();
if(convertView==null){
// inflate the layout
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
convertView = inflater.inflate(R.layout.layout_adapter_actions, parent, false);
// well set up the ViewHolder
viewHolder.codigo = (TextView) convertView.findViewById(R.id.codigo);
viewHolder.accion = (TextView) convertView.findViewById(R.id.accion);
viewHolder.evento = (TextView) convertView.findViewById(R.id.evento);
viewHolder.UnSwitch = (Switch) convertView.findViewById(R.id.activa);
convertView.setLongClickable(true);
// store the holder with the view.
convertView.setTag(viewHolder);
}else{
// we've just avoided calling findViewById() on resource everytime
// just use the viewHolder
viewHolder = (ViewHolderItem) convertView.getTag();
}
Action a = new Action(-99, 1, 1, true);
AccionDefinida LaAccion = new AccionDefinida(0, 0, "", "");
EventoDefinido ElEvento = new EventoDefinido(0, 0, "", "");
//ACTIONS
ActionsSQLite base = new ActionsSQLite(context, "Actions", null,1);
SQLiteDatabase db1 = base.getReadableDatabase();
db1 = context.openOrCreateDatabase("Actions",SQLiteDatabase.OPEN_READONLY, null);
String query = "SELECT * FROM Actions WHERE Id = " + String.valueOf(position + 1);
Cursor c1 = db1.rawQuery(query, null);
try{
if(c1!=null){
int i = c1.getColumnIndexOrThrow("Id");
int j = c1.getColumnIndexOrThrow("IdAccionDefinida");
int k = c1.getColumnIndexOrThrow("IdEventoDefinido");
int l = c1.getColumnIndexOrThrow("Activa");
boolean esActiva;
//Nos aseguramos de que existe al menos un registro
while(c1.moveToNext()){
if (c1.getInt(l) == 0){
esActiva = false;
} else
{
esActiva = true;
}
//Recorremos el cursor hasta que no haya más registros
a = new Action(c1.getInt(i), c1.getInt(j), c1.getInt(k), esActiva);
}
}
else
Toast.makeText(context.getApplicationContext(),
"No hay nada :(", Toast.LENGTH_LONG).show();
}
catch (Exception e){
Log.i("bdActions", "Error al abrir o crear la base de datos" + e);
}
if(db1!=null){
db1.close();
}
if(a.getId() != -99)
{
//EVENTOS
EventosDefinidosSQLite base2 = new EventosDefinidosSQLite(this.context, "EventosDefinidos", null, 1);
SQLiteDatabase db2 = base2.getReadableDatabase();
db2 = context.openOrCreateDatabase("EventosDefinidos",SQLiteDatabase.OPEN_READONLY, null);
String query2 = "SELECT * FROM EventosDefinidos WHERE Id = " + a.getIdEventoDefinido();
Cursor c2 = db2.rawQuery(query2, null);
try{
if(c2!=null){
int h = c2.getColumnIndexOrThrow("Id");
int k = c2.getColumnIndexOrThrow("IdEvento");
int i = c2.getColumnIndexOrThrow("Nombre");
int j = c2.getColumnIndexOrThrow("Aux");
//Nos aseguramos de que existe al menos un registro
while(c2.moveToNext()){
//Recorremos el cursor hasta que no haya más registros
ElEvento = new EventoDefinido(c2.getInt(h), c2.getInt(k), c2.getString(i), c2.getString(j));
}
}
else
Toast.makeText(context.getApplicationContext(),
"No hay nada :(", Toast.LENGTH_LONG).show();
}
catch (Exception e){
Log.i("bdEventos", "Error al abrir o crear la base de datos" + e);
}
if(db2!=null){
db2.close();
}
//ACCIONES
AccionesDefinidasSQLite base3 = new AccionesDefinidasSQLite(context, "AccionesDefinidas", null,1);
SQLiteDatabase db3 = base3.getReadableDatabase();
db3 = context.openOrCreateDatabase("AccionesDefinidas", SQLiteDatabase.OPEN_READONLY, null);
String query3 = "SELECT * FROM AccionesDefinidas WHERE Id = " + String.valueOf(a.getIdAccionDefinida());
Cursor c3 = db3.rawQuery(query3, null);
try{
if(c3!=null){
int h = c3.getColumnIndexOrThrow("Id");
int k = c3.getColumnIndexOrThrow("IdAccion");
int i = c3.getColumnIndexOrThrow("Nombre");
int j = c3.getColumnIndexOrThrow("Aux");
//Nos aseguramos de que existe al menos un registro
while(c3.moveToNext()){
//Recorremos el cursor hasta que no haya más registros
LaAccion = new AccionDefinida(c3.getInt(h), c3.getInt(k), c3.getString(i), c3.getString(j));
}
}
else
Toast.makeText(context.getApplicationContext(),
"No hay nada :(", Toast.LENGTH_LONG).show();
}
catch (Exception e){
Log.i("bdAcciones", "Error al abrir o crear la base de datos" + e);
}
if(db3!=null){
db3.close();
}
// object item based on the position
// assign values if the object is not null
if(a != null) {
// get the TextView from the ViewHolder and then set the text (item name) and tag (item ID) values
viewHolder.codigo.setText(String.valueOf(a.getId()));
viewHolder.codigo.setTag(a.getId());
viewHolder.accion.setText(LaAccion.getNombre());
viewHolder.evento.setText(ElEvento.getNombre());
viewHolder.UnSwitch.setChecked(a.getActiva());
Log.e("Position+1: "+ String.valueOf(position+1), "Id: "+ String.valueOf(a.getId()));
}
viewHolder.isChecked1 = viewHolder.UnSwitch.isChecked();
map.put(position, viewHolder.isChecked1);
viewHolder.UnSwitch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e("OnClick", "Se clickeó");
listaActions.get(position).setActiva(map.get(position));
Log.e("Listener del switch", "Modificó la action en la lista de la ActividadPrincipal");
int isActiva;
if(map.get(position) == true)
{
isActiva = 0;
Log.e("Listener del switch", "isActiva = 1");
map.put(position, false);
} else
{
isActiva = 1;
Log.e("Listener del switch", "isActiva = 0");
map.put(position, true);
}
String query = "UPDATE Actions SET Activa = " + String.valueOf(isActiva) + " WHERE Id = " + String.valueOf(position+1);
Log.e("Consulta:", query);
Log.e("Listener del switch", "query creado");
Log.e("La position debería ser", String.valueOf(position+1));
Log.e("Y el valor del map.get(position) es", String.valueOf(map.get(position)));
ActionsSQLite helper1 = new ActionsSQLite(context, "Actions", null, 1);
Log.e("Listener del switch", "Creo el helper");
SQLiteDatabase db = helper1.getWritableDatabase();
Log.e("Listener del switch", "obtenida la base escribible");
db.execSQL(query);
Log.e("Listener del switch", "Query ejecutado");
}
});
} else
{
convertView = null;
}
return convertView;
}
}
一旦您告诉 ArrayAdapter 您有(例如)9 个项目,那么您的 getView 函数需要能够为所有 9 个项目创建视图。如果您实际上不希望这些项目之一显示在适配器中,则需要将其从适配器中删除,这样 Android 就不会调用 getView 来显示该项目。
有几种方法可以解决这个问题。最简单的方法是像您目前正在做的那样构造您的适配器,然后为您不想包含的操作调用 remove(action)。
另一种选择是覆盖 BaseAdapter 而不是 ArrayAdapter。然后你可以有更复杂的代码来动态地计算出你想要显示多少项目。 BaseAdapter 更灵活,但实现起来仍然很简单。
有道理吗?