2014-12-26 2 views
0

Я внедрил пользовательский адаптер и listItemView. Адаптер устанавливает onlclick прослушиватель на кнопку, которая находится в listItemView. Слушатель onclick просто вызывает частный метод, который у меня есть в адаптере, и передает ему позицию элемента, который нужно удалить. Я знаю, что позиция правильная, потому что база данных удаляет соответствующий элемент. Я нашел похожие вопросы, но не смог адаптировать ответы для работы для меня. Идеи и мысли очень ценятся. Благодарю.вызов удалить из пользовательского адаптера всегда удаляет последний элемент

Вот полный адаптер класса

public class FoodListAdapter extends ArrayAdapter<FoodListItem> { 

    //private 
    private int type; 

    public FoodListAdapter(Context context, ArrayList<FoodListItem> _objects) { 
     super(context, 0, _objects); 
     type = 0;  
    } 

    public FoodListAdapter(Context context, ArrayList<FoodListItem> _objects, int _type) { 
     super(context, 0, _objects); 
     type = _type;  
    } 

    @Override 
    public View getView(int position, View reusableView, ViewGroup parent) 
    { 
     //Cast the reusable view to a listAdpaterItemView 
     FoodListItemView listItemView = (FoodListItemView) reusableView; 

     //Check if the listAdapterItem is null 
     if(listItemView == null) 
     { 
      //If it is null, then create a view. 
      listItemView = FoodListItemView.inflate(parent, this, type); 
     } 

     if (type == 2) 
     { 
      Button deleteButton = (Button) listItemView.findViewById(R.id.listItemViewDeleteBTN); 
      deleteButton.setTag(new Integer(position)); 
     } 

     //Now we need to set the view to display the data. 
     listItemView.setData(getItem(position)); 

     return listItemView; 
    } 
} 

Вот часть моего кода используется в фрагменте. Обратите внимание, что у меня есть приватная переменная, объявленная в классе для listAdapter, хотя я не думаю, что мне это нужно.

private void displayListForDate(Calendar _date) 
{ 
    //get the list view 
    ListView listView = (ListView) getView().findViewById(1); 
    //Clear the listview by removing the listadapter and setting it to null. 
    //listView.setAdapter(null); 

    //First we must get the items. 
    Global global = (Global) getActivity().getApplicationContext(); 
    DietSQLiteHelper database = global.getDatabase(); 

    //Create a list to hold the items we ate. This list will then be added to the listView. 
    final ArrayList<FoodListItem> consumedList; 
    //Add the items to the array. 
    consumedList = database.getConsumed(_date.getTimeInMillis()); 

    //Create an adapter to be used by the listView 
    listAdapter = new FoodListAdapter(getActivity().getBaseContext(), consumedList, 2); 

    //Add the adapter to the listView. 
    listView.setAdapter(listAdapter); 

    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
     @Override 
     public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) { 
      consumedList.remove(position); 
      listAdapter.notifyDataSetChanged(); 
     } 
    }); 
} 
+0

Где вы снимаете данные с адаптера? – Rohit5k2

+0

В deleteItem() Я вызываю remove (item), этот метод находится в классе адаптера. – n01d3a

+0

Вы можете отправить код 'remove (item)' method? – Rohit5k2

ответ

0

Я прошел и очистил свой код, и теперь он работает, вот рабочий код. Я действительно не знаю точно, в чем отличие, кроме того, что я обновил идентификаторы, которые я использовал для назначения и получения просмотров. Если кто-нибудь может объяснить причину проблемы, которую я имел, я был бы признателен.

Вот фрагмент из моего фрагмента, где я создаю представление списка и назначаю адаптер.

private void displayListForDate(Calendar _date) 
{ 
    //get the list view 
    ListView listView = (ListView) getView().findViewById(R.id.listView); 
    //Clear the listview by removing the listadapter and setting it to null. 
    //listView.setAdapter(null); 

    //First we must get the items. 
    Global global = (Global) getActivity().getApplicationContext(); 
    DietSQLiteHelper database = global.getDatabase(); 

    //Create a list to hold the items we ate. This list will then be added to the listView. 
    ArrayList<FoodListItem> consumedList; 
    //Add the items to the array. 
    consumedList = database.getConsumed(_date.getTimeInMillis()); 

    //Create an adapter to be used by the listView 
    listAdapter = new FoodListAdapter(getActivity().getBaseContext(), consumedList, 2); 

    //Add the adapter to the listView. 
    listView.setAdapter(listAdapter); 
} 

и вот мой класс адаптера.

