基本各种列表都和分页有着密不可分的关系.
在barServer这个工程里,我们首先添加一个新的实体类Product,然后添加一个公共的分页结果对象.
package com.crap.common;
import java.util.List;
public class Pagination<T> {
//当前页数
private int currentPageNumber;
//总页数
private int totalPageNumber;
//当前页的item list
private List<T> itemList;
// 省略getter和setter
}
这样无论是学生的分页结果还是product的分页结果,都可以用这个对象返回.
StudentService类中两个模拟的分页查询方法如下
public Pagination<Student> paginateStudent() {
Pagination<Student> result = new Pagination<Student>();
result.setCurrentPageNumber(3);
result.setTotalPageNumber(5);
result.setItemList(this.studentDao.findStudentList());
return result;
}
public Pagination<Product> paginateProduct() {
Pagination<Product> result = new Pagination<Product>();
result.setCurrentPageNumber(2);
result.setTotalPageNumber(8);
List<Product> list = new ArrayList<Product>();
Product p = new Product();
p.setId(0);
p.setName("product 1");
p.setPrice(34.2);
p.setOnline(true);
list.add(p);
p = new Product();
p.setId(1);
p.setName("product 2");
p.setPrice(14);
p.setOnline(true);
list.add(p);
p = new Product();
p.setId(2);
p.setName("product 3");
p.setPrice(380);
p.setOnline(true);
list.add(p);
result.setItemList(list);
return result;
}
flex端同样定义对应的分页对象
package com.crap.model{
import mx.collections.ArrayCollection;
[Bindable]
[RemoteClass(alias="com.crap.common.Pagination")]
public class FlexPagination
{
public function FlexPagination()
{
}
private var _currentPageNumber :int;
private var _totalPageNumber :int;
private var _itemList:ArrayCollection;
//省略setter和getter
}
}
这样就可以使用这个FlexPagination了
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:crap="com.crap.components.*"
minWidth="955" minHeight="600">
<fx:Declarations>
<s:RemoteObject id="studentRO" destination="student">
<s:method name="paginateStudent" result="onPaginationStudent(event)"/>
<s:method name="paginateProduct" result="onPaginationProduct(event)"/>
</s:RemoteObject>
</fx:Declarations>
<fx:Script>
<![CDATA[
import com.crap.event.PaginationEvent;
import com.crap.model.FlexPagination;
import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.rpc.events.ResultEvent;
[Bindable]
private var studentList:ArrayCollection;
[Bindable]
private var productList:ArrayCollection;
private function onPaginationStudent(event:ResultEvent):void{
var pagination:FlexPagination=event.result as FlexPagination;
studentList=pagination.itemList;
pagination1.currentNumber=pagination.currentPageNumber;
pagination1.totalNumber=pagination.totalPageNumber;
}
private function onPaginationProduct(event:ResultEvent):void{
var pagination:FlexPagination=event.result as FlexPagination;
productList=pagination.itemList;
pagination2.currentNumber=pagination.currentPageNumber;
pagination2.totalNumber=pagination.totalPageNumber;
}
private function onPageChanged(pageEvent:PaginationEvent):void{
Alert.show("我们要跳转到"+pageEvent.destinationPageNumber);
}
]]>
</fx:Script>
<s:VGroup>
<s:Button label="刷新1" click="studentRO.paginateStudent()"/>
<s:Button label="刷新2" click="studentRO.paginateProduct()"/>
<crap:PaginationHalo id="pagination1" pageChanged="onPageChanged(event)"/>
<s:DataGrid id="studentDG" width="100%" dataProvider="{studentList}">
<s:columns>
<s:ArrayList>
<s:GridColumn dataField="id" headerText="ID"/>
<s:GridColumn dataField="name" headerText="姓名"/>
</s:ArrayList>
</s:columns>
</s:DataGrid>
<crap:PaginationSpark id="pagination2" pageChanged="onPageChanged(event)"/>
<s:DataGrid id="productDG" width="100%" dataProvider="{productList}">
<s:columns>
<s:ArrayList>
<s:GridColumn dataField="id" headerText="ID"/>
<s:GridColumn dataField="name" headerText="姓名"/>
<s:GridColumn dataField="price" headerText="价格"/>
<s:GridColumn dataField="online" headerText="是否上架"/>
</s:ArrayList>
</s:columns>
</s:DataGrid>
</s:VGroup>
</s:Application>
效果如图所示
我们在这里新定义了一个PaginationEvent类,多了一个目标页数_destinationPageNumber这个属性.
对于分页控件,则可以用以下两种方式实现
1 Repeater.
barClient/src/com/crap/components/PaginationHalo.mxml内容如下
<?xml version="1.0" encoding="utf-8"?>
<s:HGroup xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="400" height="20">
<fx:Script>
<![CDATA[
import com.crap.event.PaginationEvent;
import mx.collections.ArrayCollection;
private var _totalNumber:int;
[Bindable]
private var _currentNumber:int;
[Bindable]
private var dataProvider:ArrayCollection=new ArrayCollection();
private function nextPage():void{
var event:PaginationEvent=new PaginationEvent("pageChanged",true,true);
event.destinationPageNumber=this._currentNumber+1;
this.dispatchEvent(event);
}
private function previousPage():void{
var event:PaginationEvent=new PaginationEvent("pageChanged",true,true);
event.destinationPageNumber=this._currentNumber-1;
this.dispatchEvent(event);
}
private function gotoPage(pageNumber:int):void{
var event:PaginationEvent=new PaginationEvent("pageChanged",true,true);
event.destinationPageNumber=pageNumber;
this.dispatchEvent(event);
}
public function set currentNumber(value:int):void
{
_currentNumber = value;
}
public function set totalNumber(value:int):void
{
_totalNumber = value;
dataProvider.removeAll();
for(var i:int=1;i<=value;i++){
this.dataProvider.addItem({pageNumber:i});
}
}
]]>
</fx:Script>
<fx:Metadata>
[Event(name="pageChanged", type="com.crap.event.PaginationEvent")]
</fx:Metadata>
<s:Button label="上一页" click="previousPage();">
</s:Button>
<mx:HBox>
<mx:Repeater id="rep" dataProvider="{dataProvider}">
<s:Button label="第{rep.currentItem.pageNumber}页"
click="gotoPage(event.target.getRepeaterItem().pageNumber);"
enabled="{rep.currentItem.pageNumber!=_currentNumber}">
</s:Button>
</mx:Repeater>
</mx:HBox>
<s:Button label="下一页" click="nextPage();">
</s:Button>
</s:HGroup>
Repeater是halo包里的,它必须出现在一个halo容器里,所以用一个HBox包住了它.注意它里面button的产生label可以用currentItem指代当前的Item,但是绑定handler的时候,要用getRepeaterItem().因为当handler被触发的时候,repeate已经结束了.
2 DataGroup
barClient/src/com/crap/components/PaginationSpark.mxml内容如下
<?xml version="1.0" encoding="utf-8"?>
<s:HGroup xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
width="400" height="20">
<fx:Metadata>
[Event(name="pageChanged", type="com.crap.event.PaginationEvent")]
</fx:Metadata>
<fx:Script>
<![CDATA[
import com.crap.event.PaginationEvent;
import mx.collections.ArrayCollection;
private var _totalNumber:int;
private var _currentNumber:int;
[Bindable]
private var dataProvider:ArrayCollection=new ArrayCollection();
public function set currentNumber(value:int):void
{
_currentNumber = value;
}
public function set totalNumber(value:int):void
{
_totalNumber = value;
dataProvider.removeAll();
for(var i:int=1;i<=value;i++){
this.dataProvider.addItem({pageNumber:i});
}
}
private function nextPage():void{
var event:PaginationEvent=new PaginationEvent("pageChanged",true,true);
event.destinationPageNumber=this._currentNumber+1;
this.dispatchEvent(event);
}
private function previousPage():void{
var event:PaginationEvent=new PaginationEvent("pageChanged",true,true);
event.destinationPageNumber=this._currentNumber-1;
this.dispatchEvent(event);
}
]]>
</fx:Script>
<s:Button label="上一页" click="previousPage();">
</s:Button>
<s:DataGroup dataProvider="{dataProvider}">
<s:layout>
<s:HorizontalLayout/>
</s:layout>
<s:itemRenderer>
<fx:Component>
<s:GridItemRenderer>
<s:Button label="第{data.pageNumber}页">
<fx:Script>
<![CDATA[
import com.crap.event.PaginationEvent;
]]>
</fx:Script>
<s:click>
<![CDATA[
var paginationEvent:PaginationEvent=new PaginationEvent("pageChanged",true,true);
paginationEvent.destinationPageNumber=data.pageNumber;
this.dispatchEvent(paginationEvent);
]]>
</s:click>
</s:Button>
</s:GridItemRenderer>
</fx:Component>
</s:itemRenderer>
</s:DataGroup>
<s:Button label="下一页" click="nextPage();">
</s:Button>
</s:HGroup>
在这两个自定义组件上,都可以使用元数据标签
<fx:Metadata>
[Event(name="pageChanged", type="com.crap.event.PaginationEvent")]
</fx:Metadata>
这样在引用组件的时候,可以直接添加event handler
<crap:PaginationHalo id="pagination1" pageChanged="onPageChanged(event)"/>
<crap:PaginationSpark id="pagination2" pageChanged="onPageChanged(event)"/>