无论是什么项目都少不了列表的功能,在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的使用也有各种各样简便的方法,虽然自己的并不是很简单也没有很好地封装起来,但是作为一个标志性的成功还是很有纪念意义的,希望对大家有所帮助,有问题也可以随时私信我!