分页与分页导航条

虽然分页导航条的具体实现因平台而异,但其创建过程遵循一些基本规律,导航条的基本结构也是一致的。然而网上仅针对结构的相关介绍不多,这里略作分析。


Android分页导航 导航分布页_页码超链接

图1 分页导航条结构示意图

  如图所示,分页导航条按照页码链接的变化情况,可以分为固定显示区活动显示区两类:

1、固定显示区:通常包括“上一页”、“下一页”、“首页”、“尾页”等;

2、活动显示区:活动显示区本质上是一段动态的、连续的页码链接条。通常以当前页码为中心,向左右两边延伸一定的页数,并随当前页的改变而动态更新。

四个核心参数

  创建类似图1中的分页导航条,需要知道四个重要参数:

1、总页数N——用于跳转至最后一页;

2、当前页k——用于确定活动显示区的中心点;

3、活动区左边界lEnd——即示意图中L的值;

4、活动区右边界rEnd——示意图中R的值;

  这些参数如何获取呢?

1、对于总页数N,可以通过总数据量A和每页指定显示的数据量B来求取,采用向上取整法:N = (int) B/A + 1;

2、当前页k的值,要么从分页导航条的任意页码链接得到,要么在刚打开页面时指定第一页或某一页为当前页,即k=1或任意指定页码;

3、活动区的两个边界值lEnd、rEnd,则需要根据当前页的位置分情况讨论。设当前页码为k,需要向左显示lWing个页码,向右显示rWing个页码,显然k∈[1, N],则:

Android分页导航 导航分布页_分页_02

图2 左溢出示意图

(1)如图2所示,若k-lWing越界而小于1,即1≤k<1+lWing,则lEnd=1,rEnd=lEnd+lWing+rWing=1+lWing+rWing;

Android分页导航 导航分布页_页码条_03

图3 右溢出示意图

(2)如图3所示,若k+rWing越界而大于N,即N-rWing<k≤N,则rEnd=N,lEnd=rEnd-lWing-rWing=N-lWing-rWing;

Android分页导航 导航分布页_分页导航_04

图4 两端均不溢出示意图

(3)如图4所示,若k+rWing与k-lWing均在[1,N]内,即1+lWing≤k≤N-rWing,则lEnd=k-lWing,rEnd=k+rWing;

实际应用

  获取四个参数值后,就可以生成对应的导航条了。分页导航条其实是一个包含HTML内容的字符串,可以放入一个处理类中单独创建。下面给出的示例代码使用Hibernate分页,所需的四个参数被封装到一个名为Pager的类的实例中(假设左右边界长相等且rWing=lWing=3)。


创建导航条代码:


package action;

import org.apache.struts2.ServletActionContext;

import common.Pager;

public class Service {
	public static String getNavBarString(Pager pager, String nameSpace, String methodName){
		//target: 首页 <上一页  1 2 3 4 5 6 7  下一页> 尾页
		String navBar="";
		int page  = pager.getPgIndex();
		int MAX   = pager.getPgCount();
		int lWing = pager.getPgWing();
		int rWing = lWing;	//此处左右翼长度相等,实际工作中可能不等
		//初始化左右翼:
		int lEnd = 0;
		int rEnd = 0;
		//四种情况讨论并赋值:
		if( MAX <= (1+lWing+rWing) ){				
			lEnd = 1;
			rEnd = MAX;
		}else if( page>=1 && page<1+lWing){
			lEnd = 1;
			rEnd = 1 + lWing + rWing;
		}else if( page>=1+lWing && page<MAX-rWing ){
			lEnd = page - lWing;
			rEnd = page + rWing;
		}else if( page>=MAX-rWing && page<=MAX ){
			lEnd = MAX - lWing - rWing;
			rEnd = MAX;
		}
		
		String ctxPath = ServletActionContext.getServletContext().getContextPath();
		String ns = nameSpace;
		String mn = methodName;
		//生成“首页”和“上一页”:
		if(page==1){//首页位置不加超链接
			navBar += "首页    <上一页  ";
		}else{//非首页位置加上超链接
			navBar += String.format(
					"<a href='%s/%s/%s?pgIndex=%d'>首页</a>    ",ctxPath,ns,mn,1);
			navBar += String.format(
					"<a href='%s/%s/%s?pgIndex=%d'><上一页</a>%s",ctxPath,ns,mn,page-1,"  ");
		}
		//用for循环合成页码序列:
		for(int i=lEnd; i<=rEnd; i++){
			if(i==page){
			//当前页取消超链接,字体放大,标红,加粗:
				navBar += String.format(
						"<font color='red' size='4'><b>%d</b></font>  ", i);
			}else{
			//其他页面设置超链接:
				navBar += String.format(
						"<a href='%s/%s/%s?pgIndex=%d'>%d</a>  ", ctxPath,ns,mn,i,i);
			}
		}
		//生成“下一页”和“尾页”:
		if(page==MAX){//尾页位置不加超链接
			navBar += "下一页>    尾页";
		}else{//非尾页位置加上超链接
			navBar += String.format(
					"<a href='%s/%s/%s?pgIndex=%d'>下一页></a>",ctxPath,ns,mn,page+1);
			navBar += String.format(
					"    <a href='%s/%s/%s?pgIndex=%d'>尾页</a>",ctxPath,ns,mn,MAX);
		}
		return navBar;
	}
}


Pager类:


package common;

public class Pager {
	private int pgIndex;	//页码
	private int pgWing;		//左右边界长度
	private int pgSize;		//分页容量
	private int pgCount;	//总页数

	public int getPgIndex() {
		return pgIndex;
	}
	public void setPgIndex(int pgIndex) {
		this.pgIndex = pgIndex;
	}
	public int getPgWing() {
		return pgWing;
	}
	public void setPgWing(int pgWing) {
		this.pgWing = pgWing;
	}
	public int getPgSize() {
		return pgSize;
	}
	public void setPgSize(int pgSize) {
		this.pgSize = pgSize;
	}
	public int getPgCount() {
		return pgCount;
	}
	public void setPgCount(int pgCount) {
		this.pgCount = pgCount;
	}
	
}



Action中调用创建的导航条:


public String main(){
	preparePagedList_NavBar_Pager();
	return "coursePage";
}
private void preparePagedList_NavBar_Pager() {//为显示分页列表内容准备数据
	//在有列表数据的情况下,显示某一页的数据清单,并生成页码导航条
	if( cDao.getCourses().size()>0 ){
		//为获取单页显示的列表内容准备参数,封装到Pager对象中:
		Pager pager = new Pager();
		if(pgIndex == 0) { pgIndex = 1;	}	//首次访问时,默认显示第一页
		pager.setPgIndex(pgIndex);
		pager.setPgSize(SIZE);
		pager.setPgWing(WING);
		pager.setPgCount(cDao.getPageCount(SIZE));
		
		ActionContext actx = ActionContext.getContext(); 
		//获取分页导航条备用:
		actx.put("NAVBAR", Service.getNavBarString(pager, "course", "main"));
	}
}

前端调用部分:


<body>
	<!-- 显示页码导航条(左边界、右边界、当前页数) -->
	<p>${NAVBAR}</p>
</body>

运行结果:

Android分页导航 导航分布页_Android分页导航_05