从自定义ListView(Android)中删除项目

时间:2013-11-19 20:12:24

标签: android listview

如何使用可以使用删除项按钮删除的复选框创建列表项的无尽列表视图?答案如下。

1 个答案:

答案 0 :(得分:1)

为了创建一个无休止的列表视图,你需要的第一件事是一组两个runnables。这些线程将更新适配器中的数据数组。

final int itemsPerPage = 100;
ArrayList<HashMap<String,String>> listItems = new ArrayList<HashMap<String,String>>();
boolean loadingMore = false;
int item = 0;

//Since we cant update our UI from a thread this Runnable takes care of that!
 public Runnable returnRes = new Runnable() {

    @Override
    public void run() {
        //Loop thru the new items and add them to the adapter
        if(groceries.getGroceries().size() > 0){
                    for(int i=0;i < listItems.size();i++) {
                        HashMap<String,String> grocery = listItems.get(i);
                        adapter.add(grocery);
                    }
        //Update the Application title
                setTitle("Grocery List with " + String.valueOf(groceries.getGroceries().size()) + " items");
        //Tell to the adapter that changes have been made, this will cause the list to refresh
                    adapter.notifyDataSetChanged();
        //Done loading more.
                    loadingMore = false;
            }
    }
 };


//Runnable to load the items
public Runnable loadMoreListItems = new Runnable() {
@Override
public void run() {

    //Set flag so we cant load new items 2 at the same time
    loadingMore = true;
    //Reset the array that holds the new items
    listItems = new ArrayList<HashMap<String,String>>();
    //Get 8 new listitems
    for (int i = 0; i < itemsPerPage; i++) {
        if (i < groceries.getGroceries().size()) {
            listItems.add(groceries.getGroceries().get(i));
            item++;
        }
    }
    //Done! now continue on the UI thread
            runOnUiThread(returnRes);
}

};

然后你的onCreate()方法看起来应该是这样的,并且数组传递给你的适配器:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_create_grocery_list);



    //add the footer before adding the adapter, else the footer will not load!
    View footerView = ((LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE))
            .inflate(R.layout.activity_footer_view, null, false);
    this.getListView().addFooterView(footerView);
    adapter = new ListViewAdapter(this,groceries);

    setListAdapter(adapter);
    getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
    //Here is where the magic happens
    this.getListView().setOnScrollListener(new OnScrollListener(){
        //useless here, skip!
        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {}
        //dumdumdum
        @Override
        public void onScroll(AbsListView view, int firstVisibleItem,
            int visibleItemCount, int totalItemCount) {
            //what is the bottom iten that is visible
            int lastInScreen = firstVisibleItem + visibleItemCount;
            //is the bottom item visible & not loading more already ? Load more !
            if((lastInScreen == totalItemCount) && !loadingMore && item < groceries.getGroceries().size()){
                Thread thread =  new Thread(null, loadMoreListItems);
                thread.start();
            }
        }
    });

}

您还需要一个删除方法来删除带有复选框和checkOff方法的项目。它们看起来像这样:

ArrayList<Integer> checkedBoxes = new ArrayList<Integer>();

ArrayList<HashMap<String,String>> checkedItems = new ArrayList<HashMap<String,String>>();

public void deleteItem(View view) {
      if (checkedBoxes.size() > 1 || checkedBoxes.size() == 0) {
          Toast.makeText(getApplicationContext(), "You can only delete one item at a time. Sorry :(", Toast.LENGTH_LONG).show();
          return;
      } else {

          checkedItems.add(groceries.getGroceries().get(checkedBoxes.get(0)));


          groceries.getGroceries().removeAll(checkedItems);
          checkedBoxes.clear();
          try {
              groceries.serialize();
          } catch (Exception e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }

          Intent intent = new Intent(getApplicationContext(),CreateGroceryList.class);
          startActivity(intent);

      }
}

public void checkOff(View view) {
    CheckBox box = (CheckBox)view;
    DataModel d = (DataModel)box.getTag();
    if(!checkedBoxes.contains(d.index)) {
        checkedBoxes.add(d.index);
    } else {
        checkedBoxes.remove((Integer)d.index);
    }
}

为了与适配器通信,有一个DataModel类可以为我们的信息建模。我的DataModel有一个索引变量来跟踪所选项目。

public class DataModel {
int index;
HashMap<String,String> data;
boolean selected;

public DataModel(int i) {
    index = i;
    data = new HashMap<String,String>();
    selected = false;
}

public HashMap<String, String> getData() {
    return data;
}

public void setData(HashMap<String, String> data) {
    this.data = data;
}

public boolean isSelected() {
    return selected;
}

public void setSelected(boolean selected) {
    this.selected = selected;
}

}

