2015-01-10 2 views
0

ArrayAdapter<Action>으로 확장되는 Adapter이 있습니다. 나는 ArrayList<Action>AdapterActions에주고 그것은 ListView을 그 ArrayList로 채 웁니다.어댑터의 arraylist.remove()가 ListView의 잘못된 항목을 삭제합니다.

ListaActions(0) = a 
ListaActions(1) = b 
ListaActions(2) = c 
ListaActions(3) = d 
ListaActions(4) = e 

내가 ListaActions.remove(2)을하고 나는 명확하고 ListaActions마다 Action 개체를 다시 추가, 그것은 성공적으로 ArrayList의에서 세 번째 개체를 제거합니다

이의이 내 ArrayList에있다 가정하자 : 문제는 이것이다 그러나 ListView에서 마지막 항목 (이 경우에는 ListAActions (4)의보기)을 제거하고 해당 ListView에 표시된 제거 된 객체 (ListaActions (4))의 모든 속성을 기본값 (예 : : int 속성을 0으로, 부울 속성을 true로 ...

Whe n 응용 프로그램을 닫은 다음 다시 엽니 다. 여전히 동일합니다. ListView를 "새로 고치지"않습니다. 어떤 생각?

나는 notifyDataSetChanged()에 대한 몇 가지 글을 읽었습니다,하지만이하는 일은 그 "빈 나는 응용 프로그램을 다시 시작하면이 모든 것을 다시 작성하는 경우,"데이터 세트가 변경된 것을 통지 "하는 것입니다 경우에 나는 일할 수있는 생각하지 않는다 "보기가 여전히 있으며 ArrayList의 마지막 객체가 목록보기에 표시되지 않습니다.

AdapterActions의 코드입니다 :

import java.util.ArrayList; 
    import java.util.HashMap; 
    import java.util.Map; 

    import android.annotation.SuppressLint; 
    import android.app.Activity; 
    import android.database.Cursor; 
    import android.database.sqlite.SQLiteDatabase; 
    import android.util.Log; 
    import android.view.LayoutInflater; 
    import android.view.View; 
    import android.view.ViewGroup; 
    import android.widget.ArrayAdapter; 
    import android.widget.Switch; 
    import android.widget.TextView; 
    import android.widget.Toast; 


    /*@SuppressLint("ViewHolder") */public class AdapterActions extends ArrayAdapter<Action>{ 

     // our ViewHolder. 
     // caches our TextView 
     static class ViewHolderItem { 
      TextView codigo; 
      TextView accion; 
      TextView evento; 
      Switch UnSwitch; 
      boolean isChecked1; 
     } 

     Activity context; 
     ArrayList<Action> listaActions; 
     @SuppressLint("UseSparseArrays") Map <Integer, Boolean> map = new HashMap<Integer, Boolean>(); 

     // Le pasamos al constructor el contexto y la lista de contactos 
     public AdapterActions(Activity context, ArrayList<Action> listaActions) { 
      super(context, R.layout.layout_adapter_actions, listaActions); 
      this.context = context; 
      this.listaActions = listaActions; 




     } 

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

      ViewHolderItem viewHolder; 

      // Rescatamos cada item del listview y lo inflamos con nuestro layout 
      //View item = convertView; 
      //item = context.getLayoutInflater().inflate(R.layout.layout_adapter_actions, null); 
      // well set up the ViewHolder 
      viewHolder = new ViewHolderItem(); 

      if(convertView==null){ 

       // inflate the layout 
       LayoutInflater inflater = ((Activity) context).getLayoutInflater(); 
       convertView = inflater.inflate(R.layout.layout_adapter_actions, parent, false); 

       // well set up the ViewHolder 
       viewHolder.codigo = (TextView) convertView.findViewById(R.id.codigo); 
       viewHolder.accion = (TextView) convertView.findViewById(R.id.accion); 
       viewHolder.evento = (TextView) convertView.findViewById(R.id.evento); 
       viewHolder.UnSwitch = (Switch) convertView.findViewById(R.id.activa); 
       convertView.setLongClickable(true); 

       // store the holder with the view. 
       convertView.setTag(viewHolder); 

      }else{ 
       // we've just avoided calling findViewById() on resource everytime 
       // just use the viewHolder 
       viewHolder = (ViewHolderItem) convertView.getTag(); 
      } 

      Action a = new Action(0, 1, 1, true); 
      AccionDefinida LaAccion = new AccionDefinida(0, 0, "", ""); 
      EventoDefinido ElEvento = new EventoDefinido(0, 0, "", ""); 

      //ACTIONS 
        ActionsSQLite base = new ActionsSQLite(context, "Actions", null,1); 
        SQLiteDatabase db1 = base.getReadableDatabase(); 
        db1 = context.openOrCreateDatabase("Actions",SQLiteDatabase.OPEN_READONLY, null); 

        String query = "SELECT * FROM Actions WHERE Id = " + String.valueOf(position + 1); 
        Cursor c1 = db1.rawQuery(query, null); 

        try{ 
         if(c1!=null){ 

          int i = c1.getColumnIndexOrThrow("Id"); 
          int j = c1.getColumnIndexOrThrow("IdAccionDefinida"); 
          int k = c1.getColumnIndexOrThrow("IdEventoDefinido"); 
          int l = c1.getColumnIndexOrThrow("Activa"); 
          boolean esActiva; 

          //Nos aseguramos de que existe al menos un registro 
          while(c1.moveToNext()){ 
           if (c1.getInt(l) == 0){ 
            esActiva = false; 
           } else 
           { 
            esActiva = true; 
           } 
           //Recorremos el cursor hasta que no haya más registros 
           a = new Action(c1.getInt(i), c1.getInt(j), c1.getInt(k), esActiva); 
          } 
         } 
         else 
          Toast.makeText(context.getApplicationContext(), 
             "No hay nada :(", Toast.LENGTH_LONG).show(); 
         } 
         catch (Exception e){ 
         Log.i("bdActions", "Error al abrir o crear la base de datos" + e); 
         } 

         if(db1!=null){ 
          db1.close(); 
        } 


      //EVENTOS 
      EventosDefinidosSQLite base2 = new EventosDefinidosSQLite(this.context, "EventosDefinidos", null, 1); 
      SQLiteDatabase db2 = base2.getReadableDatabase(); 
      db2 = context.openOrCreateDatabase("EventosDefinidos",SQLiteDatabase.OPEN_READONLY, null); 

      String query2 = "SELECT * FROM EventosDefinidos WHERE Id = " + a.getIdEventoDefinido(); 
      Cursor c2 = db2.rawQuery(query2, null); 
      try{ 
       if(c2!=null){ 

        int h = c2.getColumnIndexOrThrow("Id"); 
        int k = c2.getColumnIndexOrThrow("IdEvento"); 
        int i = c2.getColumnIndexOrThrow("Nombre"); 
        int j = c2.getColumnIndexOrThrow("Aux"); 

        //Nos aseguramos de que existe al menos un registro 
        while(c2.moveToNext()){ 
         //Recorremos el cursor hasta que no haya más registros 
         ElEvento = new EventoDefinido(c2.getInt(h), c2.getInt(k), c2.getString(i), c2.getString(j)); 
        } 
       } 
       else 
        Toast.makeText(context.getApplicationContext(), 
          "No hay nada :(", Toast.LENGTH_LONG).show(); 
      } 
      catch (Exception e){ 
       Log.i("bdEventos", "Error al abrir o crear la base de datos" + e); 
      } 

      if(db2!=null){ 
       db2.close(); 
      } 
      //ACCIONES 
      AccionesDefinidasSQLite base3 = new AccionesDefinidasSQLite(context, "AccionesDefinidas", null,1); 
      SQLiteDatabase db3 = base3.getReadableDatabase(); 
      db3 = context.openOrCreateDatabase("AccionesDefinidas", SQLiteDatabase.OPEN_READONLY, null); 

      String query3 = "SELECT * FROM AccionesDefinidas WHERE Id = " + String.valueOf(a.getIdAccionDefinida()); 
      Cursor c3 = db3.rawQuery(query3, null); 
      try{ 
       if(c3!=null){ 

        int h = c3.getColumnIndexOrThrow("Id"); 
        int k = c3.getColumnIndexOrThrow("IdAccion"); 
        int i = c3.getColumnIndexOrThrow("Nombre"); 
        int j = c3.getColumnIndexOrThrow("Aux"); 

        //Nos aseguramos de que existe al menos un registro 
        while(c3.moveToNext()){ 
         //Recorremos el cursor hasta que no haya más registros 
         LaAccion = new AccionDefinida(c3.getInt(h), c3.getInt(k), c3.getString(i), c3.getString(j)); 
        } 
       } 
       else 
        Toast.makeText(context.getApplicationContext(), 
          "No hay nada :(", Toast.LENGTH_LONG).show(); 
      } 
      catch (Exception e){ 
       Log.i("bdAcciones", "Error al abrir o crear la base de datos" + e); 
      } 

      if(db3!=null){ 
       db3.close(); 
      } 

      // object item based on the position 


      // assign values if the object is not null 
      if(a != null) { 
       // get the TextView from the ViewHolder and then set the text (item name) and tag (item ID) values 
       viewHolder.codigo.setText(String.valueOf(a.getId())); 
       viewHolder.codigo.setTag(a.getId()); 
       viewHolder.accion.setText(LaAccion.getNombre()); 
       viewHolder.evento.setText(ElEvento.getNombre()); 
       viewHolder.UnSwitch.setChecked(a.getActiva()); 
       Log.e("Position+1: "+ String.valueOf(position+1), "Id: "+ String.valueOf(a.getId())); 


      } 

      viewHolder.isChecked1 = viewHolder.UnSwitch.isChecked(); 
      map.put(position, viewHolder.isChecked1); 
      viewHolder.UnSwitch.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        Log.e("OnClick", "Se clickeó"); 

        listaActions.get(position).setActiva(map.get(position)); 
        Log.e("Listener del switch", "Modificó la action en la lista de la ActividadPrincipal"); 
        int isActiva; 
        if(map.get(position) == true) 
        { 
         isActiva = 0; 
         Log.e("Listener del switch", "isActiva = 1"); 
         map.put(position, false); 
        } else 
        { 
         isActiva = 1; 
         Log.e("Listener del switch", "isActiva = 0"); 
         map.put(position, true); 
        } 
        String query = "UPDATE Actions SET Activa = " + String.valueOf(isActiva) + " WHERE Id = " + String.valueOf(position+1); 
        Log.e("Consulta:", query); 
        Log.e("Listener del switch", "query creado"); 
        Log.e("La position debería ser", String.valueOf(position+1)); 
        Log.e("Y el valor del map.get(position) es", String.valueOf(map.get(position))); 
        ActionsSQLite helper1 = new ActionsSQLite(context, "Actions", null, 1); 
        Log.e("Listener del switch", "Creo el helper"); 
        SQLiteDatabase db = helper1.getWritableDatabase(); 
        Log.e("Listener del switch", "obtenida la base escribible"); 
        db.execSQL(query); 
        Log.e("Listener del switch", "Query ejecutado"); 
       } 
      }); 



      return convertView; 


     } 

