首先刚到北京一个月,产品经理让做一个类似于商城的东东,起初感觉没什么难度,(不就一个电子商务app嘛,以前也做过啊),但是当看到有需求是这样的
然后就开始做,起初太懒了,就在网上找,找到了一个ListView嵌套ListView的一哥们的讲解的大致思路的,然后根据那哥们的思路自己写了一个demo,感觉效果还挺好,不卡,
第一种实现方式:这种方式有个问题就像我项目中的问题,子列中的值如果是加减变化的,对应的每个父类的item的总价格会动态变化的话用此方式就会出现一定的问题,如果不需要实现像我项目图中的实现的方式的话可以考虑该方法,上个图看看
主要点就是:设置父类和子类的ListView的宽高都为fill_parent,这样ListView在滚动的时候就不会重新计算高度,保证滑动的流畅性
咱先看看ListView嵌套ListView应该怎样实现这个功能:
首先我存储了一段json数组,便于实现功能:
{ flag: true, message: "10000123", result: [ { createtime: "2015-08-27 10:00:00", ddaddress: "东北旺南路28号", ddarea: "东城区", ddcity: "北京市", ddhouseId: 133, ddhouseName: "北京主库房", ddoperator: "陈文东", ddoperatorphone: "13810095764", ddprovince: "", faddress: "北京市东城区东北旺南路28号", id: 10000129, orderDetailVoList: [ { faddress: "北京市东城区东北旺南路28号", goodsname: "罗技(Logitech)MK220 无线光电键鼠套装", goodspicurl: "http://static.dingdong.com.cn/img/4e78376b-c465-4e91-98dd-afb57a71af13.jpg", goodssum: 30, id: 201508261807445660, price: 90, totalmoney: 0.01 }, { faddress: "北京市东城区东北旺南路28号", goodsname: "罗技(Logitech)MK220 无线光电键鼠套装", goodspicurl: "http://static.dingdong.com.cn/img/4e78376b-c465-4e91-98dd-afb57a71af13.jpg", goodssum: 30, id: 201508261227116540, price: 90, totalmoney: 2700 }, { faddress: "北京市东城区东北旺南路28号", goodsname: "罗技(Logitech)MK120 键鼠套装", goodspicurl: "http://static.dingdong.com.cn/img/40fda34a-aa06-430f-bcb8-e2f24854bd7f.jpg", goodssum: 50, id: 201508261747296800, price: 69, totalmoney: 0.01 }, { faddress: "北京市东城区东北旺南路28号", goodsname: "TP-LINK TL-WR886N 450M无线路由器", goodspicurl: "http://static.dingdong.com.cn/img/6ec91287-fdc6-48e2-9730-8f432414640b.jpg", goodssum: 50, id: 201508261747293800, price: 89, totalmoney: 0.01 }, { faddress: "北京市东城区东北旺南路28号", goodsname: "罗技(Logitech) B175 商用无线鼠标", goodspicurl: "http://static.dingdong.com.cn/img/201a96a1-dac7-4100-bdc3-5d2a64e14138.jpg", goodssum: 50, id: 201508261805522020, price: 59, totalmoney: 0.01 }, { faddress: "北京市东城区东北旺南路28号", goodsname: "TP-LINK TL-WR886N 450M无线路由器", goodspicurl: "http://static.dingdong.com.cn/img/6ec91287-fdc6-48e2-9730-8f432414640b.jpg", goodssum: 50, id: 201508261227115650, price: 89, totalmoney: 4450 } ], purchasemoney: 13380.04, type: 2 }, { createtime: "2015-08-27 10:00:00", ddaddress: "东北旺南路28号", ddarea: "东城区", ddcity: "北京市", ddhouseId: 133, ddhouseName: "北京主库房", ddoperator: "陈文东", ddoperatorphone: "13810095764", ddprovince: "", faddress: "北京市东城区东北旺南路28号", id: 10000128, orderDetailVoList: [ { faddress: "北京市东城区东北旺南路28号", goodsname: "腾达(Tenda)N318无线路由器穿墙王300MN318无线路由器穿墙王300MN318无线路由器穿墙王300M", goodspicurl: "http://static.dingdong.com.cn/img/44f384cb-a934-482a-8524-24aa6d34c0e7.jpg", goodssum: 50, id: 201508261227115870, price: 44, totalmoney: 2200 } ], purchasemoney: 2200, type: 2 }, { createtime: "2015-08-27 10:00:00", ddaddress: "东北旺南路28号", ddarea: "东城区", ddcity: "北京市", ddhouseId: 133, ddhouseName: "北京主库房", ddoperator: "陈文东", ddoperatorphone: "13810095764", ddprovince: "", faddress: "北京市东城区东北旺南路28号", id: 10000123, orderDetailVoList: [ { faddress: "北京市东城区东北旺南路28号", goodsname: "罗技(Logitech)MK220 无线光电键鼠套装", goodspicurl: "http://static.dingdong.com.cn/img/4e78376b-c465-4e91-98dd-afb57a71af13.jpg", goodssum: 30, id: 201508261807445660, price: 90, totalmoney: 0.01 }, { faddress: "北京市东城区东北旺南路28号", goodsname: "TP-LINK TL-WDR5600 900M无线路由器", goodspicurl: "http://static.dingdong.com.cn/img/948fc3f3-bcb0-4743-8727-06249fa497e4.jpg", goodssum: 20, id: 201508261548064700, price: 139, totalmoney: 2780 }, { faddress: "北京市东城区东北旺南路28号", goodsname: "罗技(Logitech)MK120 键鼠套装", goodspicurl: "http://static.dingdong.com.cn/img/40fda34a-aa06-430f-bcb8-e2f24854bd7f.jpg", goodssum: 50, id: 201508261420353150, price: 69, totalmoney: 3450 }, { faddress: "北京市东城区东北旺南路28号", goodsname: "罗技(Logitech)MK220 无线光电键鼠套装", goodspicurl: "http://static.dingdong.com.cn/img/4e78376b-c465-4e91-98dd-afb57a71af13.jpg", goodssum: 30, id: 201508261227116540, price: 90, totalmoney: 2700 }, { faddress: "北京市东城区东北旺南路28号", goodsname: "罗技(Logitech)MK120 键鼠套装", goodspicurl: "http://static.dingdong.com.cn/img/40fda34a-aa06-430f-bcb8-e2f24854bd7f.jpg", goodssum: 50, id: 201508261747296800, price: 69, totalmoney: 0.01 }, { faddress: "北京市东城区东北旺南路28号", goodsname: "TP-LINK TL-WR886N 450M无线路由器", goodspicurl: "http://static.dingdong.com.cn/img/6ec91287-fdc6-48e2-9730-8f432414640b.jpg", goodssum: 50, id: 201508261747293800, price: 89, totalmoney: 0.01 }, { faddress: "北京市东城区东北旺南路28号", goodsname: "罗技(Logitech) B175 商用无线鼠标", goodspicurl: "http://static.dingdong.com.cn/img/201a96a1-dac7-4100-bdc3-5d2a64e14138.jpg", goodssum: 50, id: 201508261805522020, price: 59, totalmoney: 0.01 }, { faddress: "北京市东城区东北旺南路28号", goodsname: "TP-LINK TL-WR886N 450M无线路由器", goodspicurl: "http://static.dingdong.com.cn/img/6ec91287-fdc6-48e2-9730-8f432414640b.jpg", goodssum: 50, id: 201508261227115650, price: 89, totalmoney: 4450 } ], purchasemoney: 13380.04, type: 2 } ], state: true, status: 1 }
接着我们需要一个Activity:
package com.zl.listview;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.Toast;
import com.kjy.kjylistview.R;
public class QianTaoListviewActivity extends Activity {
private ListView listView;
private ArrayList<HashMap<String, Object>> parentList, childList;
private ParentAdapter parentAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_qiantao);
init();
}
private void init() {
listView = (ListView) findViewById(R.id.qiantao_lv);
getHttpMessage();
}
public void getHttpMessage(){
GetMessageControl getMessageControl = new GetMessageControl(handler, getApplicationContext());
try {
getMessageControl.setHttpMsg();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
List<PurOrderBean> listBeans = (List<PurOrderBean>)msg.obj;
parentAdapter = new ParentAdapter(listBeans, QianTaoListviewActivity.this);
listView.setAdapter(parentAdapter);
};
};
}
然后我们需要解析存储在res/raw中的json字符:
package com.zl.listview;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.util.LinkedList;
import java.util.List;
import com.base.utils.HandlerParse;
import com.google.gson.Gson;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
import com.kjy.kjylistview.R;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
/**
* @author wangkai
*
*/
public class GetMessageControl {
Handler handler;
private List<PurOrderBean> listBeans;
private Context context;
public GetMessageControl(Handler handler, Context context) {
this.handler = handler;
this.context = context;
}
public void setHttpMsg() throws Exception{
InputStream is = context.getResources().openRawResource(R.raw.json);
byte[] buffer;
buffer = new byte[is.available()];
is.read(buffer);
//将字节数组转换为以GB2312编码的字符串
String json = new String(buffer, "utf-8");
Type listType = new TypeToken<LinkedList<PurOrderBean>>(){}.getType();
Gson gson = new Gson();
JsonParser jsonparer = new JsonParser();
listBeans = gson.fromJson(jsonparer.parse(json.toString()).getAsJsonObject().get("result"), listType);
for (PurOrderBean bean : listBeans) {
System.out.println("bean======" + bean);
}
Message msg = Message.obtain();
msg.obj = listBeans;
msg.what = HandlerParse.HTTP_SUCCESS;
handler.sendMessage(msg);
}
}
然后我们需要两个Adapter:
首先是父类的Adapter:
package com.zl.listview;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ListAdapter;
import android.widget.TextView;
import com.kjy.kjylistview.R;
public class ParentAdapter extends BaseAdapter implements ListAdapter {
private List<PurOrderBean> list;
private Context context;
private LayoutInflater inflater;
private ChildAdapter daAdapter;
public ParentAdapter(List<PurOrderBean> list, Context context) {
super();
this.list = list;
this.context = context;
daAdapter = new ChildAdapter(context);
this.inflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return list.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ChildListViewItem childListViewItem = null;
if (convertView == null) {
childListViewItem = new ChildListViewItem();
convertView = inflater.inflate(R.layout.parentitem, null, false);
childListViewItem.text_caigou = (TextView) convertView.findViewById(R.id.text_caigou);
childListViewItem.child_item_img = (TextView) convertView.findViewById(R.id.text_caigou);
childListViewItem.child_item_title = (TextView) convertView.findViewById(R.id.shouhuoren_text);
childListViewItem.parent_lv = (ChildLiistView) convertView.findViewById(R.id.parent_lv);
childListViewItem.callphone_text = (TextView) convertView.findViewById(R.id.callphone_text);
childListViewItem.shouhuodizhi_text = (TextView) convertView.findViewById(R.id.shouhuodizhi_text);
convertView.setTag(childListViewItem);
} else {
childListViewItem = (ChildListViewItem) convertView.getTag();
}
childListViewItem.text_caigou.setText(list.get(position).getId()+"");
childListViewItem.child_item_title.setText(list.get(position).getDdoperator());
childListViewItem.callphone_text.setText(list.get(position).getDdoperatorphone());
String address = list.get(position).getDdprovince() + list.get(position).getDdcity() + list.get(position).getDdarea() + list.get(position).getDdaddress();
childListViewItem.shouhuodizhi_text.setText(address);
final Button bt_jz = (Button) convertView.findViewById(R.id.button_add);
int z = ((List<ItemGoodsBean>)list.get(position).getBeanGoodsList()).size();
// if (z <= 2) {
bt_jz.setVisibility(View.GONE);
daAdapter.addAll(((List<ItemGoodsBean>)list.get(position).getBeanGoodsList()));
childListViewItem.parent_lv.setAdapter(daAdapter);
bt_jz.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
bt_jz.setVisibility(View.GONE);
daAdapter.addAll(((List<ItemGoodsBean>) list.get(position).getBeanGoodsList()));
}
});
childListViewItem.parent_lv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
Intent intent = new Intent(context, Activity_2.class);
context.startActivity(intent);
}
});
return convertView;
}
public class ChildListViewItem {
TextView text_caigou;
TextView child_item_title, shouhuodizhi_text,
callphone_text;
TextView child_item_img;
ChildLiistView parent_lv;
}
}
其次是子类的Adapter:
package com.zl.listview;
import java.util.List;
import android.content.Context;
import android.graphics.Paint;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.eegets.peter.enclosure.network.bitmap.abitmap.AWonderBitmap;
import com.kjy.kjylistview.R;
public class ChildAdapter extends BaseAdapter {
private List<ItemGoodsBean> list;
private Context context;
private LayoutInflater inflater;
private AWonderBitmap aWonderBitmap;
public ChildAdapter(Context context) {
super();
this.context = context;
aWonderBitmap = AWonderBitmap.create(context);
}
public void addAll(List<ItemGoodsBean> list) {
this.list=list;
notifyDataSetChanged();
}
public void clearAll() {
this.list.clear();
notifyDataSetChanged();
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return list.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ParentListItem parentListItem = null;
if (convertView == null) {
parentListItem = new ParentListItem();
inflater = LayoutInflater.from(context);
convertView = inflater.inflate(R.layout.sssssss, null, false);
parentListItem.exhibit_item_icon = (ImageView) convertView .findViewById(R.id.exhibit_item_icon);
parentListItem.text_name = (TextView) convertView .findViewById(R.id.text_name);
parentListItem.text_count = (TextView) convertView .findViewById(R.id.text_count);
parentListItem.text_price = (TextView) convertView .findViewById(R.id.text_price);
convertView.setTag(parentListItem);
} else {
parentListItem = (ParentListItem) convertView.getTag();
}
parentListItem.text_name.setText(list.get(position).getGoodsname());
parentListItem.text_count.setText(list.get(position).getGoodssum()+"");
parentListItem.text_price.setText(list.get(position).getPrice()+"");
parentListItem.text_price.getPaint() .setFlags(Paint.STRIKE_THRU_TEXT_FLAG | Paint.ANTI_ALIAS_FLAG);
aWonderBitmap.display(parentListItem.exhibit_item_icon, list.get(position).getGoodspicurl());
return convertView;
}
public class ParentListItem {
ImageView exhibit_item_icon;
TextView text_name, text_count, text_price;
}
}
然后我们需要一个我们重写的ListView,为的是设置Listview的固定高度:
package com.zl.listview;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ListView;
public class ChildLiistView extends ListView {
public ChildLiistView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public ChildLiistView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
public ChildLiistView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
然后是我们父类和子类的两个xml:
parentitem.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" > <LinearLayout android:id="@+id/rela_caigou" android:layout_width="fill_parent" android:layout_height="wrap_content" > <ImageView android:id="@+id/img_caigou" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_margin="10dp" android:background="@drawable/icon_order" /> <TextView android:id="@+id/text_caigou" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:lines="1" android:text="采购单:112312ssssss1" android:textSize="15dp" /> <RelativeLayout android:id="@+id/rela_qianggou_time" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="right" > <ImageView android:id="@+id/img_qianggou_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginBottom="10dp" android:layout_marginTop="10dp" android:background="@drawable/icon_clock" /> <TextView android:id="@+id/text_qianggou_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_toRightOf="@+id/img_qianggou_time" android:text="20min后失效" android:textSize="13sp" /> </RelativeLayout> </LinearLayout> <View android:id="@+id/view_line" android:layout_width="fill_parent" android:layout_height="1dp" android:layout_below="@+id/rela_caigou" android:background="#BFBFBF" /> <RelativeLayout android:id="@+id/rela_shouhuo_sss" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/view_line" android:layout_marginBottom="10dp" android:layout_marginTop="10dp" > <RelativeLayout android:id="@+id/rela_shouhuo_time" android:layout_width="wrap_content" android:layout_height="wrap_content" > <ImageView android:id="@+id/img_shouhuoren" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_margin="10dp" android:background="@drawable/icon_people" /> <TextView android:id="@+id/shouhuoren_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@id/img_shouhuoren" android:layout_marginBottom="10dp" android:layout_marginTop="10dp" android:layout_toRightOf="@id/img_shouhuoren" android:textSize="13sp" /> <ImageView android:id="@+id/img_callphone" android:layout_width="15dp" android:layout_height="15dp" android:layout_below="@+id/shouhuoren_text" android:layout_gravity="center_vertical" android:layout_margin="10dp" android:background="@drawable/icon_phone" /> <TextView android:id="@+id/callphone_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/shouhuoren_text" android:layout_marginBottom="10dp" android:layout_marginTop="10dp" android:layout_toRightOf="@+id/img_callphone" android:textSize="13sp" /> <ImageView android:id="@+id/img_shouhuoaddress" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/callphone_text" android:layout_gravity="center_vertical" android:layout_margin="10dp" android:background="@drawable/icon_place" /> <TextView android:id="@+id/shouhuodizhi_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@id/img_shouhuoaddress" android:layout_below="@id/callphone_text" android:layout_marginBottom="10dp" android:layout_marginTop="10dp" android:layout_toRightOf="@id/img_shouhuoaddress" android:textSize="13sp" /> </RelativeLayout> <!-- <ImageView android:id="@+id/shouhuoren_phone" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight="10dp" android:background="@drawable/shouhuoren_phone" /> --> </RelativeLayout> <com.zl.listview.ChildLiistView android:id="@+id/parent_lv" android:layout_width="fill_parent" android:layout_height="fill_parent" android:cacheColorHint="#00000000" android:divider="#e8e8e8" android:dividerHeight="1dp" android:fadingEdge="none" android:listSelector="@android:color/transparent" android:scrollbars="none" android:scrollingCache="false" > </com.zl.listview.ChildLiistView> <View android:id="@+id/view_line1" android:layout_width="fill_parent" android:layout_height="1dp" android:layout_below="@+id/parent_lv" android:background="#BFBFBF" /> <Button android:id="@+id/button_add" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_below="@+id/view_line1" android:text="添加" /> </LinearLayout>
子类的xml:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="#f9f9f9" android:orientation="vertical" > <ImageView android:id="@+id/exhibit_item_icon" android:layout_width="80dip" android:layout_height="80dip" android:layout_centerVertical="true" android:layout_margin="10dip" android:background="@drawable/ic_launcher" /> <RelativeLayout android:id="@+id/rel_right" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginRight="5dp" android:layout_marginTop="10dp" android:layout_toRightOf="@+id/exhibit_item_icon" > <TextView android:id="@+id/text_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:lines="2" android:text="轻轻巧巧轻轻巧巧轻轻巧巧轻轻巧巧轻轻巧巧轻轻巧巧轻轻巧巧轻轻巧巧轻轻巧巧轻轻巧巧" android:textColor="@android:color/black" android:textSize="15dp" /> <RelativeLayout android:id="@+id/rel_right_right" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_below="@+id/text_name" android:layout_marginTop="10dp" > <TextView android:id="@+id/text_count" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingTop="5dp" android:scaleType="centerInside" android:text="×100" /> <TextView android:id="@+id/text_price" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:paddingTop="5dp" android:text="¥12201" android:textSize="13dp" /> </RelativeLayout> </RelativeLayout> </RelativeLayout>
具体用到的一些jar包以及xml都在demo中,下载地址在最后~~~~~~~~~~~~~~~
具体的代码下载地址:http://download.csdn.net/detail/wangkai1101/9088931
第二种方法实现方式是重写一个ListView来实现效果的,效果非常好,能实现任意方式。第二种方式近期也会上传到csdn上~~~