最后,这是BaseAdapter的代码:

    public class ListViewAdapter extends BaseAdapter {//To create an adapter we have to extend BaseAdapter instead of Activity, or whatever.

    private ListActivity activity;
    private View vi;
    private ArrayList<DataModel> data;
    private static LayoutInflater inflater=null;


    public ListViewAdapter(ListActivity a, GroceryList g) {
        activity = a;
        data = new ArrayList<DataModel>();
        inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        groceries = g;
    }



    public void add(HashMap<String,String> a){
        DataModel d = new DataModel(data.size());
        d.setData(a);
        d.setSelected(false);
        data.add(d);
    }

    public ArrayList<DataModel> getData() {
        return data;
    }

    public int getCount() {   //get the number of elements in the listview
        return data.size();
    }

    public Object getItem(int position) {   //this method returns on Object by position
        return position;
    }

    public long getItemId(int position) {   //get item id by position
        return position;
    }

    public View getView() {
        return vi;
    }

    public View getView(int position, View convertView, ViewGroup parent) {   //getView method is the method which populates the listview with our personalized rows
        vi=convertView;
        final ViewHolder holder = new ViewHolder();
        if(convertView==null) {
            vi = inflater.inflate(R.layout.custom_row_view, null);

        //every item in listview uses xml "listview_row"'s design 

            holder.name = (CheckBox)vi.findViewById(R.id.name);
            holder.price = (TextView)vi.findViewById(R.id.price);   // You can enter anything you want, buttons, radiobuttons, images, etc.
            holder.quantity = (TextView)vi.findViewById(R.id.quantity);
            holder.name
            .setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

                @Override
                public void onCheckedChanged(CompoundButton buttonView,
                    boolean isChecked) {
                  DataModel element = (DataModel) holder.name
                      .getTag();
                  element.setSelected(buttonView.isChecked());

                }
              });
            vi.setTag(holder);
            holder.name.setTag(data.get(position));
            ViewHolder vholder = (ViewHolder) vi.getTag();
            vholder.name.setChecked(data.get(position).isSelected());
            HashMap<String, String> hash = new HashMap<String, String>();  //We need a HashMap to store our data for any item
            hash = data.get(position).getData();
            vholder.name.setText(hash.get("brand") + " " + hash.get("name"));  //We personalize our row's items.
            vholder.price.setText("$" + hash.get("price"));
            vholder.quantity.setText("Quantity: " + hash.get("quantity"));
        } else {
            vi = convertView;
            ((ViewHolder) vi.getTag()).name.setTag(data.get(position));
        }

            if (holder.name == null) {
                ViewHolder vholder = (ViewHolder) vi.getTag();
                vholder.name.setChecked(data.get(position).isSelected());
                HashMap<String, String> hash = new HashMap<String, String>();  //We need a HashMap to store our data for any item
                hash = data.get(position).getData();
                vholder.name.setText(hash.get("brand") + " " + hash.get("name"));  //We personalize our row's items.
                vholder.price.setText("$" + hash.get("price"));
                vholder.quantity.setText("Quantity: " + hash.get("quantity"));

            }   

        return vi;  
    }
}

class ViewHolder {
    CheckBox name;
    TextView price;
    TextView quantity;
    public CheckBox getName() {
        return name;
    }
    public void setName(CheckBox name) {
        this.name = name;
    }
    public TextView getPrice() {
        return price;
    }
    public void setPrice(TextView price) {
        this.price = price;
    }
    public TextView getQuantity() {
        return quantity;
    }
    public void setQuantity(TextView quantity) {
        this.quantity = quantity;
    }

}

您的布局文件夹中还需要一些xml文件,它们的外观如下:

您需要一个页脚视图,告诉您的列表何时加载新项目:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:gravity="center_horizontal"
android:padding="3dp"
android:layout_height="fill_parent">
        <TextView
               android:id="@id/android:empty"
               android:layout_width="wrap_content"
               android:layout_height="fill_parent"
               android:gravity="center"
               android:padding="5dp"
               android:text="Add more grocery items..."/>

由BaseAdapter填充的自定义行视图:

  <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >



    <CheckBox
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="CheckBox"
        android:focusable="false"
        android:textSize="25dip"
        android:onClick="checkOff"
        />

    <TextView
        android:id="@+id/quantity"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="40dip"
        android:text="Lastname"
        android:textSize="15dip" />

    <TextView
        android:id="@+id/price"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="40dip"
        android:text="Lastname"
        android:textSize="15dip" />




</LinearLayout>

在父视图中,我的名字叫做create_grocery_list,因为我正在编写一个购物清单编辑器:这个编辑器必须包含一个具有正确id的ListView。

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="400dp" >

        <ListView
            android:id="@android:id/list"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1" >
        </ListView>

    </LinearLayout>

    <AbsoluteLayout
        android:layout_width="match_parent"
        android:layout_height="72dp" >

        <Button
            android:id="@+id/button2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_x="105dp"
            android:layout_y="0dp"
            android:onClick="deleteItem"
            android:text="@string/deleteItem" />

        <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_x="8dp"
            android:layout_y="0dp"
            android:onClick="goToAddItemScreen"
            android:text="@string/addItem" />

        <Button
            android:id="@+id/button3"
            style="?android:attr/buttonStyleSmall"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_x="221dp"
            android:layout_y="0dp"
            android:onClick="scanner"
            android:text="@string/scanCode" />
    </AbsoluteLayout>

</LinearLayout>

这就是它...希望这有助于任何人。这是你能找到的最完整的教程。

我从本教程中学到了所有这些:http://www.vogella.com/articles/AndroidListView/article.html#androidlists_overview然后添加了两个runnables来创建一个无休止的购物清单:)有趣的编程......