그리고 내가 그 ArrayList를에서 개체를 삭제할 때,이 대화 상자에서 작업을 수행합니다

import java.util.ArrayList; 

import android.app.Activity; 
import android.app.DialogFragment; 
import android.content.DialogInterface; 
import android.database.sqlite.SQLiteDatabase; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.view.View.OnClickListener; 
import android.widget.ArrayAdapter; 
import android.widget.Button; 
import android.widget.Spinner; 


public class DialogModificarAction extends DialogFragment 
{  

    public interface DialogModificarActionListener { 

     } 



    private int getIndex(Spinner spinner, ArrayList<String> MiLista){ 

     int index = 0; 

      for(int j = 0;j<=MiLista.size();j++){ 
      if (spinner.getSelectedItem().equals(MiLista.get(j))){ 
       index = j; 
       break; 
      } 
     } 
     return index; 
} 

    private Button cancelButton; 
    private Button confirmButton; 
    private Button deleteButton; 
    private Spinner spinnerAccion; 
    private Spinner spinnerEvento; 
    private static Action ActionAModificar = null; 
    private ArrayList<EventoDefinido> ListaEventosDefinidos = new ArrayList<EventoDefinido>(); 
    private ArrayList<AccionDefinida> ListaAccionesDefinidas = new ArrayList<AccionDefinida>(); 
    private ArrayList<String> ListaNombresAccionesDefinidas = new ArrayList<String>(); 
    private ArrayList<String> ListaNombresEventosDefinidos = new ArrayList<String>(); 

