J'essaye de créer ma première application Android, mais je ne peux pas faire ce que je veux. Mon idée est de créer un simple compteur de score. J'ai une activité avec une vue de liste. Chaque élément de la liste a un TextView avec un nom, deux boutons pour ajouter et soustraire et un TextView pour la partition.

Mon idée était de montrer un sélecteur de numéro personnalisé lorsque l'utilisateur clique sur le score, de sélectionner un nombre pour augmenter une diminution. Le sélecteur de numéro personnalisé a une interface pour utiliser la méthode de rappel pour obtenir le numéro sélectionné.

Dans la classe d'activité, j'ai un adaptateur personnalisé pour la vue de liste et une classe de visualiseur pour améliorer la fonctionnalité. J'ai plusieurs doutes / problèmes:

1) Quand puis-je définir les écouteurs pour les boutons / vues de texte? Actuellement, j'ai les écouteurs dans la visionneuse, mais je ne suis pas sûr que ce soit la meilleure solution, peut-être vaut-il mieux les définir dans l'adaptateur, ou même créer un onitemclicklistener pour la liste.

2) Puis-je implémenter la méthode définie dans l'interface de dialogue numberpicker à l'intérieur de l'adaptateur ou de la classe de visualiseur? Je l'ai essayé mais j'obtiens une exception de distribution car la classe interne n'est pas une activité ...

3) Si j'implémente la méthode d'interface dans la classe d'activité (externe), je ne suis pas en mesure de modifier la vue de texte souhaitée qui a appelé le sélecteur de nombres ...

Mes deux principaux problèmes sont où et comment définir l'auditeur pour chaque vue dans les lignes de la vue de liste et comment obtenir le numéro de la boîte de dialogue du sélecteur de nombres et continuer l'exécution ...

Quelqu'un pourrait-il m'aider?

Merci.

0
jgonzal 31 déc. 2015 à 21:04

3 réponses

Meilleure réponse

Pour utiliser un écouteur dans une vue à l'intérieur d'un adaptateur, l'écouteur doit être déclaré dans l'adaptateur et une nouvelle instance d'écouteur doit être créée pour chaque vue.

private static class ViewHolder {
    private CustomListener listener;
    private Button incrementBtn;
}

Maintenant dans la méthode getView():

holder.listener = new CustomListener(position);
holder.incrementBtn.setOnClickListener(holder.listener);

Définissez maintenant une classe héritée pour implémenter la méthode onClick():

private class CustomListener implements View.OnClickListener {
    private int position;

    protected CustomListener(int position) {
        this.position = position;
    }

    @Override
    public void onClick(View v) {
        //increment score here
        notifyDataSetChanged();
    }
}

Une fois la méthode onClick() terminée, la vue avec mise à jour via notifyDataSetChanged() avec le nouveau score. Pour utiliser la boîte de dialogue du sélecteur de nombres, c'est le même modèle avec un DialogInterface.OnClickListener défini dans le visualiseur.

0
Alex Loper 31 déc. 2015 à 18:28

Bien sûr, désolé ...

package com.example.cdp.mispartidas;

imports...

public class Tanteo extends ActionBarActivity {

private String identificador;
private Partida partida;
private Backup backup;
private int indice;
private static Context context;

ListView listviewjugadores;

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

    // Parametros
    listviewjugadores = (ListView) findViewById(R.id.jugadorestanteo);

    Tanteo.context = getApplicationContext();

    Log.i("MILOG", "Obtenemos el backup");
    backup = Backup.getMiBackup(getApplicationContext());

    // Obtenemos el numero de jugadores
    Bundle bundle = getIntent().getExtras();
    identificador = bundle.getString("idpartida");

    Log.i("MILOG", "El identificador de la partida es " + identificador);


    // Buscamos la partida
    indice = backup.getPartida(identificador);
    if (indice >= 0) {
        partida = backup.getBackup().get(indice);
        // Establecemos el adaptador
        Log.i("MILOG", "Establecemos el adaptador");
        AdaptadorTanteo adaptador = new AdaptadorTanteo(this, getTaskId(), partida.getJugadores());
        listviewjugadores.setAdapter(adaptador);
    } else {
        Toast.makeText(this, "No se ha encontrado la partida " + identificador, Toast.LENGTH_SHORT).show();
    }

}

