Android开发之自定义的ListView(UITableViewController)
Android开发中的ListView, 顾名方法思义,就是表视图。表示图在iOS开发中就是TableView。两者虽然名称不一样,但是其使用方法,使用场景以及该控件的功能都极为相似,都是用来展示大量数据并带有分页的控件。本篇博客将要类比着iOS开发来认识一下ListView, 如果你是Android开发者,你可以看一下iOS中TableView的工作方式。如果你是初学者,那么只看Android的开发即可。其实Android开发和iOS开发有许多东西都是相通的,尽管控件的名称以及具体的使用方式不同,但是其使用的本质思想是一样的。今天的博客就在恰当的地方类比一下iOS开发来好好的搞一下Android开发这个高级控件ListView。
言归正传,今天就先认识一下Android开发中系统自带的ListView. 然后再进一步认识一下ListView, 来自定义一下属于自己的ListView。在自定义属于自己的ListView时,是结合者某个理财App中,财富管理页面的列表来实现的。开始今天博客的主题。
一. 系统自带的ListView
ListView也就是表视图,表视图中摆放的是一个个的Cell(单元格),Cell上放的是我们要展示的数据。在博客的第一部分,我们先使用一下AndroidSDK中预定义的一种ListView,当然还有其他种,但是我们使用最简单的,也就是Cell上只有一个标题。开始我们这第一部分的正题。
1. 创建ListView
ListView虽然是高级控件,但是高级控件也是控件不是,在XML中也是有ListView标签的。首先我们创建一个空的Activity,在Activity对应的xml文件中添加ListView标签。下方就是所添加的内容。
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
2. 创建模拟数据
ListView上显示的是一个数据的集合,所以我们要先创建一个Array, 其中存放着在ListView上显示的数据。模拟数据如下:
private String[] dataSource = {"Android", "Google","Java", "Go","iOS", "Apple", "Objc", "Swift"};
3. 数据显示
第三部要做的就是在ListView上显示上面数组中的值了。每个Cell上显示一个元素,在Android开发中,为了在ListView中显示数据,引入了数据适配器的概念,这个数据适配其其实就是对应着iOS开发中的TableViewCell。Android中的ArrayAdapter其实就是Cell的不同模板,我们把数据赋值给数据适配器,数据适配器就会把要显示的数据放到相应的Cell上,并且在ListView上展示。
下方第一行代码是通过ID从XML中获取ListView对象。然后创建ArrayAdatper(数组适配器),适配器的构造函数第一个参数是数据所在的Activity,第二个参数是单元格要使用的模板,也就是Cell的上要显示的数据及其布局方式(对应着iOS开发中Cell的布局),第三个参数是数据源即在ListView上显示的数据集合。最后就是给ListView对接数据适配器进行数据的显示了
//通过ID获取ListView对象
ListView listView = (ListView) findViewById(R.id.list_view);
//创建数据适配器
ArrayAdapter<String> adapter = new ArrayAdapter<String>(FirstListViewActivit.this, R.layout.support_simple_spinner_dropdown_item, dataSource);
//给ListView添加数据
listView.setAdapter(adapter);
经过上面这几步,你就可以创建并显示一个简单的ListView了,上面的Activity运行后,效果如下所示:

二. 自定义ListView
如果你经过第一步觉得过于简单没有挑战性的话,那么我们紧接着来第二部分自定义属于你自己的ListView. 在开发中大部分还是自定义ListView居多,接下来就来一个真实的案例。下方是我们要实现的效果,也就是我们写完代码运行后的一个效果,下方是某知名互联网金融公司其中一个理财App中“我的财富”模块中的一部分ListView。下方是运行后的效果,我参与项目开发时,做的是iOS版本,接下来看下Android开发中要实现下方的一个ListView应如何去实现呢。

1.对布局进行分析
磨刀不误砍柴工,拿到一个UI设计时,不要急着动手,要先分析UI的结构。一个UI的结构分析透了,那么实现起来就容易多了。在iOS开发中,如果想分析其他App中的UI实现方式,可以使用一个叫Reveal的神器,至于安卓中有木有类似强大的UI分析神器,我就不可而知了。好,我们开始分析上面的UI, 其实上面的Cell是重复的,只要对一个UI进行分析透即可,下方是我们摘抄出来的Cell:

下面我们就要开始对上述Cell的布局开始分析了,百字不如一图,在此我还是想用一个效果图来说明一下,效果图如下所示。接下来用语言简单的描述一下,最外方我们使用的是垂直布局的LinearLayout,也就是说该布局内的控件都是从上往下排列。接着又是三个子LinearLayout布局,该布局是水平方向,也就是其中的控件是水平方向排列的,里边的控件都是均分的。如果对此有布局有疑问请看之前发布的博客《Android开发之基本控件和详解四种布局方式》其中对Android开发中常用的布局进行了介绍。

2.上述布局的实现
布局分析完了,接下来就是该如何实现了。实现起来就是写XML文件了。如果上面真正的分析透彻了,写布局文件应该不算话下。紧接着需要创建一个XML布局文件,然后对上述布局进行实现,并为相应控件指定id。下方是上面Cell的布局代码,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginRight="@dimen/activity_horizontal_margin">
<!-- 类似于iOS开发中Cell的布局 -->
<LinearLayout
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp">
<TextView
android:id="@+id/product_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="left"
android:textSize="@dimen/item_top_title_size"
android:text="@string/item_top_title"
android:lines="1"/>
<TextView
android:id="@+id/product_status"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:textSize="@dimen/item_top_font_size"
android:text="认购状态"
android:lines="1"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="@dimen/item_top_height">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="@dimen/item_top_font_size"
android:text="@string/item_top_left_title"
android:lines="1"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:lines="1"
android:textSize="@dimen/item_top_font_size"
android:text="@string/item_top_center_title" /> <TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:lines="1"
android:textSize="@dimen/item_top_font_size"
android:text="@string/item_top_right_title"/>
</LinearLayout> <LinearLayout
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="@dimen/item_top_height"
android:layout_marginBottom="10dp">
<TextView
android:id="@+id/product_lend_money"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="@dimen/item_down_font_size"
android:text="0.00"
android:lines="1"/>
<TextView
android:id="@+id/product_interest"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:lines="1"
android:textSize="@dimen/item_down_font_size"
android:text="0.00"
android:textColor="#ff0000"/> <TextView
android:id="@+id/product_date"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:lines="1"
android:textSize="@dimen/item_down_font_size"
android:text="0000-00-00"/>
</LinearLayout> </LinearLayout>
3.自定义Cell的布局上面就实现好了,接下来,我们要为每个Cell上显示的数据定义一个数据实体类来表示Cell上的数据,这一点在开发中也是经常使用到的。接下来定义的就是我们的Model类,也就是实体类,如下所示:
public class ProductModel {
public String productName = "";
public String productBuyState = "";
public String lendMoney = "0.00";
public String interest = "0.00";
public String endDate = "0000-00-00";
}
4.紧接着要定制上述布局的数据适配器了,我们将要创建的适配器是继承自系统的ArrayAdapter适配器的,我们可以在此基础上来做一些属于我们自己的一些东西。其中有一个私有变量是resourceId, 我们用它来暂存上面布局文件的Id的,由此我们就可以找到该适配器对应的布局方式了。在自定义的ProductAdatper中我们还重写了getView方法,该方法返回的就是带有数据的Cell。
在getView方法中,我们可以通过getItem(position)来获取当前将要显示在Cell上的数据,通过LayoutInflater来获取Cell布局文件,在接着就是把数据赋值给Cell上相应的TextView了。最后就是返回这个View(也就是iOS开发中的Cell)。到此这个自定义产品数据适配器就实现完毕了。具体代码如下所示。
/**
* Created by lizelu on 15/12/20.
* Adapter类似于iOS开发中UITableViewCell源文件,就是给每个Cell赋值的
*/
public class ProductAdapter extends ArrayAdapter<ProductModel> {
private int resourceId;
/**
* Constructor
*
* @param context listView所在的上下文,也就是ListView所在的Activity
* @param resource Cell的布局资源文件
* @param objects Cell上要显示的数据list,也就是实体类集合
*/
public ProductAdapter(Context context, int resource, List<ProductModel> objects) {
super(context, resource, objects);
resourceId = resource;
} @Override
/**
* @param position 当前设置的Cell行数,类似于iOS开发中的indexPath.row
*/
public View getView(int position, View convertView, ViewGroup parent) {
ProductModel product = getItem(position); View productView = LayoutInflater.from(getContext()).inflate(resourceId, null); TextView productName = (TextView) productView.findViewById(R.id.product_name);
TextView productStatus = (TextView) productView.findViewById(R.id.product_status);
TextView productLendMoney = (TextView) productView.findViewById(R.id.product_lend_money);
TextView productInterest = (TextView) productView.findViewById(R.id.product_interest);
TextView productEndDate = (TextView) productView.findViewById(R.id.product_date); productName.setText(product.productName);
productStatus.setText(product.productBuyState);
productLendMoney.setText(product.lendMoney);
productInterest.setText(product.interest);
productEndDate.setText(product.endDate); return productView;
}
}
5.自定义完以后,接下来就是制造在ListView上显示的模拟数据了,模拟数据就是一个ArrayList, 其中存放的是一个个ProductModel,每个ProductModel对应着一个Cell。下方函数就是创建模拟数据的函数,如下所示:
private void createProductList() {
for (int i=0; i<20; i++) {
ProductModel product = new ProductModel();
product.productName = "产品名称" + i;
if (i % 2 == 0){
product.productBuyState = "认购中";
} else {
product.productBuyState = "认购成功";
}
product.lendMoney = "" + (i * 100 + i);
product.interest = "" + (i * 10);
if (i < 10) {
product.endDate = "2016-01-0" + i;
} else {
product.endDate = "2016-01-" + i;
}
productList.add(i, product);
}
}
6.这是最后一步,也是放大招的时刻。接下来就是利用数据适配器对接ListView和ProductModel数据集合的时候了。此时可以把数据适配器看做是iOS开发中TableViewDatasource中的代理方法。形象点就是转换器(适配器)一头连接着数据源,一头则连接着显示数据的ListView, 而适配器的功能就是把数据转换成在TableView上显示的元素,下方就是这个转换的过程。
ProductAdapter adapter = new ProductAdapter(CustomeItemListViewActivity.this, R.layout.custome_item, productList);
ListView listView = (ListView)findViewById(R.id.second_list_view);
listView.setAdapter(adapter);
7.如果你想给每个Cell都加上点击事件,换句话说,你想在点击Cell时做一些事情,那么你需要为ListView的每个item添加点击事件,为每个Cell添加点击事件的代码如下所示,点击Cell是我们就使用Toast显示当前Cell的产品名称。
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
ProductModel product = productList.get(position);
Toast.makeText(CustomeItemListViewActivity.this, product.productName, Toast.LENGTH_SHORT).show();
}
});
到此,上述Demo以实现完毕,你还可以在此基础上做许多扩充,比如下拉刷新, 上拉加载等listView常用的功能,在此就不做过多赘述了。
上述Demo在GitHub上的分分享地址:https://github.com/lizelu/AndroidListViewDemo
Android开发之自定义的ListView(UITableViewController)的更多相关文章
- Android开发:自定义GridView/ListView数据源
http://mobile.51cto.com/android-259861.htm 在开发中,我们常常会遇到比较复杂的GridView/ListView的布局,重新实现BaseAdapter不但能帮 ...
- android开发之自定义组件
android开发之自定义组件 一:自定义组件: 我认为,自定义组件就是android给我们提供的的一个空白的可以编辑的图片,它帮助我们实现的我们想要的界面,也就是通过自定义组件我们可以把我们要登入的 ...
- Android开发中常用的ListView列表的优化方式ViewHolder
在Android开发中难免会遇到大量的数据加载到ListView中进行显示, 然后其中最重要的数据传递桥梁Adapter适配器是常用的,随着市场的需 求变化ListView'条目中的内容是越来越多这就 ...
- Android开发之自定义组件和接口回调
说到自定义控件不得不提的就是接口回调,在Android开发中接口回调用的还是蛮多的.在这篇博客开始的时候呢,我想聊一下iOS的自定义控件.在iOS中自定义控件的思路是继承自UIView, 在UIVie ...
- Android开发之自定义局部导航菜单
如今,要实现导航功能方案有很多.比如: 1.用3.0+自带的Toolbar + Fragment导航. 2.用Tabhost实现导航.小弟学浅,就只用过这两种方案实现导航. 但是这两种方案都有一个很明 ...
- Android开发进阶——自定义View的使用及其原理探索
在Android开发中,系统提供给我们的UI控件是有限的,当我们需要使用一些特殊的控件的时候,只靠系统提供的控件,可能无法达到我们想要的效果,这时,就需要我们自定义一些控件,来完成我们想要的效果了.下 ...
- Android开发之自定义圆角矩形图片ImageView的实现
android中的ImageView只能显示矩形的图片,这样一来不能满足我们其他的需求,比如要显示圆角矩形的图片,这个时候,我们就需要自定义ImageView了,其原理就是首先获取到图片的Bitmap ...
- Android开发之自定义圆形的ImageView的实现
android中的ImageView只能显示矩形的图片,这样一来不能满足我们其他的需求,比如要显示圆形的图片,这个时候,我们就需要自定义ImageView了,其原理就是首先获取到图片的Bitmap,然 ...
- Android开发之自定义圆角矩形图片ImageView的实现 - Jamy Cai
android中的ImageView只能显示矩形的图片,这样一来不能满足我们其他的需求,比如要显示圆角矩形的图片,这个时候,我们就需要自定义ImageView了,其原理就是首先获取到图片的Bitmap ...
随机推荐
- GreenDao 数据库:使用Raw文件夹下的数据库文件以及数据库升级
一.使用Raw文件夹下的数据库文件 在使用GreenDao框架时,数据库和数据表都是根据生成的框架代码来自动创建的,从生成的DaoMaster中的OpenHelper类可以看出: public sta ...
- 在离线环境中使用.NET Core
在离线环境中使用.NET Core 0x00 写在开始 很早开始就对.NET Core比较关注,一改微软之前给人的印象,变得轻量.开源.跨平台.最近打算试着在工作中使用.但工作是在与互联网完全隔离的网 ...
- 随手记_C#验证码
前言 最近在网上偶然看见一个验证码,觉得很有意思,于是搜了下,是使用第三方实现的,先看效果: 总体来说效果还是可以的,官方提供的SDK也比较详细,可配置性很高.在这里在简单啰嗦几句使用方式: 使用步骤 ...
- HTML文档声明
前面的话 HTML文档通常以类型声明开始,该声明将帮助浏览器确定其尝试解析和显示的HTML文档类型.本文将详细介绍文档声明DOCTYPE 特点 文档声明必须是HTML文档的第一行.且顶格显示, ...
- JavaScript之职责链模式
一.概述 职责链模式(Chain of responsibility),就是使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这个对象连成一条链,并沿着这条链传递该请求,直到有 ...
- AJAX 大全
本章内容: 简介 伪 AJAX 原生 AJAX XmlHttpRequest 的属性.方法.跨浏览器支持 jQuery AJAX 常用方法 跨域 AJAX JsonP CORS 简单请求.复制请求.请 ...
- Tomcat启动报错org.springframework.web.context.ContextLoaderListener类配置错误——SHH框架
SHH框架工程,Tomcat启动报错org.springframework.web.context.ContextLoaderListener类配置错误 1.查看配置文件web.xml中是否配置.or ...
- 【夯实Mysql基础】MySQL性能优化的21个最佳实践 和 mysql使用索引
本文地址 分享提纲: 1.为查询缓存优化你的查询 2. EXPLAIN 你的 SELECT 查询 3. 当只要一行数据时使用 LIMIT 1 4. 为搜索字段建索引 5. 在Join表的时候使用相当类 ...
- StrategyPattern (策略模式)
/** * 策略模式 * @author TMAC-J * 根据环境的不同选择不同的策略,把策略用接口抽象出来 */ public class StrategyPattern { interface ...
- 装饰者模式 Decoration
1.什么是装饰者模式 动态给对象增加功能,从一个对象的外部来给对象添加功能,相当于改变了对象的外观,比用继承的方式更加的灵活.当使用装饰后,从外部系统的角度看,就不再是原来的那个对象了,而是使用一系列 ...