    public DialogModificarAction() 
    { 
     // Empty constructor required for DialogFragment 
    }  
    @SuppressWarnings("unused") 
    private DialogModificarActionListener dialogListener; 


    //This is how you can supply your fragment with information 
    public static DialogModificarAction newInstance(ArrayList<Action> ListaActions, ArrayList<AccionDefinida> ListaAccionesDefinidas, ArrayList<EventoDefinido> ListaEventosDefinidos, Action ActionAModificar) 
    { 
     DialogModificarAction myDialog = new DialogModificarAction(); 
     Bundle args = new Bundle(); 
     args.putParcelableArrayList("ListaActions", ListaActions); 
     args.putParcelableArrayList("ListaAccionesDefinidas", ListaAccionesDefinidas); 
     args.putParcelableArrayList("ListaEventosDefinidos", ListaEventosDefinidos); 
     args.putParcelable("ActionAModificar", ActionAModificar); 
     myDialog.setArguments(args); 
     return myDialog; 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setStyle(STYLE_NO_TITLE, 0); // Le saca el título al DialogFragment 

    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    { 
     View view = inflater.inflate(R.layout.dialog_modif_baja_action, container); 

     //DECLARO LOS ELEMENTOS EN EL LAYOUT 
     ActionAModificar = getArguments().getParcelable("ActionAModificar"); 
     ListaAccionesDefinidas = getArguments().getParcelableArrayList("ListaAccionesDefinidas"); 
     ListaEventosDefinidos = getArguments().getParcelableArrayList("ListaEventosDefinidos"); 

     spinnerAccion = (Spinner)view.findViewById(R.id.spinnerAccionDefinida); 
     spinnerEvento = (Spinner)view.findViewById(R.id.spinnerEventoDefinido); 

     AccionDefinida AccionTemporal; 
     for(int i = 0; i<= ListaAccionesDefinidas.size()-1;i++) 
     { 
      AccionTemporal = ListaAccionesDefinidas.get(i); 
      ListaNombresAccionesDefinidas.add(AccionTemporal.getNombre()); 
     } 

     EventoDefinido EventoTemporal; 
     for(int i = 0; i<= ListaEventosDefinidos.size()-1;i++) 
     { 
      EventoTemporal = ListaEventosDefinidos.get(i); 
      ListaNombresEventosDefinidos.add(EventoTemporal.getNombre()); 
     } 


     ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this.getActivity(), android.R.layout.simple_spinner_item, ListaNombresAccionesDefinidas); 
     dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 
     spinnerAccion.setAdapter(dataAdapter); 
     spinnerAccion.setSelection(ActionAModificar.getIdAccionDefinida()-1); 

     ArrayAdapter<String> dataAdapter2 = new ArrayAdapter<String>(this.getActivity(), android.R.layout.simple_spinner_item, ListaNombresEventosDefinidos); 
     dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 
     spinnerEvento.setAdapter(dataAdapter2); 
     spinnerEvento.setSelection(ActionAModificar.getIdEventoDefinido()-1); 

     //Setup cancel button listener 
     cancelButton = (Button) view.findViewById(R.id.cancelButton); 
     cancelButton.setOnClickListener(new OnClickListener() 
     { 
      @Override 
      public void onClick(View v) 
      { 
       //Cerrar diálogo y no hacer nada 
       getDialog().dismiss(); 
      } 
     }); 

     //Setup confirm button listener 
     confirmButton = (Button) view.findViewById(R.id.confirmButton); 
     confirmButton.setOnClickListener(new OnClickListener() 
     { 
      @Override 
      public void onClick(View v) 
      { 
       //Obtengo los ids de la accion y el evento 
       int IdAccionDefinidaSeleccionada; 
       int IdEventoDefinidoSeleccionado; 

       IdAccionDefinidaSeleccionada = ListaAccionesDefinidas.get(getIndex(spinnerAccion, ListaNombresAccionesDefinidas)).getId(); 
       IdEventoDefinidoSeleccionado = ListaEventosDefinidos.get(getIndex(spinnerEvento, ListaNombresEventosDefinidos)).getId(); 
       ActionAModificar.setIdAccionDefinida(IdAccionDefinidaSeleccionada); 
       ActionAModificar.setIdEventoDefinido(IdEventoDefinidoSeleccionado); 

       ActividadPrincipal.listaActions.get(ActionAModificar.getId()).setIdAccionDefinida(IdAccionDefinidaSeleccionada); 
       ActividadPrincipal.listaActions.get(ActionAModificar.getId()).setIdEventoDefinido(IdEventoDefinidoSeleccionado); 

       //Agrego la Action a la base de datos 
       ActionsSQLite helper1 = new ActionsSQLite(getActivity(), "Actions", null, 1); 
       SQLiteDatabase db = helper1.getWritableDatabase(); 
       String myQuery = "UPDATE Actions SET IdAccionDefinida = " + String.valueOf(IdAccionDefinidaSeleccionada) + ", IdEventoDefinido = " + String.valueOf(IdEventoDefinidoSeleccionado) + " WHERE Id = " + String.valueOf(ActionAModificar.getId()); 
       db.execSQL(myQuery); 

       ActividadPrincipal parent = (ActividadPrincipal) getActivity(); 
       parent.listView.invalidateViews(); 
       //Cerrar diálogo 
       getDialog().dismiss(); 


      } 
     }); 

     deleteButton = (Button) view.findViewById(R.id.deleteButton); 
     deleteButton.setOnClickListener(new OnClickListener() 
     { 
      @Override 
      public void onClick(View v) 
      { 
       String query = "DELETE FROM Actions WHERE Id = " + String.valueOf(ActionAModificar.getId()); 
       ActionsSQLite helper1 = new ActionsSQLite(getActivity(), "Actions", null, 1); 
       SQLiteDatabase db = helper1.getWritableDatabase(); 
       db.execSQL(query); 
       Log.e("Listener del switch", "Query ejecutado"); 
       ActividadPrincipal.listaActions.remove(ActionAModificar.getId()-1); 
       ActividadPrincipal.adapterActions.notifyDataSetChanged(); 

       //Cerrar diálogo 
       getDialog().dismiss(); 
      } 
     }); 


     return view; 
    } 