@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_tanteo, 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();

    int numjugadores;

    switch(id){
        // Anadimos un nuevo jugador a la partida
        case R.id.addjugador:
            numjugadores = listviewjugadores.getAdapter().getCount();
            Jugador player = new Jugador();
            // Ponemos un nombre por defecto
            player.setNombre("Jugador" + String.valueOf(numjugadores + 1));
            player.setNumerojugador(numjugadores + 1);
            // Anadimos la puntuacion
            player.setPuntuacion(0);
            // Anadimos el jugador a la lista
            partida.addJugador(player);
            // Actualizamos el backup
            backup.getBackup().set(indice, partida);
            // Almacenamos
            Log.i("MILOG", "Guardamos el backup");
            backup.guardarBackup();
            // Si todo ha ido bien, acutalizamos la lista de jugadores
            ((AdaptadorTanteo) listviewjugadores.getAdapter()).notifyDataSetChanged();
            break;

        case R.id.partidasguardadas:
            // Llamamos al intent de nuestras partidas guardadas
            Intent intenthistorial = new Intent(this, Historial.class);
            startActivity(intenthistorial);
            break;

        case R.id.reiniciarpartida:
            // Ponemos todos los marcadores a 0
            // Recorremos nuestra partida
            numjugadores = partida.getJugadores().size();
            // recorremos y reiniciamos
            for(int i = 0; i < numjugadores; i++){
                partida.getJugadores().get(i).setPuntuacion(0);
            }
            // Actualizamos el backup
            backup.getBackup().set(indice, partida);
            // Almacenamos
            Log.i("MILOG", "Guardamos el backup");
            backup.guardarBackup();
            // Si todo ha ido bien, acutalizamos la lista de jugadores
            ((AdaptadorTanteo) listviewjugadores.getAdapter()).notifyDataSetChanged();
            break;

        case R.id.action_settings:
            break;
        default:
            return true;
    }


    return super.onOptionsItemSelected(item);
}

// Adaptador para el layout del listview
public class AdaptadorTanteo extends ArrayAdapter<Jugador> {

    Activity context;
    List<Jugador> jugadores;
    ViewHolder holder;

    AdaptadorTanteo(Activity context, int textViewResourceId, List<Jugador> listajugadores) {
        super(context, textViewResourceId, listajugadores);
        this.context = context;
        this.jugadores = listajugadores;
    }

    public View getView(final int position, View convertView, ViewGroup parent) {
        View item = convertView;

        // Optimizamos el rendimiento de nuestra lista
        // Si la vista no existe, la creamos
        if (item == null) {
            LayoutInflater inflater = context.getLayoutInflater();
            item = inflater.inflate(R.layout.tanteo_jugador, null);

            // Declaramos el holder pasandole nuestras vistas
            TextView nombre = (TextView) item.findViewById(R.id.nombrejugador);
            TextView puntuacion = (TextView) item.findViewById(R.id.puntos);
            ImageButton mas = (ImageButton) item.findViewById(R.id.sumar);
            ImageButton menos = (ImageButton) item.findViewById(R.id.restar);

            holder = new ViewHolder(nombre, puntuacion, mas, menos);

            // Establecemos el tag
            item.setTag(holder);
        }
        // Si la vista existe, la reusamos
        else {
            holder = (ViewHolder) item.getTag();
        }

        // Guardamos la posicion en el holder para usarlo en los listener
        holder.botonmas.setTag(position);
        holder.botonmenos.setTag(position);
        holder.puntos.setTag(position);

        // Establecemos el nombre por defecto
        holder.nombrejugador.setText(jugadores.get(position).getNombre());
        holder.puntos.setText(String.valueOf(jugadores.get(position).getPuntuacion()));

        return (item);
    }
}


class ViewHolder implements NumeroTanteoDialogFragment.NumberTanteoDialogListener{

    TextView nombrejugador;
    TextView puntos;
    ImageButton botonmas;
    ImageButton botonmenos;
    int position;

    public ViewHolder(TextView nombre, TextView puntuacion, ImageButton mas, ImageButton menos) {

        nombrejugador = nombre;
        puntos = puntuacion;
        botonmas = mas;
        botonmenos = menos;

        // Definimos los listener
        nombrejugador.setOnClickListener(miListenerLocal);
        puntos.setOnClickListener(miListenerLocal);
        botonmas.setOnClickListener(miListenerLocal);
        botonmenos.setOnClickListener(miListenerLocal);

    }

