【Android】9.3 自定义列表视图的外观
分类:C#、Android、VS2015;
创建日期:2016-02-18
一、简介
自定义的列表视图通常用Resources/Layout文件夹下的axml文件中的资源来声明,适配器则通过Id去加载它。一个视图可以包含任意数量的类 (如 TextViews、 ImageViews 和其他控件) 以及自定义的颜色、字体和布局。
由于ListView的外观是由行的布局决定的,因此,若要更改列表视图的外观,只需要使用不同的行布局即可。
如果希望显示更复杂的布局 (如电子邮件、联系人列表),必须用自定义视图来实现。
二、运行截图

三、主要设计步骤
1、在colors.xml中添加颜色定义
在/Resources/values/ colors.xml文件中添加本示例选中行的颜色:
<color name="cellback">#FFDAFF7F</color>
2、添加ch0902CustomSelector.xml文件
在 /Resources/Drawable文件夹下添加该文件。
<?xml version="1.0" encoding="utf-8" ?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false"
android:state_selected="false"
android:drawable="@color/cellback" />
<item android:state_pressed="true" >
<shape>
<gradient
android:startColor="#E77A26"
android:endColor="#E77A26"
android:angle="270" />
</shape>
</item>
<item android:state_selected="true"
android:state_pressed="false"
android:drawable="@color/cellback" />
</selector>
3、添加ch0902_CustomView.axml文件
要为列表视图中每一行都创建一个自定义的布局,必须定义一个单独的布局文件。在此示例中,每行都用绿色背景、棕色文本以及一个右对齐的图像来呈现。这个单独的布局保存在/Resources/Layout/ch0902_CustomView.axml文件中:
<?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="@drawable/ch0902CustomSelector"
android:padding="8dp">
<LinearLayout
android:id="@+id/Text"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dip">
<TextView
android:id="@+id/Text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FF7F3300"
android:textSize="20dip"
android:textStyle="italic" />
<TextView
android:id="@+id/Text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14dip"
android:textColor="#FF267F00"
android:paddingLeft="100dip" />
</LinearLayout>
<ImageView
android:id="@+id/Image"
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="5dp"
android:src="@drawable/icon"
android:layout_alignParentRight="true" />
</RelativeLayout>
虽然自定义行布局可以包含许多不同的控件,但是滚动性能可能会受到影响(特别是通过网络加载图像时)。
关于解决滚动性能问题的详细信息,可参考谷歌官网上的相关文章。
4、添加ch0902_Main.axml文件
在/Resources/Layout文件夹下添加该文件。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="@+id/Heading"
android:text="Vegetable Groups"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="30dp"
android:textColor="#FF267F00"
android:textStyle="bold"
android:padding="5dp" />
<ListView
android:id="@+id/List"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:cacheColorHint="#FFDAFF7F" />
</LinearLayout>
5、添加ch0902MyBaseAdapter.cs文件
这个文件的关键是GetView方法,该方法使用Resource.Layout.ch0902_CustomView的资源ID加载自定义的axml,然后设置视图中控件的每个属性,最后返回结果。
using System.Collections.Generic;
using Android.App;
using Android.Views;
using Android.Widget; namespace MyDemos.SrcDemos
{
public class ch0902MyBaseAdapter : BaseAdapter<ch0901TableItem>
{
List<ch0901TableItem> items;
Activity context;
public ch0902MyBaseAdapter(Activity context, List<ch0901TableItem> items)
{
this.context = context;
this.items = items;
} public override long GetItemId(int position)
{
return position;
} public override ch0901TableItem this[int position]
{
get { return items[position]; }
} public override int Count
{
get { return items.Count; }
} public override View GetView(int position, View convertView, ViewGroup parent)
{
var item = items[position];
View view = convertView;
// 如果没有可复用的视图(view为null),就创建一个新视图
if (view == null)
{
view = context.LayoutInflater.Inflate(Resource.Layout.ch0902_CustomView, null);
}
view.FindViewById<TextView>(Resource.Id.Text1).Text = item.Heading;
view.FindViewById<TextView>(Resource.Id.Text2).Text = item.SubHeading;
view.FindViewById<ImageView>(Resource.Id.Image).SetImageResource(item.ImageResourceId);
return view;
}
}
}
6、添加ch0902Main.cs文件
在SrcDemos文件夹下添加该文件。
using System.Collections.Generic;
using Android.App;
using Android.OS;
using Android.Widget; namespace MyDemos.SrcDemos
{
[Activity(Label = "【例9-2】 自定义视图")]
public class ch0902Main : Activity
{
List<ch0901TableItem> tableItems = new List<ch0901TableItem>();
ListView listView; protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.ch0902_Main);
listView = FindViewById<ListView>(Resource.Id.List);
tableItems.Add(new ch0901TableItem() { Heading = "Vegetables", SubHeading = "65 items", ImageResourceId = Resource.Drawable.ch09Vegetables });
tableItems.Add(new ch0901TableItem() { Heading = "Fruits", SubHeading = "17 items", ImageResourceId = Resource.Drawable.ch09Fruits });
tableItems.Add(new ch0901TableItem() { Heading = "Flower Buds", SubHeading = "5 items", ImageResourceId = Resource.Drawable.ch09FlowerBuds });
tableItems.Add(new ch0901TableItem() { Heading = "Legumes", SubHeading = "33 items", ImageResourceId = Resource.Drawable.ch09Legumes });
tableItems.Add(new ch0901TableItem() { Heading = "Bulbs", SubHeading = "18 items", ImageResourceId = Resource.Drawable.ch09Bulbs });
tableItems.Add(new ch0901TableItem() { Heading = "Tubers", SubHeading = "43 items", ImageResourceId = Resource.Drawable.ch09Tubers });
listView.Adapter = new ch0902MyBaseAdapter(this, tableItems);
}
}
}
四、代码解释
1、行复用
如果所有行可在一个屏幕内全部显示出来,此时不需要复用。但是,当显示成百上千行的数据时,一次创建这么多的视图但只能使用几行太浪费内存空间了。为了避免这种情况,当某行从屏幕上消失时,可将其保存到一个队列中,以便复用。
具体实现办法是:当用户滚动屏幕时,先判断在convertView参数中传递的视图实例,如果该值为null,就创建新的视图实例,否则重新设置该对象的属性以便复用它。
GetView方法应该按下面的模式来复用行视图:
public override View GetView(int position, View convertView, ViewGroup parent)
{
View view = convertView; // re-use an existing view, if one is supplied
if (view == null) view = context.LayoutInflater.Inflate(Android.Resource.Layout.SimpleListItem1, null);
view.FindViewById<TextView>(Android.Resource.Id.Text1).Text = items[position];
return view;
}
创建新的视图前,自定义适配器应该总是实现convertView对象,这样可确保显示大量的列表数据时不会导致内存溢出。
注意,某些适配器的实现(例如CursorAdapter)可能没有GetView方法,不过,这些适配器采用的策略是将GetView的职责分成两种不同的方法NewView和BindView,从而确保强制执行复用的行。
2、快速滚动
当一个ListView包含多行数据时,可利用快速滚动导航到该列表的不同部分(Api 11及更高版本都支持快速滚动)。
将FastScrollEnabled属性设置为true,即可显示快速滚动手柄(handle):
ListView.FastScrollEnabled = true;
3、通过C#代码设置或查找选项
设置列表中的初始化选项时,用SetItemChecked方法实现即可,例如:
listview.SetItemChecked(1, true);
也可能需要从多个选项中查找某个已选择的单项,例如:
FindViewById<ListView>(Android.Resource.Id.List).CheckedItemPosition
要确定在多选模式中用户选择了哪些行,需要遍历用稀疏数组(sparseArray)保存的所有可选项,该数组类似于一个保存更改记录的字典,所以必须遍历整个数组才能找到所有选项,例如:
var sparseArray = FindViewById<ListView>(Android.Resource.Id.List).CheckedItemPositions;
for (var i = 0; i < sparseArray.Size(); i++ )
{
Console.Write(sparseArray.KeyAt(i) + "=" + sparseArray.ValueAt(i) + ",");
}
Console.WriteLine();
4、自定义所选行的颜色
当用户选择某行时,一般应突出显示该行。突出显示行是在ch0902_CustomView.axml文件中实现的(将背景设置为淡绿色),重启突出显示的行也是用它来实现,但是采用的是反色背景。因此,先在 /Resources/Drawable/ch0902CustomSelector.xml 文件中包含对应的声明,然后在ch0902_CustomView.axml 文件中通过引用自定义的选择器来改变背景:
android:background="@drawable/ch0902CustomSelector"
当选择某行时(按住不抬起来),即得到运行截图所示的效果。
5、避免滚动闪烁
安卓系统是通过缓存布局信息来改善ListView的滚动性能的。如果列表视图中有比较长的滚动列表的数据,还应该在axml布局文件的ListView控件中声明android:cacheColorHint属性(将其值设置为和自定义行布局中的背景色相同),否则的话,滚动列表时就可能会出现一闪一闪(flicker)的情况。
【Android】9.3 自定义列表视图的外观的更多相关文章
- Office365学习笔记—Xslt自定义列表视图
1,在Office365中需要添加自定义的视图!用Spd添加视图,这儿我添加一个testView! (1)打开testView.aspx将</ZoneTemplate>节点中的内容全部删除 ...
- Android课程---优化ListView列表视图(2)
layout_simple.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout ...
- Android课程---优化ListView列表视图
activity_ui4.xml <?xml version="1.0" encoding="utf-8"?> <ListView xmlns ...
- Android课程---关于ListView列表视图的学习
activity_ui3.xml <?xml version="1.0" encoding="utf-8"?> <ListView xmlns ...
- XsltListViewWebPart 和自定义列表视图
http://msdn.microsoft.com/zh-cn/library/ff806162(v=office.14).aspx
- Apply Grouping to List View Data 将分组应用于列表视图数据
This lesson will teach you how to apply grouping to List View data. For this purpose, you will group ...
- Change Field Layout and Visibility in a List View 在列表视图中更改字段布局和可见性
This lesson will guide you through the steps needed to select columns displayed in the List View. Fo ...
- Android 自学之列表视图ListView和ListActivity
ListView是手机系统中使用非常广泛的一种组件,它以垂直列表的形式显示所有列表项. 创建ListView有两种方式: 直接使用ListView创建. 让Activity继承ListActivity ...
- Android使用Mono c#分段列表视图
下载source code - 21.7 KB 你想知道如何把多个ListView控件放到一个布局中,但是让它们在显示时表现正确吗 多个列表项?你对它们正确滚动有问题吗?这个例子将向你展示如何组合单独 ...
随机推荐
- C# WebRequest处理Https请求
http://www.cnblogs.com/youlechang123/archive/2013/03/23/2976630.html 正常情况下,处理https和http没有什么区别,如以下代码, ...
- listView.getChildAt(i)时java.lang.NullPointerException
BaseAdapter返回的是当前屏幕所能显示Item条数的组件,所以通过listView.getChildAt(i); 返回的是当前屏幕所能显示的组件.不能通过listView.getChildAt ...
- 用 Eclipse 插件提高代码质量
如果能在构建代码前发现代码中潜在的问题会怎么样呢?很有趣的是,Eclipse 插件中就有这样的工具,比如 JDepend 和 CheckStyle,它们能帮您在软件问题暴露前发现这些问题.在 让开发自 ...
- MySQL 数据库几种类型
关系数据库(MySQL.Oracle.SQL Server.DB2.Postgres)键-值存储数据库(Riak和Redis)面向列的数据库(HBase) 面向文档的数据库(MongoDB 和Couc ...
- spring jdbc连接数据库
1.在applicationContext.xml中配置jdbc bean <bean id="dataSource" class="org.springframe ...
- 【转】javascript中值传递,地址传递,引用传递的问题(使用js创建list对象时会用到)
function initEditModal_SI(node) { if (node.siArray == undefined) { node.siArray = new Object(); } va ...
- Unity 添加自定义菜单(插件),添加功能
网上介绍如何写这种插件的文章很多...但是对于新手来说,最基本的,怎么运行这个插件,都不知道...网上的文章都懒得说这个... 幸好,看了半天官方网站别的资料,突然就发现办法了... 这个不是 ...
- Struts2的配置文件的配置struts.xml
在学习struts的时候,我们一定要掌握struts2的工作原理. 仅仅有当我们明白了在struts2框架的内部架构的实现过程.在配置整个struts 的框架时.能够非常好的进行逻辑上的配置.接下来我 ...
- with/as上下文管理器
# -*- coding: utf-8 -*- #python 27 #xiaodeng #Python学习手册 868 #with/as上下文管理器 #with语句的基本格式: with open( ...
- centos7编译python3.6与原有的2.7共存
在某些场景下我们可能需要python2.7和python3这两个版本进行共存,我在工作中也遇到过这样的问题,所以今天来总结下我的安装过程, 我的是用源码包安装的,安装的是python3.6的版本. 安 ...