PDA

Ver la Versión Completa : [ SOLUCIONADO ] Hacer clickables elementos de un ListView y abrir Activity


Godlike
31/10/15, 18:08:38
Buenas a todos,

la última parte de mi aplicación consiste en crear un ListView que se nutre de una base de datos SQLite y todo se une mediante un SimpleCustomAdapter.

La idea es que me rellena el layout con tantas líneas como elementos hay en la base de datos, y muestra diversa información. Pero ahora necesito modificarlo para que al clickar sobre una de las líneas se abra una nueva actividad y muestre más detalles de ese caso. Es algo que veo realmente común pero no logro hacerlo funcionar, en teoría con lo que tengo pensaba que debería hacerlo.

Por un lado el Layout contenedor:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:descendantFocusability="blocksDescendants"
android:textIsSelectable="false"
android:focusable="false"
android:clickable="false" >

<ListView
android:id="@+id/listDBitems"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

</LinearLayout> Por otro lado tengo un Layout que es el que forma una línea, y se repetirá para cada elemento. Es más o menos largo así que copio un fragmento:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:descendantFocusability="blocksDescendants"
android:textIsSelectable="false" >

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="com.Activities.ParteTecnico"
android:orientation="vertical"
android:descendantFocusability="blocksDescendants" >

<TextView
android:id="@+id/selectedItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingLeft="10dp"
android:paddingTop="20dp"
android:text="Item seleccionado"
android:textSize="25dp" />

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_marginTop="10dp"
android:orientation="horizontal" >

<TextView
android:id="@+id/itemId"
android:layout_width="20dp"
android:layout_height="wrap_content"
android:text="Info 1 item seleccionado"
android:textSize="20dp"/>

[...]
Y ya por último tengo la Activity que utiliza los layouts en la función PopulateListView():

public class ListDB extends Activity {

MySQLiteHelper db = new MySQLiteHelper(this);

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_db);

populateListView();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_list_db, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();

//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}

return super.onOptionsItemSelected(item);
}

public void populateListView () {
final Cursor cursor = db.getAllRowsPartes();
final String[] fromFieldNames = new String[]{MySQLiteHelper.KEY_PARTES_ID, MySQLiteHelper.KEY_PARTES_ID_CLIENTE, MySQLiteHelper.KEY_PARTES_HORA_INICIO, MySQLiteHelper.KEY_PARTES_HORA_FIN, MySQLiteHelper.KEY_PARTES_TECNICO, MySQLiteHelper.KEY_PARTES_NOTA_PUBLICA, MySQLiteHelper.KEY_PARTES_NOTA_INTERNA, MySQLiteHelper.KEY_PARTES_PERSONA_CONTACTO, MySQLiteHelper.KEY_PARTES_DNI, MySQLiteHelper.KEY_PARTES_EMAIL, MySQLiteHelper.KEY_PARTES_FECHA};
final int[] toViewIDs = new int[]{R.id.itemId, R.id.itemIdCliente, R.id.itemHinicio, R.id.itemHfin, R.id.itemTecnico, R.id.itemNpublica, R.id.itemNinterna, R.id.itemPcontacto, R.id.itemDni, R.id.itemEmail, R.id.selectedItem};
final SimpleCursorAdapter myCursorAdapter;
myCursorAdapter = new SimpleCursorAdapter(getBaseContext(), R.layout.activity_list_db_each, cursor, fromFieldNames, toViewIDs, 0);
final ListView myList = (ListView) findViewById(R.id.listDBitems);

myList.setAdapter(myCursorAdapter);

myList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//ItemClicked item = parent.getItemAtPosition(position);

Cursor itemCursor = (Cursor) myCursorAdapter.getItem(position);
String email = itemCursor.getString(cursor.getColumnIndex(MySQLit eHelper.KEY_PARTES_EMAIL));

Intent intent = new Intent(getApplicationContext(), EditParte.class);
intent.putExtra("email", email);
startActivity(intent);
}
});
}
}Por curiosidad este es EditParte:

public class EditParte extends ActionBarActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_parte);

//Recupero datos del Intent
Bundle bundle = getIntent().getExtras();
//String datos = bundle.getString("id");
String datos = bundle.getString("email");

TextView EPid = (TextView) findViewById (R.id.EPid);

EPid.setText(datos);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_edit_parte, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();

//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}

return super.onOptionsItemSelected(item);
}
}Aunque el comportamiento es que aparecen líneas pero no son clickables. Ni crashea ni nada, simplemente no se entera de que estoy pulsando esa línea...

¿Alguna idea de qué estoy haciendo mal?.

Mil gracias de antemano, cualquier ayuda se agradece :)

kriogeN
31/10/15, 22:45:28
Odio el setOnItemClickListener, prefiero 1000 veces establecer el onClick a la View principal cuando hago el Bind. Pero claro, eso sólo lo puedes hacer si implementas tu propio getView.

Lo principal, para que funcione el setOnItemClickListener debes hacer click en un elemento que no tenga evento Touch consumible, en este caso el contenedor principal es un ScrollView, con lo cual lo primero que tienes que hacer es quitarle el evento al ScrollView haciendo que no sea Focusable ni FocusableInTouchMode, y con eso el ScrollView dejaría de funcionar y ya lo puedes quitar.

Empieza por ahí, poniendo focusable y focusableintouchmode false a todos los elementos de la línea.

Expectro
02/11/15, 18:53:57
Es realmente necesario utilizar el ScrollView como la base de la fila??
Yo creo que si la conviertes a LinearLayout o RelativeLayout te funcionará tal como esta.

kriogeN
02/11/15, 19:53:33
Es realmente necesario utilizar el ScrollView como la base de la fila??
Yo creo que si la conviertes a LinearLayout o RelativeLayout te funcionará tal como esta.

Si, es lo que quería decir yo cuando he dicho que como tienes que hacer que el ScrollView no sea focusable en ninguno de los 2 casos ya es lo mismo que si no lo pones.

Godlike
02/11/15, 21:31:41
No me lo puedo creer... en serio, estuve varios días a ratos mirando esto y ahora borro el ScrollView y funciona a la primera!!!

He puesto el ScrollView en la vista que contiene cada vista de línea, no sé por qué lo puse ahí francamente.

Mil gracias!!!