Android开发中偶尔会遇到ScrollView嵌套GridView情景,但是谷歌官网是不推荐这种方式的,因为他们都有滚动条,嵌套使用会有冲突,无奈只能另谋他路,自定义个仿GridView的控件
1.定义attrs.xml文件
<declare-styleable name="GridLinearLayout"> <attr name="verticalSpace" format="dimension"/> <attr name="horizontalSpace" format="dimension"/> <attr name="rows" format="integer"/> <attr name="columns" format="integer"/> </declare-styleable>
2.定义GridLinearLayout文件
/** * 一个没有滚动条的LinearLayout,但是却很像GridView。 * 实际上,就是为了解决当GridView被包含在一个SrcollView中而却拥有两个滚动条相互排斥而做。 */ public class GridLinearLayout extends LinearLayout{ /**仿GridView单元格适配器*/ private BaseAdapter adapter; /**仿GridView列数*/ private int columns=1; /**仿GridView行数*/ private int rows=1; /**仿GridView填充的单元格总数*/ private int count; /**仿GridView单元格单击事件*/ private OnCellClickListener onCellClickListener; /**布局水平分割线宽度*/ private int horizontalSpace =1; /**布局垂直分割线宽度*/ private int verticalSpace =1; /** * 仿GridView构造方法 * @param context */ public GridLinearLayout(Context context) { super(context); } /** * 仿GridV构造方法 * @param context * @param attrs */ public GridLinearLayout(Context context, AttributeSet attrs) { super(context, attrs); initAttrs(context, attrs); } /*** * 加载xml文件设置的属性值 * @param context * @param attrs */ private void initAttrs(Context context ,AttributeSet attrs){ TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.GridLinearLayout); columns = typedArray.getInteger(R.styleable.GridLinearLayout_columns, 1); rows = typedArray.getInteger(R.styleable.GridLinearLayout_rows, 1); horizontalSpace = typedArray.getDimensionPixelSize(R.styleable.GridLinearLayout_horizontalSpace, 0); verticalSpace = typedArray.getDimensionPixelSize(R.styleable.GridLinearLayout_verticalSpace, 0); typedArray.recycle(); } /** * 构造水平显示LinearLayout用于填充cell * @return */ private LinearLayout rowLinearLayout(){ LinearLayout itemLinearLayout = new LinearLayout(getContext()); itemLinearLayout.setOrientation(LinearLayout.HORIZONTAL); itemLinearLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); itemLinearLayout.setGravity(Gravity.LEFT); return itemLinearLayout; } /** * 仿GridView将适配器单元格绑定到当前LinearLayout中 * @return */ public void bindLinearLayout() { removeAllViews(); rows = getSpecialRows(true); if(rows==-1){ return; } for(int r=0;r<rows;r++){ LinearLayout itemRow = rowLinearLayout(); for(int c=0;c<columns;c++){ final int index = r*columns+c; View cellView = adapter.getView(index, null, null); cellView.setLayoutParams(cellLayoutParams(index)); if(index<count||index==(count-1)){ itemRow.addView(cellView,c); cellView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if(onCellClickListener!=null){ onCellClickListener.onCellClick(index); } } }); if(index==(count-1)){ addView(itemRow, r); return; } }else{ return; } } addView(itemRow, r); } } /** * 获取屏幕宽度用于均分一行LinearLayout各个Cell * @return */ @SuppressWarnings("deprecation") private int screenWidth(){ /*Point outSize = new Point(); WindowManager windowManager = (WindowManager) getContext().getSystemService(Service.WINDOW_SERVICE); Display display = windowManager.getDefaultDisplay(); display.getSize(outSize); return outSize.x;*/ int screenWidth; WindowManager windowManager = (WindowManager) getContext().getSystemService(Service.WINDOW_SERVICE); Display display = windowManager.getDefaultDisplay(); screenWidth = display.getWidth(); return screenWidth; } /** * 设置当前单元格边距, * 每一行第一个左边距为0底边距为horizontalSpace, * 其他单元格左边距为verticalSpace底边距为horizontalSpace * @param index 单元格序数 * @return */ private LayoutParams cellLayoutParams(int index){ LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(cellWidth(),LayoutParams.WRAP_CONTENT); if(index%columns==0){ params.setMargins(0, 0, 0, horizontalSpace); return params; }else{ params.setMargins(verticalSpace, 0, 0, horizontalSpace); return params; } } /*** * 计算单元格宽度 * @return */ private int cellWidth(){ int cellScreenWidth = screenWidth()-(columns-1)*verticalSpace; return cellScreenWidth/columns; } /*** * 是否按列的倍数返回行数 * @param isSpecial TRUE:返回列的倍数行数,FALSE:有多少行显示多少行 * @return 返回-1时表示列数为0 */ private int getSpecialRows(boolean isSpecial){ try { if(isSpecial){ return count/columns; }else{ return (int) Math.ceil((double)count/columns); } } catch (Exception e) { e.printStackTrace(); return -1; } } /*** * 返回该控件的适配器 * @return */ public BaseAdapter getAdapter() { return adapter; } /** * 设置该控件的适配器 * @param adapter 自定义适配器 */ public void setAdapter(BaseAdapter adapter) { this.adapter = adapter; this.count = adapter.getCount(); } /** * 返回该控件的列数 * @return */ public int getColumns() { return columns; } /** * 设置该控件的列数 * @param columns 列数 */ public void setColumns(int columns) { this.columns = columns; } /** * 返回该控件的行数 * @return */ public int getRows() { return rows; } /** * 设置该控件的行数 * @param rows 行数 */ public void setRows(int rows) { this.rows = rows; } /** * 返回该控件各单元格水平间距 * @return */ public int getHorizontalSpace() { return horizontalSpace; } /** * 设置该控件各单元格水平间距 * @param horizontalSpace 间距 */ public void setHorizontalSpace(int horizontalSpace) { this.horizontalSpace = horizontalSpace; } /** * 返回该控件各单元格垂直间距 * @return */ public int getVerticalSpace() { return verticalSpace; } /** * 设置该控件各单元格垂直间距 * @param verticalSpace 间距 */ public void setVerticalSpace(int verticalSpace) { this.verticalSpace = verticalSpace; } public interface OnCellClickListener{ public void onCellClick(int index); } /** * 监听响应单元格单击事件 * @param onCellClickListener 单元格单击事件接口 */ public void setOnCellClickListener(OnCellClickListener onCellClickListener){ this.onCellClickListener = onCellClickListener; } }
3.可以将此控件嵌套在ScrollView中,然后调用方式如下
//获取控件 glFriendRecommendTask = (GridLinearLayout) view.findViewById(R.id.glFriendRecommendTask); //设置控件适配器,适配器按正常方式定义即可 glFriendRecommendTask.setAdapter(friendRecommendTaskAdapter); //如果需要监听适配器中的单击事件可在此处触发 glFriendRecommendTask.setOnCellClickListener(new OnCellClickListener() { @Override public void onCellClick(int index) { } }); //设置该控件显示的列数 glFriendRecommendTask.setColumns(3); //最后调用绑定方法即可 glFriendRecommendTask.bindLinearLayout();
相关推荐
在上面的布局文件中,我们使用了自定义的 MyGridView 控件来代替原来的 GridView 控件,从而解决了 ScrollView 嵌套 GridView 不能滚动的问题。 解决 ScrollView 嵌套 GridView 不能滚动的问题的关键是重写 ...
然而,由于ScrollView自身并不支持滚动事件的监听,因此当我们在ScrollView中嵌套可滚动的组件如ListView或GridView时,可能会遇到滚动冲突问题。为了解决这个问题,开发者需要手动处理滚动事件,或者选择使用如...
首先,理解ScrollView的基本工作原理是解决问题的关键。ScrollView本质上是一个线性布局(LinearLayout)的扩展,它可以容纳一个或多个子视图,并允许用户滚动查看超出屏幕范围的内容。当一个ScrollView包含另一个...
解决这个问题的方法是自定义一个ScrollView,重写onInterceptTouchEvent()方法,让ScrollView只处理垂直方向的滑动,将水平滑动事件传递给内部的GridView。 具体步骤如下: 1. 创建一个新的ScrollView子类,比如...
本篇文章将详细探讨“ScrollView嵌套问题总汇”,包括S嵌L(ScrollView嵌套ListView)、S嵌G(ScrollView嵌套GridView)、S嵌S(ScrollView嵌套ScrollView)、H嵌G(HorizontalScrollView嵌套GridView)以及S嵌(H嵌G...
1、ScrollView嵌套listView、GridView时滑动冲突,自定义 ListView、GridView; 2、自定义ScrollView,解决 当有横向的滑动操作时,与ScrollView上下滑动冲突; 2、横向ListView
在Android开发中,有时我们需要在一个页面中展示大量的数据,这时可能会使用ScrollView来实现滚动效果,同时内部嵌套一个GridView以实现列表布局。然而,当ScrollView和GridView组合使用时,经常会出现显示不全的...
总的来说,解决ScrollView嵌套ListView问题需要根据具体应用场景选择合适的方法。NestedScrollView、RecyclerView、HeaderView以及自定义ViewGroup都是有效的策略,开发者应根据项目需求和性能考虑来选择最佳方案。...
android 自定义gridView 按日期显示图片和视频 galleryDemo android 自定义gridView 按日期显示图片和视频 galleryDemo android 自定义gridView 按日期显示图片和视频 galleryDemo 免费下载 给个好评!
希望有帮助,我自己摸索一段时间的来的,比较简单一个类就可以实现,添加使用内部类的方法
总之,嵌套ScrollView、ListView和GridView需要开发者对Android视图系统有深入理解,合理使用这些组件可以创建出复杂而功能丰富的用户界面,但同时也需要妥善处理可能出现的滚动冲突和性能问题。在实际项目中,应该...
总的来说,解决ScrollView与GridView和ListView嵌套冲突的关键在于合理规划布局,选择合适的组件,以及进行必要的自定义和优化。通过以上方法,我们可以实现良好的用户体验,同时避免滚动冲突带来的问题。在实际开发...
在Android开发中,GridView是一种非常常见的布局控件,它允许我们以网格的形式展示数据,通常用于创建像照片墙、应用列表等界面。本教程将深入探讨如何自定义各种风格的GridView,包括刷新、加载和横向展示等特性。 ...
总之,Android开发中ScrollView嵌套GridView的问题是一个常见的挑战,通过自定义GridView或使用更现代的滚动组件,我们可以有效地解决这个问题,确保用户能够完整地浏览所有内容。同时,持续关注Android API的更新和...
为了解决这个问题,我们通常需要自定义一个继承自 GridView 的类,重写其中的部分方法以适应在 ScrollView 内部使用的需求。以下是一些关键步骤: 1. **创建自定义 GridView 类**: 首先,创建一个新的类,如 `...
当ScrollView中嵌套ListView或者GrideView时,listView和GrideView不能完全显示的时候
本主题聚焦于如何在Android应用中实现一个"最简单的gridview嵌套gridview"的场景,并解决滑动冲突问题。 首先,让我们了解一下GridView的基本概念。GridView是一种布局管理器,它将视图(如图片、文字等)以网格的...
在某些情况下,仅仅通过设置 `padding` 或调整滚动行为可能无法完全解决问题。这时候,使用自定义 Adapter 可以提供更加灵活的方式来控制 GridView 的布局。 **自定义 Adapter 示例** ```java public class ...
在Android开发中,"Android书架(自定义GridView)"是一个常见的应用场景,通常用于实现类似电子书库或图书展示的功能。书架效果是通过自定义GridView来达成的,因为GridView是一种可以灵活展示多行多列数据的视图...