欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android中实现多行、水平滚动的分页的Gridview实例源码

程序员文章站 2023-12-01 20:17:34
功能要求: (1)比如每页显示2x2,总共2xn,每个item显示图片+文字(点击有链接)。 如果单行水平滚动,可以用horizontalscrollview实现。 如果是...
功能要求:
(1)比如每页显示2x2,总共2xn,每个item显示图片+文字(点击有链接)。
如果单行水平滚动,可以用horizontalscrollview实现。
如果是多行水平滚动,则结合gridview(一般是垂直滚动的)和horizontalscrollview实现。
(2)水平滚动翻页,下面有显示当前页的icon。

1.实现自定义的horizontalscrollview(horizontalscrollview.java):
因为要翻页时需要传当前页给调用者,所以fling函数中自己实现而不要调用父类的fling。
复制代码 代码如下:

public class drawerhscrollview extends horizontalscrollview {
private static final string tag = "drawerhscrollview";

private idrawerpresenter drawerpresenter = null;
private int currentpage = 0;
private int totalpages = 1;
private static hashtable<integer, integer> positionlefttopofpages = new hashtable();
public drawerhscrollview(context context) {
super(context);
}
public drawerhscrollview(context context, attributeset attrs) {
super(context, attrs);
}
public drawerhscrollview(context context, attributeset attrs, int defstyle) {
super(context, attrs, defstyle);
}

public void cleanup(){
currentpage = 0;
totalpages = 1;
drawerpresenter = null;
if(positionlefttopofpages != null){
positionlefttopofpages.clear();
}
}

public void setparameters(int totalpages, int currentpage, int scrolldisx) {
log.d(tag, "~~~~~setparameters totalpages:"+totalpages +",currentpage:"+ currentpage +",scrolldisx:"+scrolldisx);
this.totalpages = totalpages;
this.currentpage = currentpage;
positionlefttopofpages.clear();
for (int i = 0;i<totalpages;i++){
int posx = (scrolldisx) * i;
positionlefttopofpages.put(i, posx);
log.d(tag, "~~~~~setparameters i:"+i +",posx:"+posx);
}
smoothscrollto(0, 0);
}

public void setpresenter(idrawerpresenter drawerpresenter ) {
this.drawerpresenter = drawerpresenter;
}

@override
public void fling(int velocityx) {
log.v(tag, "-->fling velocityx:"+velocityx);
boolean change_flag = false;
if (velocityx > 0 && (currentpage < totalpages - 1)){
currentpage++;
change_flag = true;
} else if (velocityx < 0 && (currentpage > 0)){
currentpage--;
change_flag = true;
}
if (change_flag){
int postionto = (integer)positionlefttopofpages.get(new integer(currentpage)).intvalue();
log.v(tag, "------smoothscrollto posx:"+postionto);
smoothscrollto(postionto, 0);
drawerpresenter.dispatchevent(totalpages, currentpage);
}
//super.fling(velocityx);
}
}

2.布局文件activity_main.xml:
复制代码 代码如下:

<com.example.multilinegridview.drawerhscrollview
android:id="@+id/hscrollview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:scrollbars="none"
android:layout_below="@id/layout_drawer_top"
android:layout_above="@id/layout_pagenumber"
android:background="#cccccc" >
<linearlayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<gridview
android:id="@+id/gridview"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</linearlayout>
</com.example.multilinegridview.drawerhscrollview>

3.idrawerpresenter接口(idrawerpresenter.java):
复制代码 代码如下:

public interface idrawerpresenter {
idrawerpresenter getinstance();
void dispatchevent(int totalpages, int currentpage);
}

4.draweritem
复制代码 代码如下:

<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout_item"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_gravity="center"
android:background="#ffffff">
<imageview
android:id="@+id/ivicon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher" />
<textview
android:id="@+id/tvtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="优惠券1"
android:textcolor="#000000"
android:textstyle="bold"/>
</linearlayout>

5.mainactivity.java
(1)实现idrawerpresenter接口,在horizontalscrollview里通过idrawerpresenter接口来返回当前页,从而更新pageindicator。
复制代码 代码如下:

@override
public idrawerpresenter getinstance() {
return this;
}
@override
public void dispatchevent(int totalpages, int currentpage) {
log.v(tag, "~~~~dispatchevent currentpage:" + currentpage);
message msg = message.obtain();
msg.what = msg_drawer_update_page_layout;
msg.arg1 = totalpages;
msg.arg2 = currentpage;
handler.sendmessage(msg);
}

(2)pageitemimageview和page indicator的更新
pageitemimageview显示normal的page indicator,之后再将当前页的图片换成selected。
复制代码 代码如下:

