Android自定义listview适配器和numberpicker dialogfragment

时间:2015-12-31 18:04:42

标签: android listview numberpicker

我正在尝试创建我的第一个Android应用,但我无法做我想要的。 我的想法是创建一个简单的分数计数器。我有一个listview的活动。 listview的每个项目都有一个带有名称的TextView,两个用于添加和减去的按钮,以及一个用于分数的TextView。

我的想法是在用户点击分数时显示一个custum numberpicker,选择一个数字来增加减少。自定义数字选择器有一个接口,可以使用回调方法来获取所选的数字。

在activity类中,我有一个用于listview的自定义适配器,以及一个用于改进功能的viewholder类。我有几个疑问/问题:

1)我什么时候可以定义按钮/文本视图的监听器?目前我在viewholder中有监听器,但我不确定它是否是更好的解决方案,也许最好在适配器中定义它们,或者甚至为listview创建一个onitemclicklistener。

2)我可以实现适配器或viewholder类内的numberpicker对话框界面中定义的方法吗?我已经尝试了但是我得到了一个强制转换异常,因为内部类不是一个活动...

3)如果我在activity(外部)类中实现接口方法,我无法修改调用numberpicker所需的textview ...

我的两个主要问题是在listview行中为每个视图定义监听器的位置和方法,以及如何获取numberpicker对话框的编号并继续执行......

有人可以帮助我吗?

感谢。

3 个答案:

答案 0 :(得分:0)

要在适配器内的视图中使用侦听器,应在适配器中声明侦听器,并为每个视图创建新的侦听器实例。

getView()

现在使用holder.listener = new CustomListener(position); holder.incrementBtn.setOnClickListener(holder.listener); 方法:

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(); } } 方法:

onClick()

notifyDataSetChanged()方法完成后,视图会通过DialogInterface.OnClickListener更新并带有新分数。 要使用数字选择器对话框,只需在视图中定义terms aggregation即可使用相同的模式。

答案 1 :(得分:0)

当然,抱歉......

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();
    }
}

}

答案 2 :(得分:0)

感谢您的帮助,

我已经用你的指示解决了它。我告诉我,我已经定义了听众。我的一个问题是我在两个不同的地方更新了viewholder对象。我已更改它,并使用notifyDataSetChanged()更新视图。

numberpicker的解决方案是在main活动中实现回调方法,并将listview的位置作为param传递给更改正确的项目。

最好的问候。