編輯:關於android開發
首先,眾所周知,ListView是Android最常用的控件,可以說是最簡單的控件,也可以說是最復雜的控件。
作為一個Android初級開發者,可能會簡單的ListView展示圖文信息。
作為一個有一定項目開發經驗的Android開發者來說,可能會遇到ListView的列表項中存在各種按鈕的需求。
需求最多的就是購物車功能。想必大家都用過某寶某東客戶端APP吧 ,就是那個購物車的功能。

-------------------------------------------------------------------------------------------------------------
曾經做過購物車功能,今天項目需求也用到了差不多效果的購物車功能,剛好園友問了這個問題,便幫忙解答了。
之後,想了想還是寫一下關於購物車效果的博客吧。
--------------------------------------------------------------------------------------------------------------
那麼現在就學習一下購物車功能的實現原理
首先讓我們分析下實現購物車功能需要解決的問題:
1、在哪裡處理按鈕的點擊響應事件,是適配器 還是 Activity或者Fragment
2、如何知道你點擊的按鈕是哪一個列表項中的
3、點擊某個按鈕的時候,如果列表項所需的數據改變了,如何更新UI
4、列表項中存在會獲取焦點的各種按鈕,會導致列表項無法點擊,只能點擊按鈕,這種情況怎麼解決
首先,我們必須要了解:
1、自定義適配器,不會的看下博客:安卓開發_淺談ListView(自定義適配器)
2、接口回調,不會接口回調的可以看下博客:Android接口回調機制
一個ListView數據展示的實現,必須要有的 自定義適配器,數據源,ListView,列表項布局
做一個Demo,看下效果
(1)、效果一,點擊商品添加刪除數量,後面的商品總價隨之變化

(2)、效果二,一個列表項發生變化,滑出界面,在滑回來,該列表項的數據依然存在,列表項的復用不存在問題

一、創建布局文件
1、主布局

2、列表項布局

這裡解決問題:列表項中存在會獲取焦點的各種按鈕,會導致列表項無法點擊,只能點擊按鈕,這種情況怎麼解決
解決方法,在item列表項布局的最外層父容器中 設置一個屬性:
android:descendantFocusability="blocksDescendants"

二、創建實體類
看上圖,只需要三個屬性,名稱,總價格,數量

三、創建適配器(關鍵!!)
1、創建適配器成員變量
//集合 ,存放ListView的商品實體類數據
private List<Product> products;
//上下文
private Context context;
//第一步,設置接口
private View.OnClickListener onAddNum; //加商品數量接口
private View.OnClickListener onSubNum; //減商品數量接口
接口看你具體需求,我這裡是ImageButton ,所以是 View.OnClickListener
具體看情況,舉三個列子,當然還有很多接口,比如單選按鈕的

2、創建構造方法:
public ShopAdapter(List<Product> products, Context context) {
this.products = products;
this.context = context;
}
3、創建接口方法
public void setOnAddNum(View.OnClickListener onAddNum){
this.onAddNum = onAddNum;
}
public void setOnSubNum(View.OnClickListener onSubNum){
this.onSubNum = onSubNum;
}
4、重寫自定義適配器的除了getView()的三個方法
@Override
public int getCount() {
int ret = 0;
if (products != null) {
ret = products.size();
}
return ret;
}
@Override
public Object getItem(int i) {
return products.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
5、接下來就是重點了
定義內部類
private static class ViewHolder{
//商品名稱,數量,總價
private TextView item_product_name;
private TextView item_product_num;
private TextView item_product_price;
//增減商品數量按鈕
private ImageButton item_btn_add;
private ImageButton item_btn_sub;
}
重寫最重要的getView()方法,主要看紅色顏色部分
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
View v = null;
if (view != null) {
v = view;
}else{
v = LayoutInflater.from(context).inflate(R.layout.item_cart,viewGroup,false);
}
ViewHolder holder = (ViewHolder) v.getTag();
if (holder == null) {
holder = new ViewHolder();
holder.item_product_name = (TextView) v.findViewById(R.id.item_product_name);
holder.item_product_num = (TextView) v.findViewById(R.id.item_product_num);
holder.item_product_price = (TextView) v.findViewById(R.id.item_product_price);
//設置接口回調,注意參數不是上下文,它需要ListView所在的Activity或者Fragment處理接口回調方法
holder.item_btn_add = (ImageButton) v.findViewById(R.id.item_btn_add);
holder.item_btn_add.setOnClickListener(onAddNum);
holder.item_btn_sub = (ImageButton) v.findViewById(R.id.item_btn_sub);
holder.item_btn_sub.setOnClickListener(onSubNum);
}
holder.item_product_name.setText(products.get(i).getName());
holder.item_product_num.setText(products.get(i).getNum()+"");
holder.item_product_price.setText(products.get(i).getPrice() + "");
//設置Tag,用於判斷用戶當前點擊的哪一個列表項的按鈕,解決問題:如何知道你點擊的按鈕是哪一個列表項中的
holder.item_btn_add.setTag(i);
holder.item_btn_sub.setTag(i);
v.setTag(holder);
return v;
}
至此,自定義適配器部分完成了。
適配器完整代碼:

