android - studio - ListView addHeaderView hace que la posición aumente en uno?
llenar un listview android (11)
Acabo de encontrar este problema y la mejor manera parece usar ListView.getItemAtPosition(position)
lugar de ListAdapter.getItem(position)
como las cuentas de la versión de ListView
para los encabezados, es decir: -
Haz esto en su lugar:
myListView.getItemAtPosition(position)
A continuación se muestra un fragmento de código con un ListView. Agregué un EmptyView y un headerView. Agregar el headerView hace que la posición en el onItemClick se incremente en uno.
Entonces, sin el headerView, el primer elemento de la lista tendría la posición 0, con el headerView la posición del primer elemento de la lista sería 1.
Esto causa errores en mi adaptador, por ejemplo, al llamar a getItem () y al usar algunos otros métodos, consulte a continuación. Algo extraño: en el método getView () del adaptador, el primer elemento de la lista se solicita con la posición 0 incluso si se agrega el headerView.
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ListView list = (ListView) viewSwitcher.findViewById(R.id.list);
View emptyView = viewSwitcher.findViewById(R.id.empty);
list.setEmptyView(emptyView);
View sectionHeading = inflater.inflate(R.layout.heading, list, false);
TextView sectionHeadingTextView = (TextView) sectionHeading.findViewById(R.id.headingText);
sectionHeadingTextView.setText(headerText);
list.addHeaderView(sectionHeading);
list.setAdapter(listAdapter);
list.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
listAdapter.getItem(position);
//Do something with it
}
});
}
Algunos métodos de adaptador:
@Override
public int getViewTypeCount() {
return TYPE_COUNT;
}
@Override
public int getItemViewType(int position) {
return (position < items.size()) ? ITEM_NORMAL : ITEM_ADVANCED;
}
@Override
public Product getItem(int position) {
return items.get(position);
}
@Override
public boolean areAllItemsEnabled() {
return false;
}
@Override
public boolean isEnabled(int position) {
return (position < items.size());
}
¿Es este el comportamiento normal al agregar un headerView? ¿Y cómo superar los problemas en mi adaptador?
Al implementar AdapterView.OnItemClickListener
, solo restamos los encabezados de la posición.
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
position -= mListView.getHeaderViewsCount();
// what ever else follows...
}
Esto podría ayudar a alguien, mejorando la respuesta de Farid_z y Philipp, podemos aplicar correctamente setItemChecked y setTitle con algo como esto
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
position += 1;
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
position -= 1;
setTitle(mNavigationDrawerItemTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
Hola, podemos resolver esto de esta manera primero creas tu vista de encabezado, luego de insertarla en tu lista y el último paso no puede ser setOnClickListener. funciona para mi cualquier retroalimentación bienvenida
ViewGroup headerView = (ViewGroup) getLayoutInflater().inflate(R.layout.your_header, list,false);
list.addHeaderView(headerView);
headerView.setEnabled(false);
headerView.setOnClickListener(null);
No agregar mucho nuevo que @Ramesh no agregó, sino un contexto adicional:
personList.setOnItemClickListener(new OnItemClickListener() {
@SuppressWarnings("unchecked")
public void onItemClick( AdapterView<?> parent, View view, int position, long duration) {
Map<String, Object> person = (Map<String, Object>) parent.getAdapter().getItem(position);
if (person != null){
// If the header was clicked on a null is returned
OnPersonUiChangeListener listener = (OnPersonUiChangeListener) getActivity();
listener.onSelectedPersonChanged(person);
}
}
});
No es necesario cambiar ningún código. Simplemente use el código a continuación.
list.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
parent.getAdapter().getItem(position);
//Do something with it
}
});
No use su adaptador, use el adaptador ''decorado'' de getAdapter.
Si agrega un encabezado a un ListView
que se convierte en el primer elemento de la lista. Podría compensar esto anulando getCount()
para devolver menos un elemento, pero asegúrese de manejar el getItem()
, getItemId()
y demás, ya que el encabezado sería el elemento en la posición 0.
Si no le importa el clic en el encabezado, reste la cantidad de vistas de encabezado desde la posición para obtener la posición de su adaptador:
listView.addHeaderView(inflater.inflate(
R.layout.my_hdr_layout, null), null, false);
listView.setAdapter(m_adapter);
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
position -= listView.getHeaderViewsCount();
final MyObject object = m_adapter.getItem(position);
}
});
Una solución a esto es mapear la identificación al índice. Básicamente, haga que id devuelva el índice en la lista y lo haga el oyente click:
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
listAdapter.getItem((int) id);
}
Use getSelectedItemPosition () Devuelve la posición del elemento seleccionado actualmente dentro del conjunto de datos del adaptador. Este método no necesita preocuparse por el tamaño de los encabezados o pies de página.