studio programacion móviles llenar elementos dinamico desarrollo curso aplicaciones agregar android listview text android-listview zoom

programacion - Ampliando el elemento medio en una vista de lista-¿Android?



manual de programacion android pdf (2)

Estoy tratando de ampliar el elemento de vista de lista más central. (Eventualmente, espero expandir esto en una especie de efecto 3D simple y ligero que los elementos aparecerán para acercar cuando están en el medio de la pantalla y alejar cuando están abajo, Total de fondo negro y elementos de texto acercándose y alejándose ...)

Por lo tanto, hice una vista de lista ficticia. Cada fila es un elemento textview. A continuación, tengo un adaptador personalizado.

La única modificación relevante que he hecho es:

En OnCreate() , paso la siguiente variable al adaptador:

int v = (listview.getLastVisiblePosition() - listview.getFirstVisiblePosition()) + 1;

Y en getView () del adaptador, tengo esto:

if (position == x/2) { textView.setHeight(100); }

De todos modos aquí está todo el código, me he saltado las importaciones: (¡No es tan grande! ... la mayoría es bastante general)

MainActivity.java:

public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final ListView listview = (ListView) findViewById(R.id.listview); String[] values = new String[] { "Android", "iPhone", "WindowsMobile", "Blackberry", "WebOS", "Ubuntu", "Windows7","iPhone", "WindowsMobile", "Blackberry", "WebOS", "Ubuntu", "Windows7","iPhone", "WindowsMobile", "Blackberry", "WebOS", "Ubuntu", "Windows7", "Max OS X" }; final ArrayList<String> list = new ArrayList<String>(); for (int i = 0; i < values.length; ++i) { list.add(values[i]); } int v = (listview.getLastVisiblePosition() - listview.getFirstVisiblePosition()) + 1; final MySimpleArrayAdapter adapter = new MySimpleArrayAdapter(this, v, R.layout.row, list); listview.setAdapter(adapter); listview.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, final View view, int position, long id) { } }); } }

MySimpleArrayAdapter.java

public class MySimpleArrayAdapter extends ArrayAdapter<String> { private final Context context; private final int x; HashMap<String, Integer> mIdMap = new HashMap<String, Integer>(); public MySimpleArrayAdapter(Context context, int a, int textViewResourceId, List<String> objects) { super(context, textViewResourceId, objects); this.context = context; this.x = a; for (int i = 0; i < objects.size(); ++i) { mIdMap.put(objects.get(i), i); } } @Override public View getView(int position, View convertView, ViewGroup parent) { LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); View rowView = inflater.inflate(R.layout.row, parent, false); TextView textView = (TextView) rowView.findViewById(R.id.textView1); if (position == x/2) { textView.setHeight(100); } return rowView; } @Override public long getItemId(int position) { String item = getItem(position); return mIdMap.get(item); } @Override public boolean hasStableIds() { return true; } }

Además, en mi activity_main.xml solo tengo una vista de lista única, y en "row.xml" tengo una sola vista de texto ...

Problemas: ¿Por qué no aparece el texto? Claramente agregué los valores de la lista a la vista de texto.

¿Por qué el elemento más grande es grande y no el medio, específicamente lo coloqué en el del medio?

Aquí está la pantalla que da mi código actual:

Error LOGCAT - Solución de KMDev

