卡片式UI的總結 android
程式碼設計模組也是很簡單,通過一系列重要部件組成。我更加傾向於第一步先去建立介面卡,為ListView的初始化做好準備。我繼承了BaseAdapter,在getView方法裡填充列表專案的圖層, 初始化TextView的動作按鈕。 最核心部分是如何設定的各個按鈕的觸發器。因為介面卡是重複使用的,這很有可能使觸發器內嵌在介面卡裡,緊接著的專案肯定會使用相同的觸發器但使用不同的引數。在介面卡的邏輯裡,每個列表專案是由同一個檢視id構成,因此不可能知道當前id的檢視按鈕是對應哪個列表專案。
在這一點上,更為合適的方法是將實現移交給相關ListView的介面卡。為了這樣實現,我把View.OnClickListener放在我的介面卡的構造器中,在介面卡類中作為變數儲存,把按鈕觸發器作為一個例項。
下面是介面卡構造器和getView的實現:
[java] view plain copy print?- public CardsAdapter(Context context, List<String> items, OnClickListener itemButtonClickListener) {
- this.context = context;
- this.items = items;
- this.itemButtonClickListener = itemButtonClickListener;
- }
- @Override
- public
- ViewHolder holder;
- if (convertView == null) {
- convertView = LayoutInflater.from(context).inflate(R.layout.list_item_card, null);
- holder = new ViewHolder();
- holder.itemText = (TextView) convertView.findViewById(R.id.list_item_card_text);
- holder.itemButton1 = (Button) convertView.findViewById(R.id.list_item_card_button_1);
- holder.itemButton2 = (Button) convertView.findViewById(R.id.list_item_card_button_2);
- convertView.setTag(holder);
- } else {
- holder = (ViewHolder) convertView.getTag();
- }
- holder.itemText.setText(items.get(position));
- if (itemButtonClickListener != null) {
- holder.itemButton1.setOnClickListener(itemButtonClickListener);
- holder.itemButton2.setOnClickListener(itemButtonClickListener);
- }
- return convertView;
- }
public CardsAdapter(Context context, List<String> items, OnClickListener itemButtonClickListener) {
this.context = context;
this.items = items;
this.itemButtonClickListener = itemButtonClickListener;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.list_item_card, null);
holder = new ViewHolder();
holder.itemText = (TextView) convertView.findViewById(R.id.list_item_card_text);
holder.itemButton1 = (Button) convertView.findViewById(R.id.list_item_card_button_1);
holder.itemButton2 = (Button) convertView.findViewById(R.id.list_item_card_button_2);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.itemText.setText(items.get(position));
if (itemButtonClickListener != null) {
holder.itemButton1.setOnClickListener(itemButtonClickListener);
holder.itemButton2.setOnClickListener(itemButtonClickListener);
}
return convertView;
}
3:核心部分
在你選擇的Fragment或Activity中,我們在圖層裡填充ListView,以及初始化ListView例項並繫結介面卡。最後我們最關鍵的的地方是需要在介面卡新增觸發器,將會區分好所看到的專案按鈕。我們不需要關心不可見的列表專案因為它們在可見檢視視窗以外,我們不可能的點選的地方。
覆蓋View.OnClickListener的onClick方法時,我簡單地通過ListView中的getFirstVisiblePosition()和getLastVisiblePosition()遍歷所看到的專案,並檢查所點選的按鈕是否屬於現在所遍歷的專案。
private final class ListItemButtonClickListener implements OnClickListener {
@Override
public void onClick(View v) {
for (int i = cardsList.getFirstVisiblePosition(); i <= cardsList.getLastVisiblePosition(); i++) {
if (v == cardsList.getChildAt(i - cardsList.getFirstVisiblePosition()).findViewById(R.id.list_item_card_button_1)) {
// PERFORM AN ACTION WITH THE ITEM AT POSITION i
Toast.makeText(getActivity(), "Clicked on Left Button of List Item " + i, Toast.LENGTH_SHORT).show();
} else if (v == cardsList.getChildAt(i - cardsList.getFirstVisiblePosition()).findViewById(R.id.list_item_card_button_2)) {
// PERFORM ANOTHER ACTION WITH THE ITEM AT POSITION i
Toast.makeText(getActivity(), "Clicked on Right Button of List Item " + i, Toast.LENGTH_SHORT).show();
}
}
}
}
關鍵地方在於當ListView.getFirstVisiblePosition() 或 ListView.getLastVisiblePosition() 方法返回列表中索引, ListView.getChildAt 方法提供給我們的索引是可見裡的索引順序。例如如果FirstVisiblePosition為3,getChildAt(3)將會返回列表中第6個元素給我們。
總的來說,當我們需要在點選列表專案的具體內容時,可在ListView裡新增相關觸發器。(例如,跳轉到專案相關詳細的頁面)。