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 unViewHolder
- Traje tu método para cambiar el color HSV en el adaptador y lo llamé
applyColorFilter()
- Me mudé creando
ViewHolder
ennewView()
lugar de buscarnull
enbindView()
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()
:
- Comente
applyColorFilter(holder.comments_color, count);
-
holder.comments_color.setAlpha(count * 45);
comentarioholder.comments_color.setAlpha(count * 45);
- Abra mi archivo
color.xml
y cambie el atributo decolor
del elementosolid
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?