无论是什么项目都少不了列表的功能,在web页中有各种各样的的gride,在android中经常用到的是ListView,它是一个容器,以列表的形式展示具体内容,并且能够根据数据的长度自适应显示。需要我们做的是在另外的xml页面中设计好要显示的列表样式,在ListView的java类中加载之后即可!废话不多说,贴代码来一一介绍!
首先是ListView的布局页面,这里重要的是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:id="@+id/search_top_layout"
style="@style/top_title_style" >
<ImageView
android:id="@+id/search_top_logo"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_gravity="center_vertical"
android:layout_margin="5dp"
android:focusableInTouchMode="true"
android:imeOptions="actionSearch"
android:src="@drawable/search_return_button" />
<EditText
android:id="@+id/search_search_edit"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:background="@drawable/main_search_box"
android:hint="搜索文字"
android:padding="6dp"
android:textColor="@color/darkgray"
android:textSize="12sp" />
<EditText
android:id="@+id/search_button"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_margin="5dp"
android:text="筛选"
android:paddingLeft="10dp"
android:paddingRight="10dp" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="45dp"
android:background="@color/whitesmoke" >
<!--小吃类 -->
<LinearLayout
android:id="@+id/channel1"
style="@style/main_tab_but_linear" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="小吃类" />
</LinearLayout>
<!-- 价格 -->
<LinearLayout
android:id="@+id/channel2"
style="@style/main_tab_but_linear" >
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="价格|" />
</LinearLayout>
<!-- 销量 -->
<LinearLayout
android:id="@+id/channel3"
style="@style/main_tab_but_linear"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:orientation="vertical" >
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="销量|" />
</LinearLayout>
<!-- 商品-->
<LinearLayout
android:id="@+id/channel4"
style="@style/main_tab_but_linear"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:orientation="vertical" >
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="商品" />
</LinearLayout>
</LinearLayout>
<ListView
android:id="@+id/product_class_listview"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:divider="#808080">
</ListView>
</LinearLayout>
再有就是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_height="wrap_content"
android:layout_width="wrap_content"
android:paddingTop="10dp" >
<ImageView
android:id="@+id/search_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="10dp"
android:src="@drawable/catergory_mobile" />
<LinearLayout
android:id="@+id/relativeLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:layout_marginLeft="50dp"
android:layout_toRightOf="@+id/catergory_image"
android:orientation="vertical"
>
<TextView
android:id="@+id/search_item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="华为荣耀 手机"
android:textColor="@color/black"
android:textSize="12sp" />
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:paddingTop="5dp" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="¥"
android:textColor="@color/logoColor"
android:textSize="20sp" />
<TextView
android:id="@+id/search_item_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="450"
android:textColor="@color/logoColor"
android:textSize="20sp" />
</LinearLayout>
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:paddingTop="10dp" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="好评 "
android:textColor="@color/black"
android:textSize="12sp" />
<TextView
android:id="@+id/search_item_evaluate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:text="90%"
android:textColor="@color/black"
android:textSize="12sp" />
<TextView
android:id="@+id/search_item_sell"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="20人"
android:textColor="@color/black"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
最后要说的就是listview的java类代码!它有三个职能:
1.拿到需要显示的数据,我的项目中是json串;
2.转换成相应的实体模型;
3.通过适配器(adapter)将实体模型和控件一一适配;
源码清单如下:
package jczb.shoping.ui;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.PublicKey;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.alibaba.fastjson.JSON;
import jczb.shoping.common.AgentApi;
import jczb.shoping.model.productSonSorting_cate;
import jczb.shoping.model.products;
import jczb.shoping.model.sonSortigns;
import jczb.shoping.model.sorting;
import jczb.shoping.ui.base.BaseActivity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
public class SearchActivity extends BaseActivity {
//商品列表
private ListView product_class_listview;
private LayoutInflater layoutInflater;
//某一小类中商品的个数
public int LengthsortingSon;
private String[] mTitleValues = new String[10];
private String[] mContentValues = new String[10];
private String[] mEvluateValues=new String[10];
private String[] mSellValues=new String[10];
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
findViewById();
/*开始线程*/
new Thread(new MyThread()).start();
initView();
}
@Override
protected void findViewById() {
// TODO Auto-generated method stub
product_class_listview=(ListView) findViewById(R.id.product_class_listview);
product_class_listview.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterview, View view, int parent,
long id) {
Toast.makeText(SearchActivity.this, "你点击了第"+id+"项", 1).show();
}
});
}
/*子线程-解析数据*/
private Handler handler = new Handler() {
/*声明子类中商品数量*/
public List<sonSortigns> sortingSon;
private String[] ListproName = {};
// 在Handler中获取消息,重写handleMessage()方法
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case -1:
Toast.makeText(SearchActivity.this, "服务器连接失败!",
Toast.LENGTH_SHORT).show();
break;
case -2:
Toast.makeText(SearchActivity.this, "哎呀,出错啦...",
Toast.LENGTH_SHORT).show();
break;
case 1:
String temp = (String)msg.obj;
//将拿到的json转换为数组
List<productSonSorting_cate> sortingInfo = JSON.parseArray(temp,productSonSorting_cate.class);
//小吃类商品个数
LengthsortingSon=sortingInfo.get(0).getSonSortings().get(0).getProducts().size();
/*循环各个商品属性加入数据*/
for(int i=0;i<LengthsortingSon;i++){
mTitleValues[i] =sortingInfo.get(0).getSonSortings().get(0).getProducts().get(i).getProName().toString();
mContentValues[i] =sortingInfo.get(0).getSonSortings().get(0).getProducts().get(i).getMarkPrice().toString();
mEvluateValues[i]=sortingInfo.get(0).getSonSortings().get(0).getProducts().get(i).getHaoping().toString();
mSellValues[i]=sortingInfo.get(0).getSonSortings().get(0).getProducts().get(i).getAreadSell().toString();
}
/*适配商品属性和控件*/
product_class_listview.setAdapter(new productsAdapter());
break;
default:
break;
}
}
};
/*主线程-拿数据*/
public class MyThread implements Runnable {
@Override
public void run() {
Message msg = new Message();
Bitmap bitemapBitmap = null;
try {
Map<String, String> parmas = new HashMap<String, String>();
parmas.put("username", "1");
parmas.put("password", "2");
String url = "http://192.168.1.110:8080/SchoolShopJson/productSonSorting_cate.txt";
// 要发送的数据和访问的地址
String result = AgentApi.dopost(parmas, url);
// 如果返回的为空或者初始化时输入的ip地址无效(会返回下面的字符串),说明服务器连接失败!
if (result == null) {
// 使用-1代表服务器连接失败
msg.what = -1;
} else {
msg.what=1;
msg.obj=result;
}
} catch (Exception e) {
e.printStackTrace();
// 使用-1代表程序异常
msg.what = -2;
msg.obj = e;
}
handler.sendMessage(msg);
}
}
@Override
protected void initView() {
// TODO Auto-generated method stub
}
/*适配器-适配数据&控件*/
private class productsAdapter extends BaseAdapter{
@Override
public int getCount() {
// TODO Auto-generated method stub
return LengthsortingSon;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return 0;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder myHolder=new ViewHolder();
layoutInflater =layoutInflater.from(SearchActivity.this);
if(convertView==null){
convertView=layoutInflater.inflate(R.layout.activity_search_item, null);
myHolder.image=(ImageView) convertView.findViewById(R.id.search_image);
myHolder.title=(TextView) convertView.findViewById(R.id.search_item_title);
myHolder.content=(TextView) convertView.findViewById(R.id.search_item_content);
myHolder.evaluate=(TextView) convertView.findViewById(R.id.search_item_evaluate);
myHolder.sell=(TextView) convertView.findViewById(R.id.search_item_sell);
//使用tag存储数据
convertView.setTag(myHolder);
}else {
myHolder=(ViewHolder) convertView.getTag();
}
/*循环position依次适配各个控件*/
myHolder.image.setImageResource(mImageIds[position]);
myHolder.title.setText(mTitleValues[position]);
myHolder.content.setText(mContentValues[position]);
myHolder.evaluate.setText(mEvluateValues[position]);
myHolder.sell.setText(mSellValues[position]);
return convertView;
}
}
/*定义item对象*/
public static class ViewHolder {
ImageView image;
TextView title;
TextView content;
TextView evaluate;
TextView sell;
}
}
在这个过程中最为重要的就是数据和控件的适配过程,需要在ViewHoder中确定各个控件,ConvertView组装各个数据。
从研究listView实现列别功能到如今已经四五天了,参考了很多的例子也查阅了很多的资料,对于ConvertView的使用也有各种各样简便的方法,虽然自己的并不是很简单也没有很好地封装起来,但是作为一个标志性的成功还是很有纪念意义的,希望对大家有所帮助,有问题也可以随时私信我!