分类: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 自定义列表视图的外观的更多相关文章

  1. Office365学习笔记—Xslt自定义列表视图

    1,在Office365中需要添加自定义的视图!用Spd添加视图,这儿我添加一个testView! (1)打开testView.aspx将</ZoneTemplate>节点中的内容全部删除 ...

  2. Android课程---优化ListView列表视图(2)

    layout_simple.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout ...

  3. Android课程---优化ListView列表视图

    activity_ui4.xml <?xml version="1.0" encoding="utf-8"?> <ListView xmlns ...

  4. Android课程---关于ListView列表视图的学习

    activity_ui3.xml <?xml version="1.0" encoding="utf-8"?> <ListView xmlns ...

  5. XsltListViewWebPart 和自定义列表视图

    http://msdn.microsoft.com/zh-cn/library/ff806162(v=office.14).aspx

  6. 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 ...

  7. 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 ...

  8. Android 自学之列表视图ListView和ListActivity

    ListView是手机系统中使用非常广泛的一种组件,它以垂直列表的形式显示所有列表项. 创建ListView有两种方式: 直接使用ListView创建. 让Activity继承ListActivity ...

  9. Android使用Mono c#分段列表视图

    下载source code - 21.7 KB 你想知道如何把多个ListView控件放到一个布局中,但是让它们在显示时表现正确吗 多个列表项?你对它们正确滚动有问题吗?这个例子将向你展示如何组合单独 ...

随机推荐

  1. C# WebRequest处理Https请求

    http://www.cnblogs.com/youlechang123/archive/2013/03/23/2976630.html 正常情况下,处理https和http没有什么区别,如以下代码, ...

  2. listView.getChildAt(i)时java.lang.NullPointerException

    BaseAdapter返回的是当前屏幕所能显示Item条数的组件,所以通过listView.getChildAt(i); 返回的是当前屏幕所能显示的组件.不能通过listView.getChildAt ...

  3. 用 Eclipse 插件提高代码质量

    如果能在构建代码前发现代码中潜在的问题会怎么样呢?很有趣的是,Eclipse 插件中就有这样的工具,比如 JDepend 和 CheckStyle,它们能帮您在软件问题暴露前发现这些问题.在 让开发自 ...

  4. MySQL 数据库几种类型

    关系数据库(MySQL.Oracle.SQL Server.DB2.Postgres)键-值存储数据库(Riak和Redis)面向列的数据库(HBase) 面向文档的数据库(MongoDB 和Couc ...

  5. spring jdbc连接数据库

    1.在applicationContext.xml中配置jdbc bean <bean id="dataSource" class="org.springframe ...

  6. 【转】javascript中值传递,地址传递,引用传递的问题(使用js创建list对象时会用到)

    function initEditModal_SI(node) { if (node.siArray == undefined) { node.siArray = new Object(); } va ...

  7. Unity 添加自定义菜单(插件),添加功能

    网上介绍如何写这种插件的文章很多...但是对于新手来说,最基本的,怎么运行这个插件,都不知道...网上的文章都懒得说这个...   幸好,看了半天官方网站别的资料,突然就发现办法了...   这个不是 ...

  8. Struts2的配置文件的配置struts.xml

    在学习struts的时候,我们一定要掌握struts2的工作原理. 仅仅有当我们明白了在struts2框架的内部架构的实现过程.在配置整个struts 的框架时.能够非常好的进行逻辑上的配置.接下来我 ...

  9. with/as上下文管理器

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #Python学习手册 868 #with/as上下文管理器 #with语句的基本格式: with open( ...

  10. centos7编译python3.6与原有的2.7共存

    在某些场景下我们可能需要python2.7和python3这两个版本进行共存,我在工作中也遇到过这样的问题,所以今天来总结下我的安装过程, 我的是用源码包安装的,安装的是python3.6的版本. 安 ...