    @Override 
    public void onAttach(Activity activity) 
    { 
     super.onAttach(activity); 
     if (activity instanceof DialogModificarActionListener) 
     { 
      dialogListener = (DialogModificarActionListener) activity; 
     } 
     else 
     { 
      throw new ClassCastException(activity.toString() + " must implement dialogListener.DialogActionsListener"); 
     } 
    } 

    @Override 
    public void onDismiss(DialogInterface dialog) { 
     ActividadPrincipal parent = (ActividadPrincipal) getActivity(); 
     parent.ActualizarActions(); 

    } 
} 
+0

더 많은 코드를 게시하십시오. 알겠습니다 ... – Elltz

+0

코드에 질문이 추가되었습니다. –

답변

1

당신은의 데이터를 변경하는 경우 목록에서 제대로 작동하려면 어댑터의 notifyDataSetChanged 메소드를 호출해야합니다.

당신이 제외 또 다른 버그가있을 수 있습니다

하지만 notifyDataSetChanged은 분명히 필요합니다. 먼저 문제를 추가 한 다음 문제가 지속되면 문제 해결을 계속하십시오.

편집 : 이제 코드를 보았으므로 코드가 작동하지 않아서 놀라지 않을 것입니다. 당신은 분명히 별도의 엔티티가되어야하는 몇 가지 개념을 뒤죽박죽으로 보았습니다. 특히 어댑터에서 데이터베이스 액세스를해서는 안됩니다.

