详解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);
 }

一、单行横向显示

详解Android使GridView横向水平滚动的实现方式

实现思路

  1. 在代码中动态设置GridView的NumColumns,使其等于GridView要显示的数据集合大小。

  2. 动态设置item项宽度,结合数据集合大小来设置GridView的总宽度。

  3. 使用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适配器就能实现单行横向滚动了,适配器使用常规的实现方式就行,这里就不贴了

二、多行横向分页显示

详解Android使GridView横向水平滚动的实现方式

实现思路

  1. 使用ViewPager实现左右翻页效果。

  2. 根据数据集合大小,计算出要显示的页数,并生成相应数量的GridView。

  3. 在GridView的Adapter适配器中,动态分配GridView需要显示的数据集合。

  4. 使用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

标签:gridview,水平滚动,Android
0
投稿

猜你喜欢

  • Java使用Log4j记录日志的方法详解

    2022-09-19 01:09:50
  • java实现模拟进度计量器

    2023-05-26 12:05:03
  • C#编程实现四舍五入、向上及下取整的方法

    2023-10-25 07:59:38
  • C#实现俄罗斯方块

    2023-10-29 05:44:27
  • Spring Boot如何防止重复提交

    2021-11-10 16:23:42
  • Android开发升级AGP7.0后的一些适配方法技巧

    2022-10-22 17:41:22
  • Spring中自动注入的两种方式总结

    2022-10-24 08:54:14
  • System 类 和 Runtime 类的常用用法介绍

    2023-11-21 10:07:55
  • mybatis <foreach>标签动态增删改查方式

    2022-07-27 20:03:16
  • java中List接口与实现类介绍

    2022-11-17 02:54:40
  • Springboot 内部服务调用方式

    2023-08-24 00:32:20
  • ArrayList详解和使用示例_动力节点Java学院整理

    2023-08-05 13:15:41
  • android之计时器(Chronometer)的使用以及常用的方法

    2021-05-26 12:27:33
  • Java创建树形结构算法实例代码

    2021-11-21 22:24:01
  • Java如何实现http接口参数和返回值加密

    2023-08-23 12:28:37
  • c#扩展datatable转json示例

    2022-08-19 10:44:55
  • SpringBoot工程下使用OpenFeign的坑及解决

    2022-08-24 18:00:38
  • SpringCloud实战之Zuul网关服务

    2023-01-30 11:33:53
  • java开发_图片截取工具实现原理

    2023-10-23 22:52:06
  • Java:"失效"的private修饰符

    2021-06-28 19:56:48
  • asp之家 软件编程 m.aspxhome.com