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);
- }
效果图:
Android中如何实现多行、水平滚动的分页的Gridview?的更多相关文章
- Android中仿淘宝首页顶部滚动自定义HorizontalScrollView定时水平自动切换图片
Android中仿淘宝首页顶部滚动自定义HorizontalScrollView定时水平自动切换图片 自定义ADPager 自定义水平滚动的ScrollView效仿ViewPager 当遇到要在Vie ...
- Android 使用RecyclerView实现多行水平分页的GridView效果和ViewPager效果
前些天看到有人在论坛上问这种效果怎么实现,没写过也没用过这个功能,网上查了一下,大多是使用ViewPager+GridView或者HorizontalScrollView+GridView实现,不过貌 ...
- 在ASP.NET MVC5中实现具有服务器端过滤、排序和分页的GridView
背景 在前一篇文章<[初学者指南]在ASP.NET MVC 5中创建GridView>中,我们学习了如何在 ASP.NET MVC 中实现 GridView,类似于 ASP.NET web ...
- [转]在ASP.NET MVC5中实现具有服务器端过滤、排序和分页的GridView
本文转自:http://www.cnblogs.com/powertoolsteam/p/MVC5_GridView_2.html 背景 在前一篇文章<[初学者指南]在ASP.NET MVC 5 ...
- Android中如何使用命令行查看内嵌数据库SQLite3
转载博客:http://www.linuxidc.com/Linux/2011-06/37135.htm 在上图中,除了最后一个红色的方框,其它方框都是adb shell下的命令. [1]在Andro ...
- [Selenium] Android 中旋转屏幕,触摸,滚动
package com.learingselenium.android; import junit.framework.TestCase import org.openqa.selenium.Rota ...
- Android中Gallery和ImageSwitcher同步自动(滚动)播放图片库
本文主要内容是如何让Gallery和ImageSwitcher控件能够同步自动播放图片集 ,看起来较难,然而,实现的方法非常简单, 请跟我慢慢来.总的来说,本文要实现的效果如下图:(截图效果不怎么好) ...
- Android ViewPager实现多个图片水平滚动
1.示意图 2.实现分析 (1).xml配置 <!-- 配置container和pager的clipChildren=false, 并且指定margi ...
- Android中通过Java代码实现ScrollView滚动视图-以歌词滚动为例
场景 实现效果如下 注: 博客: https://blog.csdn.net/badao_liumang_qizhi 关注公众号 霸道的程序猿 获取编程相关电子书.教程推送与免费下载. 实现 将布局改 ...
随机推荐
- Chapter12:动态内存
智能指针——shared_ptr 为了更容易地使用动态内存,新的标准提供了智能指针来管理动态对象.智能指针的行为类似常规指针,重要的区别是它负责自动释放指向的对象. 智能指针的使用方式与普通指针类似. ...
- 在logopond中看到的优秀设计随想
本随笔仅仅只是自己对于设计作品的想法,不喜勿喷~ 昨日看到关于大神配色的文章,决定在logopond网站中看看优秀的作品,以为自己的配色找找灵感,学习学习,对自己有很强的震撼力的有: 以女性高跟性的抽 ...
- iOS学习中的一些误区
周二拿到offer之后,周三确定了去哪家,今天周四.今天是一个例外.中午写更新. 人到了不同的阶段,最重要的就是要更新自己的方法论.也就是说,不能穿新鞋,走老路,这样人就不会有大的突破. 下面我就分析 ...
- vim 7.4 编译安装
(1): 在安装新版本的Vim之前,你需要卸载原来安装的老版本Vim,依次在终端下执行下列命令: sudo apt-get remove vim sudo apt-get remove vim-run ...
- JavaScript之Object
两种简单的JavaScript中定义对象的方式: 在JavaScript中,可以动态添加对象的属性,也可以动态删除对象的属性. var object=new object(); //alert(obj ...
- 移动端和web端前端UI库—Frozen UI、WeUI、SUI Mobile
web http://www.pintuer.com/ 拼图 http://www.h-ui.net/ http://www.layui.com/ 很厉害的一个个人产品 http://amazeui ...
- 监听mysql是否挂了
监听mysql是否挂了,如果挂了就重启mysql 方式一: #!/bin/bash pgrep -x mysqld &> /dev/null if [ $? -ne 0 ] then e ...
- reds pub/sub官方文档翻译
Publish / Subscribe发布/订阅 redis-py includes a PubSub object that subscribes to channels and listens f ...
- Unity3D 200个插件免费分享
插件清单: 2D_Toolkit_1.51 动画开发插件包 FingerGestures 触摸插件 ORK_Okashi_RPG_Kit Unity3D角色扮演 ...
- Hadoop学习笔记(1)
Hadoop是什么?先问一下百度吧: [百度百科]一个分布式系统基础架构,由Apache基金会所开发.用户可以在不了解分布式底层细节的情况下,开发分布式程序.充分利用集群的威力进行高速运算和存储. H ...