코드를 완전히 이해하려고 노력하지 않으려 고합니다. 솔직히 말하면 엉망입니다. 대신이 코드를 사용하여 에 접근해야합니다.에 접근해야합니다.

두 가지 기본 시나리오가 있습니다. 첫 번째 시나리오에서는 개체 목록이 있고이를 ListView에 표시하려고합니다. 두 번째 시나리오에서는 데이터베이스에 개체가 있고이를 ListView에 표시하려고합니다. 두 시나리오는 혼합되어서는 안됩니다.

첫 번째 (더 간단한) 시나리오에서는 ListAdapter를 구성하고 어댑터에 목록을 제공하기 만하면됩니다. 이 시나리오에서 목록에서 항목을 삭제하면 ListAdapter의 notifyDataSetChanged() 메서드도 호출해야합니다. 이 삭제 기능을 현재 응용 프로그램 실행 이상으로 유지하려면 목록의 원본 소스를 직접 업데이트해야합니다. 두 번째 경우

, 당신은 아마 아마 컨텐트 프로에서 얻은 CursorLoader을 사용하여 데이터베이스에서 커서를 얻을 것입니다. 그런 다음 CursorAdapter를 만들고 ListView와 함께 사용합니다.이 시나리오에서는 ContentProvider에게 데이터베이스에서 항목을 삭제하도록 요청하면 ContentProvider가 자동으로 커서를 업데이트하게되며 작업을 알립니다. 그런 다음 새 커서를 CursorAdapter에 부여하고이를 notifyDataSetChanged 메소드라고합니다.

웹에서이 작업을 수행하는 방법에 대한 자습서가 많이 있습니다. 몇 가지 예를 읽고 확인해 보시기 바랍니다.

+0

답변 해 주셔서 감사합니다. 이 코드는 어디에서'notifyDataSetChanged()'를해야하고 어디에서 호출해야합니까? –

+0

목록을 수정하자마자 어댑터의 notifyDataSetChanged 메소드를 호출하십시오. – GreyBeardedGeek

+0

하지만 메서드에 대한 정적 참조를 만들 수 없습니다. 어떻게해야합니까? –