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

功能要求:

(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);

}

效果图:

时间: 2024-09-20 04:15:51

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

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

功能要求: (1)比如每页显示2X2,总共2XN,每个item显示图片+文字(点击有链接). 如果单行水平滚动,可以用Horizontalscrollview实现. 如果是多行水平滚动,则结合Gridview(一般是垂直滚动的)和Horizontalscrollview实现. (2)水平滚动翻页,下面有显示当前页的icon. 1.实现自定义的HorizontalScrollView(HorizontalScrollView.java): 因为要翻页时需要传当前页给调用者,所以fling函数中自己

Android 中 SwipeLayout一个展示条目底层菜单的侧滑控件源码解析_Android

由于项目上的需要侧滑条目展示收藏按钮,记得之前代码家有写过一个厉害的开源控件 AndroidSwipeLayout 本来准备直接拿来使用,但是看过 issue 发现现在有不少使用者反应有不少的 bug ,而且代码家现在貌似也不进行维护了.故自己实现了一个所要效果的一个控件.因为只是实现我需要的效果,所以大家也能看到,代码里有不少地方我是写死的.希望对大家有些帮助.而且暂时也不需要 AndroidSwipeLayout 大而全的功能,算是变相给自己做的项目精简代码了. 完整示例代码请看:GitHu

Silverlight实用窍门系列:40.Silverlight中捕捉视频,截图保存到本地【附带实例源码】

在Silverlight中我们可以捕捉视频设备以制作视频会议系统,或者通过视频设备截图功能上传头像等功能. 下面我们通过一个简单的实例来访问视频设备,并且截取图像下载该截图文件至本地. 一.在Silverlight运行界面中我们检查系统默认摄像头和麦克风是否可用如下图: 二.我们看Xaml代码如下所示: <Grid x:Name="LayoutRoot" Background="White"> <Border BorderBrush="S

帮忙两个存储过程:查询表中第11-20行的数据(分页)spl server 和orcle两个版本

问题描述 谁帮忙写两个存储过程 急需:查询表中第11-20行的数据(分页)spl server 和orcle两个版本 谢谢 解决方案 SQLServer的 SELECT TOP 页大小 * FROM TestTable WHERE (ID > (SELECT MAX(id) FROM (SELECT TOP 页大小*页数 id FROM 表 ORDER BY id) AS T)) ORDER BY ID ----------------------------------------------

Android中RecyclerView上拉下拉,分割线,多条目的实例代码

//activity的xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity

Android管理与操作Wifi简单实例源码_Android

因为需要一直在弄网络的问题,今天看了一下Wifi的操作,经过整理,做出来了一个类,可能不全,但是个人感觉已经完全能够满足需要了,当然,里面的方法也有可能是错误的或者是不全的,这个类我没有进行完整的测试,只测试了其中的一些方法. 其实操作Wifi也是很简单的,主要使用以下几个对象或变量: private WifiManager wifiManager;// 声明管理对象OpenWifi private WifiInfo wifiInfo;// Wifi信息 private List<ScanRes

Android管理与操作Wifi简单实例源码

因为需要一直在弄网络的问题,今天看了一下Wifi的操作,经过整理,做出来了一个类,可能不全,但是个人感觉已经完全能够满足需要了,当然,里面的方法也有可能是错误的或者是不全的,这个类我没有进行完整的测试,只测试了其中的一些方法. 其实操作Wifi也是很简单的,主要使用以下几个对象或变量: private WifiManager wifiManager;// 声明管理对象OpenWifi private WifiInfo wifiInfo;// Wifi信息 private List<ScanRes

mvc中怎样使用微软自带的rdlc报表?求源码

问题描述 mvc中怎样使用微软自带的rdlc报表?求源码 mvc中怎样使用微软自带的rdlc报表?求源码 mvc中怎样使用微软自带的rdlc报表?求源码 mvc中怎样使用微软自带的rdlc报表?求源码

Android 中Crash时如何获取异常信息详解及实例

Android 中Crash时如何获取异常信息详解 前言: 大家都知道,Android应用不可避免的会发生crash,无论你的程序写的多完美,总是无法完全避免crash的发生,可能是由于Android系统底层的bug,也可能是由于不充分的机型适配或者是糟糕的网络状况.当crash发生时,系统会kill掉你的程序,表现就是闪退或者程序已停止运行,这对用户来说是很不友好的,也是开发者所不愿意看到的,更糟糕的是,当用户发生了crash,开发者却无法得知程序为何crash,即便你想去解决这个crash,