详解Android使GridView横向水平滚动的实现方式
作者:ZHU_文涛 发布时间:2023-01-04 16:59:19
Android为我们提供了竖直方向的滚动控件GridView,但如果我们想让它水平滚动起来,就需要自己实现了。
以下使用的测试数据datas集合都为List<ResolveInfo>类型,用来存储手机中的所有App
public static List<ResolveInfo> getAppData(Context context) {
PackageManager packageManager = context.getPackageManager();
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
return packageManager.queryIntentActivities(mainIntent, 0);
}
一、单行横向显示
实现思路
在代码中动态设置GridView的NumColumns,使其等于GridView要显示的数据集合大小。
动态设置item项宽度,结合数据集合大小来设置GridView的总宽度。
使用HorizontalScrollView包裹GridView
具体实现
关键代码
/**
* 将GridView改成单行横向布局
*/
private void changeGridView() {
// item宽度
int itemWidth = DensityUtil.dip2px(this, 100);
// item之间的间隔
int itemPaddingH = DensityUtil.dip2px(this, 1);
int size = datas.size();
// 计算GridView宽度
int gridviewWidth = size * (itemWidth + itemPaddingH);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
gridviewWidth, LinearLayout.LayoutParams.MATCH_PARENT);
mContentGv.setLayoutParams(params);
mContentGv.setColumnWidth(itemWidth);
mContentGv.setHorizontalSpacing(itemPaddingH);
mContentGv.setStretchMode(GridView.NO_STRETCH);
mContentGv.setNumColumns(size);
}
这里用到的dip2px方法是根据手机的分辨率从 dp 的单位 转成为 px(像素)
/**
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
* @param context 上下文
* @param dpValue dp值
* @return px值
*/
public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
在布局文件中,使用HorizontalScrollView包裹GridView
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<GridView
android:id="@+id/gv_horizontal_gridview_line"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none"/>
</LinearLayout>
</HorizontalScrollView>
通过以上设置,再加上Adapter适配器就能实现单行横向滚动了,适配器使用常规的实现方式就行,这里就不贴了
二、多行横向分页显示
实现思路
使用ViewPager实现左右翻页效果。
根据数据集合大小,计算出要显示的页数,并生成相应数量的GridView。
在GridView的Adapter适配器中,动态分配GridView需要显示的数据集合。
使用List保存多个GridView实例并传入ViewPager适配器中,一页ViewPager对应一个GridView实例。
具体实现
数据量很多时,需要进行分页,计算方式
需要页数 = 总数量 ÷ 每页显示数量
有些整除不了的,就需要使用Math.ceil()函数,向上取整
关键代码
/**
* 获取系统所有的应用程序,根据每页需要显示的item数量,生成相应数量的GridView页面
*/
private void initViews(List<ResolveInfo> datas) {
int dataSize = datas.size();
// (需要页数 = 总数量 ÷ 每页显示数量)向上取整数
int PageCount = (int) Math.ceil(dataSize / APP_SIZE);
mGridViewList = new ArrayList<>();
for (int i = 0; i <= PageCount; i++) {
GridView appPage = new GridView(this);
appPage.setAdapter(new HorizontalGvAdapter(this, datas, i));
appPage.setNumColumns(4);
appPage.setVerticalSpacing(1);
appPage.setHorizontalSpacing(1);
appPage.setHorizontalScrollBarEnabled(false);
appPage.setVerticalScrollBarEnabled(false);
mGridViewList.add(appPage);
}
if(dataSize % APP_SIZE == 0){
mGridViewList.remove(mGridViewList.size()-1);
PageCount--;
}
mGvPagerAdapter = new HorizontalGvPagerAdapter(mGridViewList);
viewPager.setAdapter(mGvPagerAdapter);
viewPager.addOnPageChangeListener(new MyPageChangeListener());
addDot(PageCount);
}
当总数量 ÷ 每页显示数量刚好被整除时,会出现一页空白页的情况,这个时候需要去掉多出来的那一页
if(dataSize % APP_SIZE == 0){
mGridViewList.remove(mGridViewList.size()-1);
PageCount--;
}
Adapter在创建初期就要对显示的数据进行控制,因为这里每个GridView都有一个单独的Adapter,所以需要对其显示的datas进行动态计算
通过传入构造方法的数据进行动态计算,可以得出数据开始加载的位置、结束加载的位置
HorizontalGvAdapter的构造方法:
/**
* 所有应用数据
*/
private List<ResolveInfo> mAppDatas = new ArrayList<ResolveInfo>();
public HorizontalGvAdapter(Context context, List<ResolveInfo> list, int page) {
this.mContext = context;
// 开始加载的位置
int pageStart = page * HorizontalGridViewAct.APP_SIZE;
// 结束加载的位置
int pageEnd = pageStart + HorizontalGridViewAct.APP_SIZE;
while ((pageStart < list.size()) && (pageStart < pageEnd)) {
mAppDatas.add(list.get(pageStart));
pageStart++;
}
}
如果需要加小圆点的话,可以先在布局中用一个空LinearLayout当小圆点的容器
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:orientation="vertical">
<android.support.v4.view.ViewPager
android:id="@+id/vp_horizontal_gridview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_gravity="center"
android:background="#c5c5c5"
android:scaleType="fitXY"/>
<!-- 底部小圆点 -->
<LinearLayout
android:id="@+id/ll_dot_container"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#4b4b4b"
android:layout_gravity="bottom"
android:gravity="center"
android:orientation="horizontal"/>
</LinearLayout>
然后在代码中用List<View>来保存创建的小圆点
// 放圆点的list
private List<View> dotViewsList;
/**
* 创建指定数量的圆点
* @param dotNumber viewPager的数量
*/
private void addDot(int dotNumber) {
if (null == dotViewsList) {
dotViewsList = new ArrayList<View>();
}
LinearLayout dotLayout = (LinearLayout) findViewById(R.id.ll_dot_container);
for (int i = 0; i <= dotNumber; i++) {
ImageView dotView = new ImageView(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT);
// 圆点与圆点之间的距离
params.leftMargin = 10;
params.rightMargin = 10;
// 圆点的大小
params.height = 15;
params.width = 15;
dotLayout.addView(dotView, params);
dotViewsList.add(dotView);
}
// 设置圆点默认选中第一个
setDotShow(0);
}
动态添加完小圆点后,就可以设置它们的选中状态了,这里只需要更改对应小圆点的图片显示就行
/**
* 显示底部圆点导航
* @param position 选中哪个圆点
*/
private void setDotShow(int position){
if (dotViewsList == null){
return;
}
for (int i = 0; i < dotViewsList.size(); i++) {
if (i == position) {
dotViewsList.get(position).setBackgroundResource(R.drawable.ic_dot_on);
} else {
dotViewsList.get(i).setBackgroundResource(R.drawable.ic_dot_off);
}
}
}
三、总结
来源:http://blog.csdn.net/zhuwentao2150/article/details/70211610?utm_source=tuicool&utm_medium=referral
猜你喜欢
- SpringMVC文件下载说明: 在 SpringMVC 中,通过返回 ResponseEntity的类型,可以实现文件下载的功能案例演示1
- 拼图小游戏,学习阶段。很多不足,改进了一下演示图片:J_Puzzle.javaimport java.awt.BorderLayout;im
- 本期文章源码:GitHub一文彻底搞懂《并查集》!概念并查集是一种树型的数据结构,用于处理一些不相交集合的合并及查询问题(即所谓的并、查)。
- 面试题1:谈一下你对 Nginx 的理解Nginx 是一款自由的、开源的、高性能的 HTTP 服务器和反向代理服务器;同时也是一个 IMAP
- 委托(delegate)是一种可以把引用存储为函数的类型,这类似于c++中的函数指针。回调函数c++中的回调函数,就是用函数指针来实现的。类
- 在Android系统上开发游戏是Android开发学习者所向往的,有成就感也有乐趣,还能取得经济上的报酬。那怎样开发Androi
- 前言Postman是一款Http请求模拟工具.它可以模拟各种Http Request,使用起来十分的方便.使用背景利用Spring Boot
- 概述java移位符主要包括3种:运算符名称>>左移运算符<<有符号右移运算符<<<无符号右移运算符
- 代码一/// <summary> /// 截断字符串 /// </su
- OAuth 简介OAuth 是由 Blaine Cook、Chris Messina、Larry Halff 及 David Recordo
- 无论是Android开发或者是其他移动平台的开发,ListView肯定是一个大咖,那么对ListView的操作肯定是不会少的,上一篇博客介绍
- C#事件实例详解C#和JAVA有许多相似的地方,设计思想差不多,语法及其相像,均传承自面向对象设计思想,灵感来自C++并取其精华去其“糟粕(
- 实现二分法查找二分法查找,需要数组内是一个有序的序列二分查找比线性查找:数组的元素数越多,效率提高的越明显二分查找的效率表示:O(log2N
- “Java is still not dead—and people are starting to figure that out.”本教
- 1、使用FileStream读写文件 文件头:using System;using System.Collections.Gene
- 工欲善其事,必先利其器,对于想要深入学习Android源码,必须先掌握Android编译命令.一、引言关于Android Build系统,这
- spring cloud gateway获取请求的真实地址在使用spring cloud gateway的时候,路由一般配置为服务名例如 l
- 为什么要学习Android与H5互调?微信,QQ空间等大量软件都内嵌了H5,不得不说是一种趋势。Android与H5互调可以让我们的实现混合
- 前言很多微信公众号中需要生成推广海报的功能,粉丝获得专属海报后可以分享到朋友圈或发给朋友,为公众号代言邀请好友即可获取奖励的。海报自带渠道二
- 目录课设要求相关知识点1.服务端能够看到所有在线用户2.服务端能够强制用户下线3.客户端能够看到所有在线用户4.客户端要求能够向某个用户发送