四、主Activity
public class MainActivity extends Activity implements View.OnClickListener, AdapterView.OnItemClickListener {
private List<Product> datas; //數據源
private ShopAdapter adapter; //自定義適配器
private ListView listView; //ListView控件
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
listView = (ListView) findViewById(R.id.listView);
// 模擬數據
datas = new ArrayList<Product>();
Product product = null;
for (int i = 0; i < 30; i++) {
product = new Product();
product.setName("商品:"+i+":單價:"+i);
product.setNum(1);
product.setPrice(i);
datas.add(product);
}
adapter = new ShopAdapter(datas,this);
listView.setAdapter(adapter);
//以上就是我們常用的自定義適配器ListView展示數據的方法了
//解決問題:在哪裡處理按鈕的點擊響應事件,是適配器 還是 Activity或者Fragment,這裡是在Activity本身處理接口
//執行添加商品數量,減少商品數量的按鈕點擊事件接口回調
adapter.setOnAddNum(this);
adapter.setOnSubNum(this);
listView.setOnItemClickListener(this);
}
//
3、點擊某個按鈕的時候,如果列表項所需的數據改變了,如何更新UI
@Override
public void onClick(View view) {
Object tag = view.getTag();
switch (view.getId()){
case R.id.item_btn_add: //點擊添加數量按鈕,執行相應的處理
// 獲取 Adapter 中設置的 Tag
if (tag != null && tag instanceof Integer) { //解決問題:如何知道你點擊的按鈕是哪一個列表項中的,通過Tag的position
int position = (Integer) tag;
//更改集合的數據
int num = datas.get(position).getNum();
num++;
datas.get(position).setNum(num); //修改集合中商品數量
datas.get(position).setPrice(position*num); //修改集合中該商品總價 數量*單價
//解決問題:點擊某個按鈕的時候,如果列表項所需的數據改變了,如何更新UI
adapter.notifyDataSetChanged();
}
break;
case R.id.item_btn_sub: //點擊減少數量按鈕 ,執行相應的處理
// 獲取 Adapter 中設置的 Tag
if (tag != null && tag instanceof Integer) {
int position = (Integer) tag;
//更改集合的數據
int num = datas.get(position).getNum();
if (num>0) {
num--;
datas.get(position).setNum(num); //修改集合中商品數量
datas.get(position).setPrice(position * num); //修改集合中該商品總價 數量*單價
adapter.notifyDataSetChanged();
}
}
break;
}
}
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Toast.makeText(MainActivity.this,"點擊了第"+i+"個列表項",Toast.LENGTH_SHORT).show();
}
}
----------------------------------------------------------------------------------------------------
總結下:
1、有人說列表項中最好不要用ImageButton,而盡可能的用ImageView替代,目前沒有發現使用ImageButton會發生什麼錯誤
2、有人說列表項中 解決焦點問題需要兩步:
(1)、最外層父容器需要加屬性:
android:descendantFocusability="blocksDescendants"
(2)、能獲取焦點的控件,Button,ImageButton等等 需要 有屬性:android:focusable="false"
但是我實際測試 發現子空間不需要設置focusable屬性也不會產生問題,當然加上也沒有問題
3、沒有做過列表項中存在EditText控件的情況,可能會有焦點沖突。畢竟購物車中加一個編輯框也很少見
最後,一個實際的購物車,當然還需要顯示當前的總金額,包含“去結算”按鈕的功能的那一個框,這不屬於ListView
如圖:

那麼怎麼處理當你操作列表項中的按鈕,不僅列表項中的數據發生變哈,而且不屬於列表項的下面部分的“合計”數據也發生變化呢,
這就要學習Adapter中觀察者模式的應用 了。
---------------------------------------------------------------------------------------------
以上內容,如有錯誤,歡迎指出!
Android draw9patch 圖片制作與使用,
Android draw9patch 圖片制作與使用,理解一下4句話: 下面我拿6張圖片分別舉例說明: 1.QQ多彩氣泡 聊天對話框也用.9
百度地圖可視化定位效果,可以輸入目的地定位。,可視化目的地
百度地圖可視化定位效果,可以輸入目的地定位。,可視化目的地登錄百度開發者帳號後下載sdk導入自己的工程中。 代碼如下: 1 package com.lixu.bai
Android自定義View入門(一),androidview
Android自定義View入門(一),androidview最近在寫一個關於音樂播放的應用,寫到播放界面UI時,就想自己實現的一個播放界面。那麼如何實現自定義View呢
Android提高21篇之七:XML解析與生成
本文使用SAX來解析XML,在Android裡面可以使用SAX和DOM,DOM需要把整個XML文件