2015-09-24 4 views
0

Я делаю приложение корзины покупок, где пользователи могут добавлять и удалять элементы из корзины. Когда пользователь просматривает свою корзину, появляется список элементов, которые они добавили. Этот список создается с помощью ArrayAdapter. Каждая строка содержит кнопку удаления, где пользователь может удалить элемент из корзины. Я успешно удалил элемент из объекта Cart. Тем не менее, у меня возникают проблемы при обновлении экрана, когда пользователь нажимает кнопку удаления. Я слышал об методе notifydatasetchanged() для адаптеров, но я не уверен, как реализовать это изнутри OnClickListener в getView. Вот код:Обновление ArrayAdapter изнутри onClickListener в getView

CartScreen.java

package com.livilatenight.livilatenight; 

import android.support.v7.app.ActionBarActivity; 
import android.os.Bundle; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.widget.ListView; 
import android.widget.Toast; 

import com.parse.ParseException; 
import com.parse.ParseUser; 
import com.parse.SaveCallback; 

public class CartScreen extends ActionBarActivity { 

    ListView items; 

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

     final ParseUser current = ParseUser.getCurrentUser(); 

     try{ 
      Cart userCart = (Cart) current.fetchIfNeeded().get("cart"); 
      String[] itemNames = userCart.getItems(); 
      String[] itemPrices = userCart.getPrices(); 
      int[] quantities = userCart.getQuantities(); 
      Integer[] itemPictures = userCart.getPictures(); 

      CartListAdapter adapter = new CartListAdapter(CartScreen.this, itemNames,itemPrices,quantities,itemPictures); 
      items = (ListView) findViewById(R.id.listView); 
      items.setAdapter(adapter); 
     }catch(ParseException e){ 
      Toast.makeText(CartScreen.this, e.toString(),Toast.LENGTH_LONG).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_cart_screen, 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(); 

     //noinspection SimplifiableIfStatement 
     if (id == R.id.action_settings) { 
      return true; 
     } 

     return super.onOptionsItemSelected(item); 
    } 
} 

CartListAdapter.java

package com.livilatenight.livilatenight; 

import android.app.Activity; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ArrayAdapter; 
import android.widget.Button; 
import android.widget.ImageView; 
import android.widget.Spinner; 
import android.widget.TextView; 
import android.widget.Toast; 

import com.parse.ParseUser; 

public class CartListAdapter extends ArrayAdapter<String> { 

    private final Activity context; 
    private final String[] items; 
    private final String[] prices; 
    private final int[] quantities; 
    private final Integer[] pictures; 

    public CartListAdapter(Activity context, String[] itemnames, String[] prices, int[] quantities, Integer[] pictures) { 
     super(context, R.layout.item_list, itemnames); 

     this.context=context; 
     this.items=itemnames; 
     this.prices=prices; 
     this.quantities=quantities; 
     this.pictures=pictures; 
    } 

    public View getView(final int position,View view,ViewGroup parent) { 
     LayoutInflater inflater=context.getLayoutInflater(); 
     View rowView=inflater.inflate(R.layout.cart_item, null,true); 

     TextView itemName = (TextView) rowView.findViewById(R.id.tvItemName); 
     TextView itemPrice = (TextView) rowView.findViewById(R.id.tvPrice); 
     ImageView itemPicture = (ImageView) rowView.findViewById(R.id.ivItemPicture); 
     View blankView = (View) rowView.findViewById(R.id.blankView); 
     Button removeCart = (Button) rowView.findViewById(R.id.btnRemoveCart); 

     final Spinner spinner = (Spinner) rowView.findViewById(R.id.spinnerQty); 
     ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(context, R.array.spinner_numbers, android.R.layout.simple_spinner_item); 
     adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 
     spinner.setAdapter(adapter); 


     spinner.setSelection(quantities[position]-1); 

     itemName.setText(items[position]); 
     itemPrice.setText(prices[position]); 
     itemPicture.setImageResource(pictures[position]); 

     removeCart.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       ParseUser current = ParseUser.getCurrentUser(); 
       int quantity = spinner.getSelectedItemPosition()+1; 

       Cart userCart = (Cart) current.get("cart"); 
       boolean success = userCart.removeFromCart(items[position]); 

       if(success){ 
        Toast.makeText(getContext(), "Removed from Cart", Toast.LENGTH_LONG).show(); 
       }else{ 
        Toast.makeText(getContext(), "Item is already in your shopping cart", Toast.LENGTH_LONG).show(); 
       } 

       current.saveInBackground(); 
      } 
     }); 
     return rowView; 
    }; 
} 

Я хочу, чтобы обновить список корзины, когда пользователь нажимает на кнопку removeCart. Как я могу это сделать?

UPDATE

Я сделал обходной путь, где я просто установить новый адаптер каждый раз, когда элемент удаляется. Не то, что я хотел сделать, но он работает, поэтому я сохраню его так, как есть.

+0

Вы хотите, чтобы удалить его строку из ListView? –

+0

Да, я хочу удалить строку, как только пользователь удалит ее. Я успешно удалил его, когда оставил активность и вернулся, но я хочу, чтобы он удалялся в том же самом действии. – CipherOne

ответ

1

В вашем пользовательском адаптере вызова this.notifyDataSetChanged(); где вы выполняете функцию удаления и удаляете этот элемент из массива, который настроен на этот адаптер. Вы также должны удалить эту запись из ArrayList, которую вы установили в ваш адаптер, если знаете, какую запись вы можете использовать ArrayList.remove (index); а затем используйте notifyDataSetChanged();

EDIT: Перейти к адаптеру и добавить метод удаления();

public void delete(int position){ 
data.remove(position); 
notifyItemRemoved(position); 
} 

В вашем onClick(); Метод добавить следующее:

delete(getPosition()); 
+0

Как я могу ссылаться на адаптер изнутри прослушивателя кликов? Вызов этого.notifyDataSetChanged() не работает, потому что он находится внутри нового View.OnClickListener() – CipherOne

+0

См. обновленный ответ. – Stanojkovic

1

попробовать этот

if (success) { 
        Toast.makeText(getContext(), "Removed from Cart", Toast.LENGTH_LONG).show(); 
        final String s = items[position]; 
        List<String> list = new ArrayList<String>(Arrays.asList(items)); 
        list.remove(s); 
        items = list.toArray(array); 
        this.notifyDataSetChanged() 
       } 
0

Вот решение, которое работает в моем случае.

В вашем CartListAdapter переопределения метода удалить из массива адаптера.

@Override 
public void remove(String var){ 
    // Call your utility methods you defined to delete the item 
    // Notify ListView that their is a change 
    notifyDataSetChanged(); 
} 

Внести следующие изменения в вашем Click Listener

removeCart.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      // Call this.remove(var) with String you want to delete 
     } 
    }); 

notifyDataSetChanged() работает только в случае, add()insert(), remove() и clear(). Читать this

НТН

+0

Я не могу вызвать CartListAdapter.remove (var), потому что метод remove не является статическим. Если я сделаю его статическим, я не могу вызвать notifyDataSetChanged() в remove, потому что он является статичным. Это моя главная проблема, когда мы это делаем. – CipherOne

+0

Правильно, спасибо за указание. Однако нам не нужно ставить метод 'remove'. Нажмите «Слушатель» и удалите их в одном классе. Вы можете вызвать метод remove из Click Listener таким образом 'this.remove (var)' или просто 'remove (var)'. Ответ был обновлен. – Prateek

+0

Они не в одном классе. OnClick() находится в новом классе View.OnClickListener(). Но все в порядке, я уже сделал обходной путь, поэтому я просто оставлю его. – CipherOne

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