protected class pageitemimageview extends imageview {
public pageitemimageview(context context) {
super(context);
bitmap bitmap = bitmapfactory.decoderesource(getresources(),
r.drawable.icon_page_normal);
this.setimagebitmap(bitmap);
}
}
public void updatedrawerpagelayout(int total_pages, int sel_page) {
log.e(tag, "~~~updatebookspagelayout total_pages:"+total_pages+",sel_page:"+sel_page);
layout_pagenumber.removeallviews();
if (total_pages <= 0 || sel_page < 0 || sel_page >= total_pages){
log.e(tag, "total_pages or sel_page is outofrange.");
return;
}
for (int i = 0;i< total_pages;i++){
if (i != 0){
linearlayout.layoutparams params = new linearlayout.layoutparams(layoutparams.wrap_content, layoutparams.wrap_content);
params.setmargins(5, 0, 0, 0);
layout_pagenumber.addview(new pageitemimageview(this), params);
} else {
layout_pagenumber.addview(new pageitemimageview(this));
}
}
pageitemimageview selitem = (pageitemimageview) layout_pagenumber.getchildat(sel_page);
bitmap bitmap = bitmapfactory.decoderesource(getresources(), r.drawable.icon_page_selected);
selitem.setimagebitmap(bitmap);
}

(3)drawerlistadapter
复制代码 代码如下:

private class drawerlistadapter extends baseadapter {
private final string tag = "mylistadapter";
private layoutinflater minflater;
private linearlayout layout_item;
private textview tvtitle;
private imageview ivicon;
private final context context;
private int colwid;
private int colhei;
public drawerlistadapter(context context, int colwid, int colhei) {
this.context = context;
this.colwid = colwid;
this.colhei = colhei;
minflater = (layoutinflater) context
.getsystemservice(context.layout_inflater_service);
}
public int getcount() {
return draweritemlist.size();
}
public object getitem(int position) {
return draweritemlist.get(position);
}
public long getitemid(int position) {
return position;
}
public view getview(int position, view convertview, viewgroup parent) {
draweritem item = draweritemlist.get(position);
if (convertview == null) {
convertview = minflater.inflate(r.layout.drawer_item, null);
layout_item = (linearlayout) convertview
.findviewbyid(r.id.layout_item);
ivicon = (imageview) convertview.findviewbyid(r.id.ivicon);
tvtitle = (textview) convertview.findviewbyid(r.id.tvtitle);
if (colhei != 0 && colwid != 0) {
linearlayout.layoutparams params = new linearlayout.layoutparams(
colwid, colhei - 30);
ivicon.setlayoutparams(params);
}
convertview.settag(layout_item);
} else {
layout_item = (linearlayout) convertview.gettag();
}
ivicon.setimageresource(r.drawable.ic_launcher);
tvtitle.settext(string.valueof(position));
return convertview;
}
}

(4)draweritemclicklistener:
实现onitemclicklistener。
(5) updatedrawerlayout
获得data的size后,可以算出列数来得到固定行。
intnumcols = (draweritemlist.size() - 1) / 2 + 1
再算出gridview的width。因每页可显示2列,最后一页可能右侧没有,为了翻页顺滑,可以给gridview增加一列空白。
intgridviewwid = numcols * colwid + (numcols + 1) * spaceing;
if(numcols % 2 == 1){
gridviewwid+= colwid + spaceing;
}
复制代码 代码如下:

public void updatedrawerlayout() {
if ((draweritemlist == null) || (draweritemlist.size() == 0)) {
log.d(tag, "itemlist is null or empty");
return;
}
if (!hasmeasured){
log.d(tag, "hasmeasured is false");
return;
}
int scrollwid = hscrollview.getwidth();
int scrollhei = hscrollview.getheight();
if (scrollwid <= 0 || scrollhei <= 0){
log.d(tag, "scrollwid or scrollhei is less than 0");
return;
}

int spaceing = 10;
int colwid = (scrollwid - spaceing * 3) / 2;
int colhei = (scrollhei - spaceing * 3) / 2;
int numcols = (draweritemlist.size() - 1) / 2 + 1;
int gridviewwid = numcols * colwid + (numcols + 1) * spaceing;
// if numcols is odd (like 5), add blank space
if (numcols % 2 == 1){
gridviewwid += colwid + spaceing;
}

layoutparams params = new layoutparams(gridviewwid, scrollhei);
gridview.setlayoutparams(params);
gridview.setcolumnwidth(colwid);
gridview.sethorizontalspacing(spaceing);
gridview.setverticalspacing(spaceing);
gridview.setstretchmode(gridview.no_stretch);
gridview.setnumcolumns(numcols);
adapter = new drawerlistadapter(this, colwid, colhei);
listener = new draweritemclicklistener();
gridview.setadapter(adapter);
gridview.setonitemclicklistener(listener);
int pagenum = (draweritemlist.size() - 1) / 4 + 1;
hscrollview.setparameters(pagenum, 0, scrollwid - spaceing);
updatedrawerpagelayout(pagenum, 0);
}

效果图:
Android中实现多行、水平滚动的分页的Gridview实例源码