    // Creamos aqui los listener
    // Asi tenemos acceso al resto de vistas dentro de la fila
    private View.OnClickListener miListenerLocal = new View.OnClickListener() {

        @Override
        public void onClick(View v) {

            position = (Integer) v.getTag();

            // Comprobamos la vista que lo esta invocando
            switch (v.getId()) {
                case R.id.nombrejugador:

                    break;

                case R.id.puntos:
                    try {
                        // Decrementamos el tanteo
                        Log.i("MILOG", "Modificamos el tanteo");
                        // Lanzamos el dialog
                        NumeroTanteoDialogFragment fragmento = new NumeroTanteoDialogFragment();
                        Bundle bundles = new Bundle();
                        bundles.putString("titulo", getString(R.string.sumar_puntos));
                        fragmento.setArguments(bundles);
                        Log.i("MILOG", "Mostramos el dialog para elegir el numero que queremos modificar");
                        FragmentManager fragmentManager = ((Activity) context).getFragmentManager();
                        fragmento.show(fragmentManager, "Dialogo_jugadores");

                    } catch (Exception ex) {
                        Toast.makeText(Tanteo.context, "Se produjo un error al modificar el tanteo", Toast.LENGTH_SHORT).show();
                    }
                    break;

                case R.id.sumar:
                    try {
                        Log.i("MILOG", "Sumamos uno");
                        // Incrementamos el tanteo
                        int tantos = Integer.parseInt(puntos.getText().toString()) + 1;
                        puntos.setText(String.valueOf(tantos));
                        // Actualizamos el backup
                        partida.getJugadores().get(position).setPuntuacion(tantos);
                        // Actualizamos el backup
                        backup.getBackup().set(indice, partida);
                        // Almacenamos
                        Log.i("MILOG", "Guardamos el backup");
                        backup.guardarBackup();

                    } catch (Exception ex) {
                        Toast.makeText(Tanteo.context, "Se produjo un error al incrementar el tanteo", Toast.LENGTH_SHORT).show();
                    }
                    break;

                case R.id.restar:
                    try {
                        // Decrementamos el tanteo
                        Log.i("MILOG", "Restamos uno");
                        int tantos = Integer.parseInt(puntos.getText().toString()) - 1;
                        puntos.setText(String.valueOf(puntos));
                        // Actualizamos el backup
                        partida.getJugadores().get(position).setPuntuacion(tantos);
                        // Actualizamos el backup
                        backup.getBackup().set(indice, partida);
                        // Almacenamos
                        Log.i("MILOG", "Guardamos el backup");
                        backup.guardarBackup();
                    } catch (Exception ex) {
                        Toast.makeText(Tanteo.context, "Se produjo un error al decrementar el tanteo", Toast.LENGTH_SHORT).show();
                    }
                    break;

            }
        }
    };

    // Sobreescribimos el metodo del dialogo para elegir el numero
    @Override
    public void onNumberSelected(int number) {

        Log.i("MILOG", "Actualizamos los puntos con el dialog");
        int puntuacion = Integer.parseInt(puntos.getText().toString()) + number;
        // Modificamos los puntos
        puntos.setText(String.valueOf(puntuacion));

        // Actualizamos el backup
        partida.getJugadores().get(position).setPuntuacion(puntuacion);
        // Actualizamos el backup
        backup.getBackup().set(indice, partida);
        // Almacenamos
        Log.i("MILOG", "Guardamos el backup");
        backup.guardarBackup();
    }
}

}

0
jgonzal 31 déc. 2015 à 18:32

Merci de votre aide,

Je l'ai résolu en utilisant vos indications. J'ai défini les auditeurs comme vous me l'avez dit. L'un de mes problèmes était que je mettais à jour l'objet viewholder à deux endroits différents. Je l'ai changé et j'ai également mis à jour la vue avec notifyDataSetChanged ().

La solution pour le numberpicker était d'implémenter la méthode de rappel dans l'activité principale et de passer la position de la liste comme paramètre pour modifier l'élément correct.

Meilleures salutations.

0
jgonzal 4 janv. 2016 à 20:42