我正在尝试创建我的第一个Android应用,但我无法做我想要的。 我的想法是创建一个简单的分数计数器。我有一个listview的活动。 listview的每个项目都有一个带有名称的TextView,两个用于添加和减去的按钮,以及一个用于分数的TextView。
我的想法是在用户点击分数时显示一个custum numberpicker,选择一个数字来增加减少。自定义数字选择器有一个接口,可以使用回调方法来获取所选的数字。
在activity类中,我有一个用于listview的自定义适配器,以及一个用于改进功能的viewholder类。我有几个疑问/问题:
1)我什么时候可以定义按钮/文本视图的监听器?目前我在viewholder中有监听器,但我不确定它是否是更好的解决方案,也许最好在适配器中定义它们,或者甚至为listview创建一个onitemclicklistener。
2)我可以实现适配器或viewholder类内的numberpicker对话框界面中定义的方法吗?我已经尝试了但是我得到了一个强制转换异常,因为内部类不是一个活动...
3)如果我在activity(外部)类中实现接口方法,我无法修改调用numberpicker所需的textview ...
我的两个主要问题是在listview行中为每个视图定义监听器的位置和方法,以及如何获取numberpicker对话框的编号并继续执行......
有人可以帮助我吗?
感谢。
答案 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传递给更改正确的项目。
最好的问候。