public class FoodListAdapter extends ArrayAdapter<FoodListItem> 
{ 

    //private 
    private int type; 

    public FoodListAdapter(Context context, ArrayList<FoodListItem> _objects) { 
     super(context, 0, _objects); 
     type = 0;  
    } 

    public FoodListAdapter(Context context, ArrayList<FoodListItem> _objects, int _type) { 
     super(context, 0, _objects); 
     type = _type;  
    } 

    @Override 
    public View getView(int position, View reusableView, ViewGroup parent) 
    { 
     //Cast the reusable view to a listAdpaterItemView 
     FoodListItemView listItemView = (FoodListItemView) reusableView; 

     //Check if the listAdapterItem is null 
     if(listItemView == null) 
     { 
      //If it is null, then create a view. 
      listItemView = FoodListItemView.inflate(parent, type); 
     } 

     if (type == 2) 
     { 
      Button deleteButton = (Button) listItemView.findViewById(R.id.listItemViewDeleteBTN); 
      deleteButton.setTag(new Integer(position)); 
      deleteButton.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View view) { 
        Integer tag = (Integer) view.getTag(); 
        deleteItem(tag.intValue()); 
       } 
      }); 
     } 

     //Now we need to set the view to display the data. 
     listItemView.setData(getItem(position)); 

     return listItemView; 
    } 

    private void deleteItem(int position) 
    { 
     FoodListItem item = getItem(position); 
     Global global = (Global) getContext().getApplicationContext(); 

     DietSQLiteHelper database = global.getDatabase(); 
     database.removeConsumed(item.getID()); 

     remove(getItem(position)); 
    } 
} 
0

Если вы не реализовали метод «equals» метода FoodListItem, попробуйте его реализовать.

+0

Это реализовано, и я прошел через отладчик, чтобы убедиться, что true возвращается, когда идентификатор аргумента соответствует самому элементу. – n01d3a

0

Я бы предложил, , что вы просто обновите базовые данные, в вашем случае его ArrayList<FoodItems>.

В вашем адаптере сделать этот простой метод и изменения:

private List<FoodListItem> myList = new ArrayList<FoodListItem>(); 

public FoodListAdapter(Context context, List<FoodListItem> myList) { 
    super(context, 0, myList); 
    type = 0; 
    this.myList = myList; 
} 

public FoodListAdapter(Context context, List<FoodListItem> myList, int _type) { 
    super(context, 0, myList); 
    type = _type; 
    this.myList = myList;  
} 

// Also update your getView() method to use myList! 
@Override 
public View getView(int position, View reusableView, ViewGroup parent) 
{ 
    ... 
    listItemView.setData(myList.get(position)); 

public void removeItem(int positio){ 
    if(myList != null){ 
     myList.remove(position); 
    } 
} 

И тогда в классе, вы создаете адаптер (Activity/Fragment), просто вызовите метод.

// Update the underlying ArrayAdapter 
adapter.removeItem(position); 
// Notify the adapter, the data has changed 
adapter.notifyDataSetChanged(); 

Кроме того, вы не должны открытое подключение к SQLiteDatabase на UI потоке, потому что вы блокируете его. Вы никогда не знаете, насколько быстро читается с диска. Если это займет слишком много времени, пользователь может подумать, что ваше приложение застыло, и поэтому он уходит, чего вы не хотите. Я бы предложил использовать AsyncTask, вы найдете много examples.

+0

Я надеялся держаться подальше от реализации списка сам, когда адаптер обеспечивает его для вас. Я также должен будет переопределить некоторые методы, не будет. Также, как я могу удалить удаление из моего фрагмента, когда я добавляю clickListener к кнопке в адаптере; если вы посмотрите, что каждая строка в списке имеет кнопку удаления. Я рассмотрю ваши рекомендации по AsyncTask, однако я не хочу, чтобы пользовательский интерфейс продолжался до тех пор, пока данные не будут обновлены. Возможно, достаточно экрана ожидания. – n01d3a

+0

Я внес изменения, которые вы предложили, и по-прежнему имеет ту же проблему. Я должен что-то игнорировать. – n01d3a

+0

@ n01d3a похоже, что вы должны установить Listener в ListView и удалить элемент из ArrayList. Затем сообщите об этом адаптеру, и он должен правильно обновиться. Это означает, что вы делаете этот код в своей деятельности/фрагменте, а не в адаптере. Попробуйте взглянуть на это: http://stackoverflow.com/questions/18444671/remove-item-in-arrayadapterstring-in-listview –

Смежные вопросы