10-06 17:54:02.529: E/AndroidRuntime(19596): FATAL EXCEPTION: main 10-06 17:54:02.529: E/AndroidRuntime(19596): java.lang.RuntimeException: Unable to start activity ComponentInfo{mple.finala/mple.finala.MainActivity}: java.lang.NullPointerException 10-06 17:54:02.529: E/AndroidRuntime(19596): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2077) 10-06 17:54:02.529: E/AndroidRuntime(19596): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2104) 10-06 17:54:02.529: E/AndroidRuntime(19596): at android.app.ActivityThread.access$600(ActivityThread.java:134) 10-06 17:54:02.529: E/AndroidRuntime(19596): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1247) 10-06 17:54:02.529: E/AndroidRuntime(19596): at android.os.Handler.dispatchMessage(Handler.java:99) 10-06 17:54:02.529: E/AndroidRuntime(19596): at android.os.Looper.loop(Looper.java:154) 10-06 17:54:02.529: E/AndroidRuntime(19596): at android.app.ActivityThread.main(ActivityThread.java:4624) 10-06 17:54:02.529: E/AndroidRuntime(19596): at java.lang.reflect.Method.invokeNative(Native Method) 10-06 17:54:02.529: E/AndroidRuntime(19596): at java.lang.reflect.Method.invoke(Method.java:511) 10-06 17:54:02.529: E/AndroidRuntime(19596): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:809) 10-06 17:54:02.529: E/AndroidRuntime(19596): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:576) 10-06 17:54:02.529: E/AndroidRuntime(19596): at dalvik.system.NativeStart.main(Native Method) 10-06 17:54:02.529: E/AndroidRuntime(19596): Caused by: java.lang.NullPointerException 10-06 17:54:02.529: E/AndroidRuntime(19596): at mple.finala.MainActivity$2.onScroll(MainActivity.java:79) 10-06 17:54:02.529: E/AndroidRuntime(19596): at android.widget.AbsListView.invokeOnItemScrollListener(AbsListView.java:1297) 10-06 17:54:02.529: E/AndroidRuntime(19596): at android.widget.AbsListView.setOnScrollListener(AbsListView.java:1286) 10-06 17:54:02.529: E/AndroidRuntime(19596): at mple.finala.MainActivity.onCreate(MainActivity.java:58) 10-06 17:54:02.529: E/AndroidRuntime(19596): at android.app.Activity.performCreate(Activity.java:4479) 10-06 17:54:02.529: E/AndroidRuntime(19596): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1050) 10-06 17:54:02.529: E/AndroidRuntime(19596): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2041) 10-06 17:54:02.529: E/AndroidRuntime(19596): ... 11 more

EDICION 2:

Código completo , todavía dando una excepción nula.

http://codeviewer.org/view/code:373d


Algunas cosas necesitan ser abordadas.

  1. Necesita usar el patrón ViewHolder. Eso y las cosas que realmente necesita saber sobre ListView están en GoogleIO 2010 - El mundo de ListView video.

  2. No es realmente una buena idea ajustar el diseño de un elemento en getView, ya que tendrá un impacto negativo en el reciclador de vistas que utiliza ListView. Eso también está en el video. Realmente lo aliento a que intente y encuentre una forma diferente de mostrar lo que desea mostrar.

