版權聲明:^_^ 尊重原創,共享知識,轉載請注明"_程式猿大人_"http://blog.csdn.net/a_running_wolf
我做了一些修改
手機螢幕畢竟有限,當我們要顯示較多資料時便不得不舍去一些次要資訊,将主要資訊優先顯示,也使顯示效果更加簡潔美觀。遇到類似的需求,我們使用最多的就是 ListView ,而如果每次點選一個 Item 都要跳轉到下一頁檢視詳情,檢視另一個還要傳回清單重新進入另一條詳情,使得操作繁瑣體驗降低。此時可隐藏和展開 Item 的 ListView 便應運而生,這不是一個新的控件,隻是我們靈活使用造出來的用法,下邊我就來實作 ListView 點選 Item 展開隐藏項,包括清單單項展開、多項展開、複雜布局展開的實作。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
一、單項展開
OneExpandActivity 中就是模拟一些資料,使用 OneExpandAdapter 擴充卡加載:
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
private void requestData() {
ArrayList<HashMap<String, String>> datas = new ArrayList<HashMap<String,String>>();
for(int i = 1; i <= 10; i++){
HashMap<String, String> item = new HashMap<String, String>();
item.put("phoneType", "HTC-M" + i + "");
item.put("discount", "9");
item.put("price", (2000 + i) + "");
item.put("time", "2016020" + i);
item.put("num", (300 - i) + "");
datas.add(item);
}
ListView lvProduct = (ListView) findViewById(R.id.lv_products);
OneExpandAdapter adapter = new OneExpandAdapter(this, datas);
lvProduct.setAdapter(adapter);
}
-------------------------------------------------------------------------------------------------------------------------------
Activity 的布局檔案就不看了,隻有一個 ListView。我們看 OneExpandAdapter.java:先看 Adapter 用到的布局樣式:
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- 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:background="@drawable/shape2"
- android:orientation="vertical" >
- <LinearLayout
- android:id="@+id/layout_showArea"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:padding="10dp" >
- <TextView
- android:id="@+id/tv_phoneType"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="HTC M8"
- android:textColor="#162834"
- android:textSize="25sp" />
- <TextView
- android:id="@+id/tv_discount"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginLeft="12dp"
- android:text="9"
- android:textColor="#F75252"
- android:textSize="15sp" />
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="折"
- android:textColor="#F75252"
- android:textSize="15sp" />
- <TextView
- android:id="@+id/tv_price"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginLeft="100dp"
- android:text="2000"
- android:textColor="#F75252"
- android:textSize="20sp" />
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="¥"
- android:textColor="#767171"
- android:textSize="15sp" />
- </LinearLayout>
- <RelativeLayout
- android:id="@+id/layout_hideArea"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:padding="10dp" >
- <TextView
- android:id="@+id/tv_timeNote"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignBottom="@+id/tv_time"
- android:text="活動截止時間:"
- android:textColor="#162834"
- android:textSize="12sp" />
- <TextView
- android:id="@+id/tv_time"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_toRightOf="@id/tv_timeNote"
- android:text="2016.02.10"
- android:textColor="#F09BED"
- android:textSize="15sp" />
- <TextView
- android:id="@+id/tv_numNote"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@id/tv_timeNote"
- android:layout_marginTop="10dp"
- android:text="庫存剩餘:"
- android:textColor="#162834"
- android:textSize="12sp" />
- <TextView
- android:id="@+id/tv_num"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignBottom="@id/tv_numNote"
- android:layout_below="@id/tv_time"
- android:layout_toRightOf="@id/tv_numNote"
- android:gravity="bottom"
- android:text="888"
- android:textColor="#F09BED"
- android:textSize="15sp" />
- <ImageView
- android:id="@+id/img_icon"
- android:layout_width="50dp"
- android:layout_height="50dp"
- android:layout_alignParentRight="true"
- android:src="@drawable/red_packet" />
- <Button
- android:id="@+id/btn_buy"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@id/tv_num"
- android:padding="4dp"
- android:textSize="24sp"
- android:layout_alignParentBottom="true"
- android:layout_centerHorizontal="true"
- android:background="@drawable/select_btn"
- android:text="立即搶購" />
- </RelativeLayout>
- </LinearLayout>
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
看 Adapter 的代碼(總體都還是正常用法,本次用到的邏輯都有注釋):
- public class OneExpandAdapter extends BaseAdapter {
- private Context context;
- private ArrayList<HashMap<String, String>> list;
- private int currentItem = -1; //用于記錄點選的 Item 的 position,是控制 item 展開的核心
- public OneExpandAdapter(Context context,
- ArrayList<HashMap<String, String>> list) {
- super();
- this.context = context;
- this.list = list;
- }
- @Override
- public int getCount() {
- return list.size();
- }
- @Override
- public Object getItem(int position) {
- return list.get(position);
- }
- @Override
- public long getItemId(int position) {
- return position;
- }
- @Override
- public View getView(final int position, View convertView, ViewGroup parent) {
- ViewHolder holder = null;
- if (convertView == null) {
- convertView = LayoutInflater.from(context).inflate(
- R.layout.item_2, parent, false);
- holder = new ViewHolder();
- holder.showArea = (LinearLayout) convertView.findViewById(R.id.layout_showArea);
- holder.tvPhoneType = (TextView) convertView
- .findViewById(R.id.tv_phoneType);
- holder.tvDiscount = (TextView) convertView
- .findViewById(R.id.tv_discount);
- holder.tvPrice = (TextView) convertView
- .findViewById(R.id.tv_price);
- holder.tvTime = (TextView) convertView
- .findViewById(R.id.tv_time);
- holder.tvNum = (TextView) convertView
- .findViewById(R.id.tv_num);
- holder.btnBuy = (Button) convertView
- .findViewById(R.id.btn_buy);
- holder.hideArea = (RelativeLayout) convertView.findViewById(R.id.layout_hideArea);
- convertView.setTag(holder);
- } else {
- holder = (ViewHolder) convertView.getTag();
- }
- HashMap<String, String> item = list.get(position);
- // 注意:我們在此給響應點選事件的區域(我的例子裡是 showArea 的線性布局)添加Tag,為了記錄點選的 position,我們正好用 position 設定 Tag
- holder.showArea.setTag(position);
- holder.tvPhoneType.setText(item.get("phoneType"));
- holder.tvDiscount.setText(item.get("discount"));
- holder.tvPrice.setText(item.get("price"));
- holder.tvTime.setText(item.get("time"));
- holder.tvNum.setText(item.get("num"));
- //根據 currentItem 記錄的點選位置來設定"對應Item"的可見性(在list依次加載清單資料時,每加載一個時都看一下是不是需改變可見性的那一條)
- if (currentItem == position) {
- holder.hideArea.setVisibility(View.VISIBLE);
- } else {
- holder.hideArea.setVisibility(View.GONE);
- }
- holder.showArea.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View view) {
- //用 currentItem 記錄點選位置
- int tag = (Integer) view.getTag();
- if (tag == currentItem) { //再次點選
- currentItem = -1; //給 currentItem 一個無效值
- } else {
- currentItem = tag;
- }
- //通知adapter資料改變需要重新加載
- notifyDataSetChanged(); //必須有的一步
- }
- });
- holder.tvPhoneType.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View view) {
- Toast.makeText(context, "hehe", Toast.LENGTH_SHORT).show();
- }
- });
- return convertView;
- }
- private static class ViewHolder {
- private LinearLayout showArea;
- private TextView tvPhoneType;
- private TextView tvDiscount;
- private TextView tvPrice;
- private TextView tvTime;
- private TextView tvNum;
- private Button btnBuy;
- private RelativeLayout hideArea;
- }
- }
我們隻是 給特定元件 setTag(int position),根據點選的 View 記錄下這個 position,在 getView() 中判斷目前加載 View 是 position 是不是和記錄的 position 相等來進行特定元件的可見性設定 即可。
這裡我們需要明白:我們平時對 ListView 做的最多的操作就是 setOnItemClickListener,這個操作一般都是在 Activity 中進行的,此時響應區域是 Item 整體,不管你點選 Item 的哪個角落都會響應。而對于每個 Item 中子控件的事件監聽(差別于整個Item,比如說 Item 中的按鈕、輸入框等等)都是在擴充卡類中添加,此時隻有點選添加監聽的子控件區域才會響應,相當于每個 Item 中的該控件都添加了監聽。OnClick 的響應優先級:子控件(元控件)> 父布局(但是不像 onTouch 事件有 Boolean 傳回值那樣,OnClick 事件是沒有傳回值的,即是“阻斷式式響應”,不會再響應它所歸屬的上層控件)。
就不一一的列代碼了,多項展開,表格展開的下載下傳位址:http://download.csdn.net/detail/zhanghuaiwang/9912624