studio programacion para herramientas fundamentos desarrollo con avanzado aplicaciones android android-layout android-listview onclick android-listfragment

programacion - manual android studio avanzado



¿Cómo adjuntar múltiples acciones táctiles a un solo elemento de la lista? (1)

No ha publicado ningún código relacionado con el adaptador en sí, pero encontré su pregunta anterior y está casi todo el camino hasta allí.

La respuesta rápida y sucia

En bindView() , modifiquemos su cuenta_compartida TextView para guardar el índice de la fila actual en la etiqueta (para su itemUri ) y agreguemos un OnClickListener simple:

public void bindView(View view, Context context, Cursor cursor) { ViewHolder holder = (ViewHolder)view.getTag(); if (holder == null) { ... holder.comments_count.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // Get the position from the ViewHolder long id = (Long) v.getTag(); Toast.makeText(v.getContext(), "Comment Click: " + id, Toast.LENGTH_SHORT).show(); } }); } ... holder.comments_count.setTag(cursor.getLong(0)); }

Cuando el usuario haga clic en la fila, seguirá llamando a onListItemClick() , excepto si hace clic en el cuadro de comentarios. El recuadro de comentarios dispara OnClickListener arriba donde puede dirigir al usuario a su CommentActivity. No mencionaste dónde itemUri los diferentes valores para itemUri pero asumí que necesitas la identificación de la fila para obtenerlo.

Respuesta superior

En su pregunta anterior, noté que está haciendo algunas llamadas repetitivas y que el diseño de Thiago Moreira Rocha era extremadamente complejo para ser utilizado repetidamente (para cada fila de ListView). Por lo tanto, propongo un enfoque diferente. He dividido mi respuesta en partes relacionadas con el adaptador, el diseño de filas y los colores para comments_count :

El adaptador
Publicaré el código completo y luego explicaré en la parte inferior:

public class CustomCursorAdapter extends CursorAdapter { private LayoutInflater mInflater; private int[] mFrom; private OnClickListener commentClick = new OnClickListener() { @Override public void onClick(View v) { // Get the position saved in bindView() long id = (Long) v.getTag(); Toast.makeText(v.getContext(), "Comment Click: " + id, Toast.LENGTH_SHORT).show(); } }; public CustomCursorAdapter(Context context, Cursor cursor, int flags) { super(context, cursor, flags); mInflater = LayoutInflater.from(context); } private void applyColorFilter(Drawable drawable, int count) { drawable.clearColorFilter(); if (count > 0) { float saturation = (count * 15) / 100f; // The value gets pinned if out of range. int color = Color.HSVToColor(new float[] {110f, saturation, 1f}); drawable.setColorFilter(color, Mode.SRC); } } @Override public void bindView(View view, Context context, Cursor cursor) { ViewHolder holder = (ViewHolder) view.getTag(); holder.title.setText(cursor.getString(mFrom[0])); holder.description.setText(cursor.getString(mFrom[1])); // Get comments_count and set it as text int count = cursor.getInt(mFrom[2]); holder.comments_count.setText(count + ""); holder.comments_count.setTag(cursor.getLong(0)); // Adjust the color by saturation applyColorFilter(holder.comments_color, count); // Alternate method, that I explain in the answer // Note: set the solid color in color.xml to #2aff00 //holder.comments_color.setAlpha(count * 45); } @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { View view = mInflater.inflate(R.layout.list_item, parent, false); ViewHolder holder = new ViewHolder(); holder.title = (TextView)view.findViewById(R.id.title); holder.description = (TextView)view.findViewById(R.id.description); holder.comments_count = (TextView)view.findViewById(R.id.comments_count); holder.comments_count.setOnClickListener(commentClick); holder.comments_color = ((LayerDrawable) holder.comments_count.getBackground()).findDrawableByLayerId(R.id.color); view.setTag(holder); return view; } @Override public Cursor swapCursor(Cursor newCursor) { if(mFrom == null && newCursor != null) { mFrom = new int[] {newCursor.getColumnIndex(TITLE), newCursor.getColumnIndex(DESCRIPTION), newCursor.getColumnIndex(COMMENTS_COUNT)}; } return super.swapCursor(newCursor); } private class ViewHolder { TextView title; TextView description; TextView comments_count; Drawable comments_color; } }

Hice algunos cambios:

  • mFrom contiene los índices de las columnas que está utilizando. Solo necesita obtener el índice de la columna una vez , no cambiará a menos que cambie el Cursor
  • commentsClick es un OnClickListener genérico que utilizo para cada fila y lo configuro al crear un ViewHolder
  • Traje tu método para cambiar el color HSV en el adaptador y lo llamé applyColorFilter()
  • Me mudé creando ViewHolder en newView() lugar de buscar null en bindView()

El diseño de filas
Probablemente hayas notado que cambio el color de los comentarios de forma un poco diferente, es porque utilizo un diseño de fila más simple:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="10dp" > <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_toLeftOf="@+id/comments_count" android:textAppearance="?android:attr/textAppearanceLarge" /> <TextView android:id="@+id/description" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/title" android:layout_toLeftOf="@+id/comments_count" android:textAppearance="?android:attr/textAppearanceSmall" /> <TextView android:id="@+id/comments_count" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight="15dp" android:background="@drawable/comments_layers" android:textAppearance="?android:attr/textAppearanceLarge" /> </RelativeLayout>

(Aunque el diseño de Thiago Moreira Rocha funciona, los ViewGroups anidados parecen exagerados. Cada vez que tienes un ViewGroup con un solo hijo, generalmente es una alternativa).

Utilizo un LayerDrawable para reemplazar los dos LinearLayouts, que explicaré en los pasos. Primero, el borde ( border.xml ), muy similar al anterior:

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <corners android:radius="10dp" /> <padding android:bottom="2dp" android:left="2dp" android:right="2dp" android:top="2dp" /> <solid android:color="#ffffff" /> <stroke android:width="2dp" android:color="#000000" /> </shape>

(Tenga en cuenta que el relleno es el ancho del trazo).

En segundo lugar, el color de fondo ajustable ( color.xml ):

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <corners android:radius="10dp" /> <padding android:bottom="10dp" android:left="10dp" android:right="10dp" android:top="10dp" /> <solid android:color="#ffffff" /> </shape>

Por último, creé un LayerDrawable para combinar las dos imágenes ( comments_layers.xml ):

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/border" android:drawable="@drawable/border" /> <item android:id="@+id/color" android:drawable="@drawable/color" /> </layer-list>

(Opcional)
Ajusta la saturación de su valor de HSV en applyColorFilter() , pero parece que esto equivale a ajustar el alfa de un fondo verde. Si esto es cierto, el cambio del valor alfa es una tarea mucho más simple. Encuentra mis comentarios en bindView() :

  1. Comente applyColorFilter(holder.comments_color, count);
  2. holder.comments_color.setAlpha(count * 45); comentario holder.comments_color.setAlpha(count * 45);
  3. Abra mi archivo color.xml y cambie el atributo de color del elemento solid de #ffffff a #2aff00

En verdad, nunca antes había usado LayerDrawables así, puede haber una manera más rápida, pero creo que esto es bastante astuto.

Estoy usando el siguiente diseño de lista para los elementos que tienen comentarios asociados. La cantidad de comentarios se indica con el cuadro del lado derecho.

Actualmente, estoy usando el controlador onListItemClick para iniciar otra vista de detalles .

public class CustomListFragment extends ListFragment implements LoaderCallbacks<Cursor> { private Activity mActivity; private CursorAdapter mAdapter; private QueryParameters mQueryParameters; @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); setEmptyText("No data to display"); mActivity = getActivity(); if (mActivity == null) { Log.e(getClass().getName(), "Activity is null"); return; } // Prepare query. mQueryParameters = QueryHelper.getQueryParameters(mActivity); if (mQueryParameters == null || !mQueryParameters.isPreparedForLoader()) { Log.d(getClass().getName(), "One or more query parameters are null."); return; } mAdapter = new CustomCursorAdapter(mActivity, null, 0); setListAdapter(mAdapter); getLoaderManager().initLoader(0, null, this); } @Override public Loader<Cursor> onCreateLoader(int id, Bundle extras) { return new CursorLoader(mActivity, mQueryParameters.uri, mQueryParameters.fromColumnsLoader, mQueryParameters.selection, mQueryParameters.selectionArgs, mQueryParameters.sortOrder); } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { mAdapter.swapCursor(cursor); } @Override public void onLoaderReset(Loader<Cursor> loader) { mAdapter.swapCursor(null); } @Override public void onListItemClick(ListView l, View v, int position, long id) { Intent intent = new Intent(mActivity, ItemDetailsActivity.class); intent.putExtra("ITEM_URI", mItemUri); mActivity.startActivity(intent); } }

Me gustaría implementar que el usuario pueda tocar el elemento de cuadro a la derecha. Esta acción debería comenzar entonces la actividad de CommentsActivity asociada. Sin embargo, cuando el usuario toca el lado izquierdo, aún debe iniciar la actividad ItemDetailsActivity .
En ambos casos, debo pasar el itemUri con la intención de itemUri la vista de detalles o la lista de comentarios para el artículo en particular.
ListFragment utiliza un CursorAdapter para vincular los TextView a las propiedades de un elemento .

Pregunta:

  • ¿Cómo puedo adjuntar una segunda acción táctil a un solo elemento de la lista?