удаление элемента из ViewHolder (списка), экран обновления - PullRequest
1 голос
/ 14 марта 2012

У меня есть ViewHolder, который содержит (относительное расположение) представления, добавленные в список.В каждой отдельной раскладке у меня есть кнопка удаления.Я хочу иметь возможность нажать кнопку удаления и обновить экран.Моя текущая реализация работает, но я должен нажать кнопку «Назад», а затем вернуться к экрану, чтобы увидеть, что он был удален.

По сути, это корзина покупок, в которую элементы добавляются динамически.Короче говоря, что мне нужно добавить к событию onClick, которое обновит экран при нажатии кнопки удаления?Invalidate () не работает.

напоминание: эти методы отделены от onCreate (), поэтому я не могу использовать finish () или getIntent () или что-либо подобное.

edit:Я добавил дополнительные комментарии к ответу Рейнира

1 Ответ

3 голосов
/ 14 марта 2012

Я полагаю, вы используете ListView с пользовательским ListAdapter? Передайте ваш набор данных (например, ArrayList) в свой ListAdapter в конструкторе. Затем, когда вы манипулируете своим набором данных (например, dataset.remove(Object object)), вызовите .notifyDatasetChanged() в своем ListAdapter. Ваш адаптер обновит представление, которому он принадлежит.

Обновление

Я не совсем уверен, что вы имеете в виду, когда под этим понимается, что он «запирает» положение в держателе ». ViewHolder предназначен в основном просто для хранения ссылок на View, которые вы хотите манипулировать в вашем getView() -методе. Ваш набор данных отделен от ViewHolder, поэтому удаление содержимого из набора данных не должно влиять на макет - за исключением удаления элемента из представления списка, конечно.

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

Примечание: это, вероятно, не идеально, но должно быть просто отлично.

public class MyAdapter extends ArrayAdapter<CartItem> {

// This is our data-model.
// let's say your cartitems only contain an id and name
// normally this would be defined elsewhere in your code
public class CartItem {
    public int id;
    public String product_name;
}

/*
 * ViewHolders are basically meant to keep a reference to the Views,
 * so that you don't have to use .findViewById() on every getView()
 * for the elements you're trying to manipulate.
 * 
 * .findViewById() finds Views by traversing the hierarchy (heavy).
 * This generally isn't a problem, but we want to avoid this in
 * ListViews because getView() gets called a lot - which makes our app slow.   
 * 
 * We will want to keep a reference to our TextView and Button,
 * because these are the elements we want to change every getView().
 * Not to the RelativeLayout, because it's already passed in convertView
 * (after you inflated it for the first time) and we're not manipulating it
 * anyway.
 */
public class ViewHolder {

    public Button deleteButton;
    public TextView mTextView;

}

public MyAdapter(Context context, int textViewResourceId,
        ArrayList<CartItem> cartItems) {

    // here, we tie our data (ArrayList of CartItem's)
    // to the ListAdapter (ArrayAdapter = extended ListAdapter)
    super(context, textViewResourceId, cartItems);
}


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

    final ViewHolder holder;

    // if convertView == null, that means we haven't inflated our listitem yet.
    if(convertView == null) {

        // so, we'll inflate our listitem now.
        // after this, convertView will contain our RelativeLayout
        // and its children/subviews
        LayoutInflater inflater = (LayoutInflater) getContext()
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(R.layout.listitem, null);

        // now we're gonna instantiate the ViewHolder to keep a reference
        // to our TextView and ImageView
        holder = new ViewHolder();

        holder.mTextView = (TextView) convertView
                .findViewById(R.id.listitem_textview);
        holder.deleteButton = (Button) convertView
                .findViewById(R.id.listitem_deletebutton);

        // Now that we have our reference, we want to make sure we can
        // keep our reference by using tags. Tags are a way to attach
        // data to a View.
        convertView.setTag(holder);
    } else {
        // if we have already inflated our listitem, we just get the
        // references to our Views from the tag
        holder = (ViewHolder) convertView.getTag();
    }

    // we want to read/do-stuff-with a specific CartItem. First, get
    // a reference to the data-object.
    final CartItem mCartItem = (CartItem) getItem(position);

    // now, it's time to manipulate our views
    holder.mTextView.setText(mCartItem.product_name);
    holder.deleteButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {

            // then, pass a signal to MyAdapter that we want to remove
            // this item from our dataset
            remove(mCartItem);
            // now, we want to update any (list)views attached to our MyAdapter
            // this will let the ListView update itself
            notifyDataSetChanged();
        }

    });

    // convertView will be recycled, which means what we output here
    // will be the input for the next getView()-call
    return convertView;
}
}

Если вы хотите манипулировать вашим набором данных из своей деятельности, сделайте следующее:

MyAdapter myAdapter = new MyAdapter(this, R.layout.listitem, cartItems);
ListView listview = (ListView) findViewById(R.id.listview);
listview.setAdapter(myAdapter);

cartItems.remove(object);
myAdapter.notifyDatasetChanged();

Это удалит элемент из списка и да, это сбросит индексы позиции. Однако, если вы правильно настроили свой ListAdapter, это не будет проблемой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...