分类: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. Cass环境下光标无显示

    先安装CAD2004,十字光标正常显示:再安装CASS7.0,光标就不显示了.现在不清楚是CAD的问题,还是CASS的问题,多半是后者.重新配置了CASS环境也不行. 于是,打开CAD选项,显示,窗口 ...

  2. T-SQL 之 游标

    游标是面向行的,它会使开发人员变懒,懒得去想用面向集合的查询方式实现某些功能. 在性能上,游标会占有更多的内存,减少可用的并发,占用带宽,锁定资源,当然还有更多的代码量. 用一个比喻来说明为什么游标会 ...

  3. Idea Spring-boot gradle lombok

    1:build.gradle compile("org.projectlombok:lombok:1.16.16") 2:idea安装lombok插件 3:设置 4:重启

  4. 队列实例程序(C语言)

    /* queue.h */ #ifndef _QUEUE_H #define _QUEUE_H struct queue_record; typedef struct queue_record *qu ...

  5. 关于SimHash去重原理的理解(能力工场小马哥)

    阅读目录 1. SimHash与传统hash函数的区别 2. SimHash算法思想 3. SimHash流程实现 4. SimHash签名距离计算 5. SimHash存储和索引 6. SimHas ...

  6. vue diff算法 patch

    1.diff比较算法 图示: diff比较只会在同层级进行, 不会跨层级比较. 所以diff是:广度优先算法. 时间复杂度:O(n) 代码示例: <!-- 之前 --> <div&g ...

  7. sql server 2008分页

    SELECT id, name, staffopenid, imageurl, content, ordernum, praisenum, createdate, lable, label2, man ...

  8. C语言位域精解(转)

    有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1 两种状态,用一位二进位即可.为了节省存储空间,并使处理简便,C语言又提供了一种数据结构, ...

  9. el表达式 多条件判断

      el表达式 多条件判断 CreationTime--2018年9月13日08点59分 Author:Marydon 1.情景展示 ACCESS_ID == 'APP1039' 且 CARDTYPE ...

  10. poi读取execl的日期

    当execl中的列为日期格式时,后台读取到是一个数字,通过如下代码可以直接读取并转换到Date类型 HSSFDateUtil.getJavaDate(cell.getNumericCellValue( ...