Cómo limitar la altura de la vista desplegable de Spinner en Android

Por favor sugiera cualquier enfoque que use para crearlo.

Pregunta : Estoy creando la vista 2-Spinner, donde tengo que agregar la lista de País / Ciudades, así que si estoy seleccionando India entonces obtengo 50 elementos dentro de la vista desplegable, el problema con esto es que está tomando toda la página En Altura .

Lo que quiero : quiero crear una vista desplegable, donde el usuario puede ver solo 10 elementos en la vista desplegable, otros elementos se mostrarán cada vez que el usuario recorra la vista desplegable.


Mi problema

Puedes usar Reflection.

Spinner spinner = (Spinner) findViewById(R.id.spinner); try { Field popup = Spinner.class.getDeclaredField("mPopup"); popup.setAccessible(true); // Get private mPopup member variable and try cast to ListPopupWindow android.widget.ListPopupWindow popupWindow = (android.widget.ListPopupWindow) popup.get(spinner); // Set popupWindow height to 500px popupWindow.setHeight(500); } catch (NoClassDefFoundError | ClassCastException | NoSuchFieldException | IllegalAccessException e) { // silently fail... } 

También puede afectar la ubicación y el tamaño de la vista desplegable al getWindowVisibleDisplayFrame(Rect outRect) subclase de Spinner y reemplazar su getWindowVisibleDisplayFrame(Rect outRect) que android.widget.PopupWindow usa para los cálculos. Simplemente configure outRect para limitar el área donde se puede mostrar la vista desplegable.

Este enfoque, por supuesto, no es adecuado para todos los escenarios, ya que a veces desea colocar la vista desplegable para que no oculte otra vista o por alguna otra condición conocida solo “fuera de la instancia”.

En mi caso, tuve que aplicar el indicador FLAG_LAYOUT_NO_LIMITS a mi ventana de actividad, lo que provocó que el outRect fuera enorme y, por lo tanto, parte de la vista desplegable a veces se ocultaba detrás de la barra de navegación. Para restaurar el comportamiento original utilicé la siguiente anulación:

 @Override public void getWindowVisibleDisplayFrame(Rect outRect) { WindowManager wm = (WindowManager) getContext.getSystemService(Context.WINDOW_SERVICE); Display d = wm.getDefaultDisplay(); d.getRectSize(outRect); outRect.set(outRect.left, , outRect.right, outRect.bottom); } 

para eso he creado mi propio PopUpWindow como lo sugiere @theLittleNaruto, en la sección de comentarios.

main.xml

 < ?xml version="1.0" encoding="utf-8"?>    

popup_example.xml

 < ?xml version="1.0" encoding="utf-8"?>    

showpopup_1.java

 package com.example.spinnerworking; import android.app.Activity; import android.content.Context; import android.graphics.Color; import android.os.Bundle; import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.ImageButton; import android.widget.ListView; import android.widget.PopupWindow; import android.widget.TextView; import android.widget.PopupWindow.OnDismissListener; import android.widget.Toast; public class showpopup_1 extends Activity { boolean click = true ; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.main); final LayoutInflater inflater = (LayoutInflater) this .getSystemService(Context.LAYOUT_INFLATER_SERVICE); final Button b = (Button) findViewById(R.id.btn); final View pview = inflater.inflate(R.layout.popup_example, (ViewGroup) findViewById(R.layout.main)); final PopupWindow pw = new PopupWindow(pview); Log.i("hello", "hello") ; b.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { if (click) { // if onclick written here, it gives null pointer exception. // if onclick is written here it gives runtime exception. pw.showAtLocation(v, Gravity.CENTER_HORIZONTAL, 0, 0); pw.update(8, 0, 150, 200); String[] array = new String[] { "tushar", "pandey", "almora" }; ListView lst = (ListView) pview.findViewById(R.id.lstview); adapterHello adapter = new adapterHello(showpopup_1.this); lst.setAdapter(adapter); lst.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView< ?> arg0, View arg1, int arg2, long arg3) { Toast.makeText(showpopup_1.this, "pandey", Toast.LENGTH_SHORT).show(); } }); click = false ; } else { pw.dismiss(); click = true; } } }); } } class adapterHello extends BaseAdapter { String array[] = new String[] { "tushar", "pandey", "almora", "hello", "tushar", "pandey", "almora", "hello", "tushar", "pandey", "almora", "hello" }; showpopup_1 context; public adapterHello(showpopup_1 context) { this.context = context; } public int getCount() { // TODO Auto-generated method stub return array.length; } @Override public Object getItem(int arg0) { // TODO Auto-generated method stub return arg0; } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub TextView text = new TextView(context); text.setHeight(30); text.setPadding(10, 8, 0, 0); text.setTextColor(Color.BLACK); text.setText(array[position]); text.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Log.i("clicked", "tushar"); } }); return text; } } 
  1. agrega android:popupBackground="#00000000" al Spinner
  2. en el adaptador

 getDropDownView(); parentParams = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, (int) Utils.convertDpToPx(350)); parentParams.gravity = Gravity.BOTTOM; parent.setLayoutParams(parentParams); 
  1. puede mover la ventana emergente agregando android:dropDownVerticalOffset="60dp"