Configurando tu texto

  1. Está transfiriendo la dimensión x que desea para un elemento al constructor de su Adaptador en lugar de proporcionarle una identificación de recurso de elemento real. ArrayAdapter configurará su texto por usted si pasa los argumentos correctos. Para un ejemplo simple que utiliza un recurso de cadena y los diseños predeterminados de elementos de lista proporcionados:

    String[] mData = getResources().getStringArray(R.array.list_examples); ArrayAdapter<String> mBaseAdapter = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, android.R.id.text1, mListData);

  2. Si yo fuera tú, simplemente dejaría que el adaptador establezca el texto y capte el diseño de ese elemento llamando a super así:

    @Override public View getView(int position, View convertView, ViewGroup viewGroup){ convertView = super.getView(position,convertView, viewGroup); //other code here }

Si realmente quieres hacerlo tú mismo, aquí está con el patrón ViewHolder

//This is the ViewHolder static class Holder{ TextView mText; } @Override public View getView(int position, View convertView, ViewGroup viewGroup){ convertView = super.getView(position, convertView, viewGroup); if (convertView == null){ // If you reach this, it most likely means you''re not supplying the // adapter the layout and textview resource it needs. You can // just comment out your getView override and see if your text gets // displayed. } Holder mHolder; if(convertView.getTag() == null){ mHolder = new Holder(); mHolder.mText = (TextView)convertView.findViewById(android.R.id.text1); convertView.setTag(mHolder); } else { mHolder = (Holder) convertView.getTag(); } mHolder.mText.setText(getItem(position).toString()); }

Acerca de los métodos getXVisibleItem

// These are both implemented in AdapterView which means // they''re flat list positions int firstVis = mList.getFirstVisiblePosition(); int lastVis = mList.getLastVisiblePosition(); /* This is the "conversion" from flat list positions to ViewGroup child positions */ int count = lastVis - firstVis; /* getChildAt(pos) is implemented in ViewGroup and has a different meaning for * its position values. ViewGroup tracks visible items as children and is 0 indexed. * This means you''ll have 0 - X positions where X is however many items it takes * to fill the visible area of your screen; usually less than 10. */ View listItem = mList.getChildAt(count - ((int)count/2)); // This will get the middle // item for you to adjust as // you want.

Para encontrar el artículo en el medio de la pantalla, solo necesita tomar su conteo de elementos visibles y restar la mitad de ese conteo como se comentó anteriormente.

Establecer la implementación de altura

Deberá establecer un AbsListView.OnScrollListener en su ListView y cuando el scroll se detenga, aplique sus ajustes al elemento del medio. Ex:

mList.setOnScrollListener(new OnScrollListener(){ @Override public void onScrollStateChanged(AbsListView view, int scrollState){ } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount){ //Note that this is called when the scroll completes. //It gives us the positions we want so just calculate //the middle item, grab it and adjust the height directly //or by increasing margins if the item layout_height is //wrap_content. I''m not positive the margins do what you // need, but setting the height directly should. LinearLayout listItem = mList // <-- Replace LinearLayout with your layout .getChildAt(visibleItemCount - ((int)visibleItemCount/2)); //Make sure you use the right LayoutParams for the listItem Layout //If your listItem is a RelativeLayout for instance, you would use: // listItem.setLayoutParams( // new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, // theHeightYouWantHere)); listItem.setLayoutParams( new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, theHeightYouWantHere)); } });

He hecho algunas publicaciones de blog relacionadas de manera tangencial sobre ListView y ExpandableListView que tienen ejemplos de código completo sobre cómo actualizar elementos visibles (el código de ejemplo simplemente cambia el color del texto / fondo del elemento) que usa la estrategia childAt. Perdonen el enlace del blog personal y el estilo del mismo (es nuevo y necesita más trabajo :), pero el código funciona bien.

Editar 2: para android.R.simple_list_item_1

Esto hace exactamente lo que desea, siempre y cuando esté usando un TextView para el diseño del elemento (android.R.simple_list_item_1 es un TextView). Si decide utilizar un diseño de ViewGroup, deberá reemplazar item.setHeight con el método LayoutParams.

mList.setOnScrollListener(new OnScrollListener(){ @Override public void onScrollStateChanged(final AbsListView view, final int scrollState){ } @Override public void onScroll(final AbsListView view, final int firstVisibleItem, final int visibleItemCount, final int totalItemCount){ if (visibleItemCount != 0){ Log.i( TAG, "firstVisibleItem: " + firstVisibleItem + "/nvisibleItemCount: " + visibleItemCount); final int midPosition = visibleItemCount - (visibleItemCount / 2); final TextView listItem = (TextView) mList.getChildAt(midPosition); listItem.setHeight(500); //Only works if you''re using //android.R.simple_list_item_1 since it''s //not a ViewGroup, but rather a TextView int count = visibleItemCount; while (count >= 0){ // Here we need to loop through and make sure // all recycled items are returned to their // original height. final TextView item = (TextView) mList.getChildAt(count); if (item != null && count != midPosition){ item.setHeight(100); } count--; } } } });


1. ° no aparece el texto

En su MySimpleArrayAdapter, método getView. Olvidaste setText para tu textView. Es por eso que no se muestra texto.

2.º haz que el artículo medio sea más grande

Intenta obtener LastPisiblePosition antes de configurar su adaptador de vista de lista. Supongo que el valor de v debe ser 0 y la posición == 0. Hay una razón por la cual el artículo topper se vuelve más grande. Si intenta cambiarlo a la posición == 1 o 2, tal vez el segundo o tercer elemento se agrandará.

Para hacer que el artículo medio se vuelva más grande, setOnScrollLinstener para listview

public int currentLargedPosition = 0 // global value listView.setOnScrollListener(new OnScrollListener(){ @Override public void onScroll(AbsListView arg0, int firstVisibleItem, int visibleItemCount, int totalItemCount){ Log.i("Scroll","first "+firstVisibleItem+", visibleItemCount "+visibleItemCount+",totalCount "+totalItemCount); int center = (visibleItemCount)/2 + firstVisibleItem; if(currentLargedPosition != center){ enlargeMiddleView(currentLargedPosition-firstVisibleItem, center-firstVisibleItem); currentLargedPosition = center; } } @Override public void onScrollStateChanged(AbsListView arg0, int arg1) { Log.i("scroll","onScrollStateChanged"); } }); void enlargeMiddleView(int oldPosition, int newPosition){ // get enlarged view and make it return default size TextView newTextView = (TextView)listView.getChildAt(oldPosition).findViewById(R.id.text); newTextView.setHeight(50); // get the current center view and make it bigger TextView oldTextView = (TextView)listView.getChildAt(newPosition).findViewById(R.id.text); oldTextView.setHeight(300); }