求教高手,android下如何让gridview 行数能够水平滚动,行数固定是三行

Android 横向列表实现,可左右滑动,如下图
1.主界面布局代码:activity_main.xml
a.包裹HorizontalScrollView控件是GirdView横向滚动的基本条件b.GirdView外包裹LinearLayout是java代码中参数设置的必要条件
&?xml version="1.0" encoding="utf-8"?&
&LinearLayout xmlns:android="/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" &
&HorizontalScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp" &
&LinearLayout
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_margin="10dp" &
android:id="@+id/grid"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:numColumns="auto_fit"
android:stretchMode="spacingWidthUniform" &
&/GridView&
&/LinearLayout&
&/HorizontalScrollView&
&/LinearLayout&
2.主界面GridView列表子项布局文件:list_item.xml
&?xml version="1.0" encoding="utf-8"?&
&LinearLayout xmlns:android="/apk/res/android"
android:id="@+id/itemlayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" &
&ImageView
android:id="@+id/ItemImage"
android:layout_width="80.0dip"
android:layout_height="80.0dip"
android:layout_gravity="center_horizontal"
android:src="@drawable/china" &
&/ImageView&
android:id="@+id/tvCity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Title"
android:textColor="#000000" &
&/TextView&
android:id="@+id/tvCode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Info"
android:textColor="#000000" &
&/TextView&
&/LinearLayout&
3.java实现代码:MainActivity.java
package com.example.
import java.util.ArrayL
import java.util.L
import android.app.A
import android.content.C
import android.os.B
import android.util.DisplayM
import android.view.LayoutI
import android.view.V
import android.view.ViewG
import android.widget.BaseA
import android.widget.GridV
import android.widget.LinearL
import android.widget.RelativeL
import android.widget.TextV
* @author ymw
* @summary 博客地址欢迎访问: /_ymw
public class MainActivity extends Activity {
List&CityItem& cityL
GridView gridV
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LayoutInflater layoutInflater = (LayoutInflater) this
.getSystemService("layout_inflater");
gridView = (GridView) findViewById(R.id.grid);
setData();
setGridView();
/**设置数据*/
private void setData() {
cityList = new ArrayList&CityItem&();
CityItem item = new CityItem();
item.setCityName("深圳");
item.setCityCode("0755");
cityList.add(item);
item = new CityItem();
item.setCityName("上海");
item.setCityCode("021");
cityList.add(item);
item = new CityItem();
item.setCityName("广州");
item.setCityCode("020");
cityList.add(item);
item = new CityItem();
item.setCityName("北京");
item.setCityCode("010");
cityList.add(item);
item = new CityItem();
item.setCityName("武汉");
item.setCityCode("027");
cityList.add(item);
item = new CityItem();
item.setCityName("孝感");
item.setCityCode("0712");
cityList.add(item);
cityList.addAll(cityList);
/**设置GirdView参数,绑定数据*/
private void setGridView() {
int size = cityList.size();
int length = 100;
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
float density = dm.
int gridviewWidth = (int) (size * (length + 4) * density);
int itemWidth = (int) (length * density);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
gridviewWidth, LinearLayout.LayoutParams.FILL_PARENT);
gridView.setLayoutParams(params); // 设置GirdView布局参数,横向布局的关键
gridView.setColumnWidth(itemWidth); // 设置列表项宽
gridView.setHorizontalSpacing(5); // 设置列表项水平间距
gridView.setStretchMode(GridView.NO_STRETCH);
gridView.setNumColumns(size); // 设置列数量=列表集合数
GridViewAdapter adapter = new GridViewAdapter(getApplicationContext(),
cityList);
gridView.setAdapter(adapter);
/**GirdView 数据适配器*/
public class GridViewAdapter extends BaseAdapter {
List&CityItem&
public GridViewAdapter(Context _context, List&CityItem& _list) {
this.list = _
this.context = _
public int getCount() {
return list.size();
public Object getItem(int position) {
return list.get(position);
public long getItemId(int position) {
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater layoutInflater = LayoutInflater.from(context);
convertView = layoutInflater.inflate(R.layout.list_item, null);
TextView tvCity = (TextView) convertView.findViewById(R.id.tvCity);
TextView tvCode = (TextView) convertView.findViewById(R.id.tvCode);
CityItem city = list.get(position);
tvCity.setText(city.getCityName());
tvCode.setText(city.getCityCode());
return convertV
public class CityItem {
private String cityN
private String cityC
public String getCityName() {
return cityN
public void setCityName(String cityName) {
this.cityName = cityN
public String getCityCode() {
return cityC
public void setCityCode(String cityCode) {
this.cityCode = cityC
4.项目代码如下链接:
阅读(...) 评论()前段时间接到一个需求,要求GridView超过两行只显示两行多余的不显示。但是GridView没有设置多少行的api,只有设置多少列的方法,到处查找资料都类似的case,stakeoverfrow上面也没什么有价值的答案,不过在百度知道竟然看到了一个思路。第一个方案:说定死列数,算出总数,只有显然不科学,因为我的gridview列数十需要autofit的,随手机屏幕多宽就相应显示多少列。gridview的xml属性 android:numColumns=&6&在adapter里重写@Override public int getCount() { return 12; }这样应该行吧第二个方案:限定gridview高度,因为项目时间很紧所以脑子里也曾蹦出这个想法,试着写死一个固定高度,但事实上这高度是不起作用的,因为它是根据adapte的条目来计算的。第三个方案:其实就是第一个方案改良版,虽然是很朴素的思路但是可以改活。在探索过程中发现gridview在高版api中有一个获取列数的方法,如果知道到列数那就好办了,列数*2就得到了要显示两行的count,这样既满足列数自适应又很优雅的控制要显示的区域。问题1:获取不到grid列数,返回-1于是代码可以写下去了:int numberOfColumns = mGridView.getNumColumns();if (numberOfColumns & 0) {//adapter item 数据已填充
int countOf2Row = numberOfColumns * 2; & &for (int i = count2Row - 1; i & couponList.size(); i++)
& & & & mDataSources.remove(i);//多出2列的数据cut掉
if (mAdapter != null) mAdapter.notifyDataSetChanged();}这个if死活没进去啊,打印出来看到获取到的NumColumn是-1,然后看到方法doc:Get the number of columns in the grid. * Returns {@link #AUTO_FIT} if the Grid has never been laid out.我明明是在adapte.notifyDatasetChanged()方法之后去获取的啊,怎么还是拿不到,查阅了一些资料之后就监听gridview布局变化,在listener里面果然能获取到了。刚才说到getNumColumns()是高版方法,API11以上才有,所以还得back compat。这个只要网上搜索一下一大把,我也是摘抄了一段。/**
& & * 获取列数的兼容方法.
& & * @return
public int getNumColumnsCompat() { & & & &if (Build.VERSION.SDK_INT &= 11) { & & & & & &return getNumColumnsCompat11();
& & & &} else { & & & & & &int columns = 0; & & & & & &int children = getChildCount(); & & & & & &if (children & 0) { & & & & & & & &int width = getChildAt(0).getMeasuredWidth(); & & & & & & & &if (width & 0) {
& & & & & & & & & &columns = getWidth() /
& & & & & & & &}
& & & & & &} & & & & & &return columns & 0 ? columns : AUTO_FIT;
& &@TargetApi(Build.VERSION_CODES.HONEYCOMB) & &private int getNumColumnsCompat11(){ & & & &return getNumColumns();
& &}那最后代码变成这样了:mGridView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
& & & & & &@Override & & & & & &public void onGlobalLayout() { & & & & & & & &int numberOfColumns = ((MyGridView) mGridView).getNumColumnsCompat(); & & & & & & & &if (numberOfColumns & 0) {//adapte item 数据已填充
int count2Row = numberOfColumns * 2; & & & & & & & & & &for (int i = count2Row - 1; i & couponList.size(); i++)
& & & & & & & & & & & &list.remove(i);//多出2列的数据cut掉
if (mAdapter != null) mAdapter.notifyDataSetChanged();
& & & & & & & & & &ApiVersionCompat.removeOnGlobalLayoutListener(mGridView.getViewTreeObserver(), this);
& & & & & & & &}
& & & & & &}
& & & &});注意在onGlobalLayout处理好移除数据的逻辑之后需要移除监听器哦,移除监听也有一个版本差异,代码送上:public static void removeOnGlobalLayoutListener(ViewTreeObserver observer, ViewTreeObserver.OnGlobalLayoutListener victim) { & & & &if (Build.VERSION.SDK_INT &= 16) {
& & & & & &observer.removeOnGlobalLayoutListener(victim);
& & & &} else {
& & & & & &observer.removeGlobalOnLayoutListener(victim);
& &}问题2:加载数据和布局事件异步执行导致限行失效本以为就perfect了事了,feature也实现了,资源也节约了(因GroblaLayoutListener会多次触发,所以一定要做好限制,用完就释放掉不要让代码重复执行了)。代码交上去,apk发给测试测了之后bug就丢过来了,测试出来说还是有不止两行的grid出现啊,我心里怎么也不相信啊,怎么可能我明明自测过的。当我重新打开app,发现确实有超出2行多出一个Item掉在第三行,后来就怀疑是不是cut数据没控制好,代码明明是for (int i = count2Row - 1; i & list.size(); i++)这样循环啊。每次都多出一个,难道i&=list.size(),我也曾很多次怀疑过怎么可能会list.remove(list.size()),不可能不可能不可能啊,这样绝对会数组越界啊,难不成是i初始还要count2Row-2,试过之后还是如此多一个(因为总数是有9个,从第六个开始剪掉2个也还是有一个)。log出size让我惊讶了,size竟然是6,但接口出来明明是9啊。然后就猛然一醒,加载数据和触发布局改变事件应该是异步的,也就是说当我在布局改变事件中获取到列数&0时,并不一定数据全部加载完,而这时我已经移除监听了。当加载到第1行数据的时候就可以获取到列数了,恰好此时我移除了其中几个(如果第一次获取到的size大于2列之和小于最终size),但当处理完这块逻辑的同时数据其实还是在加载的,虽然都是微乎其微的瞬间,但也有先来后到的顺序,所以移除掉一部分后面又添加了一部分,结果就出现了超过两行的情况。&mGridView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
& & & & & &@Override & & & & & &public void onGlobalLayout() { & & & & & & & &int numberOfColumns = ((MyGridView) mGridView).getNumColumnsCompat();//有可能每次会有变动
if (numberOfColumns & 0) {//adapter item 数据已填充
int countOf2Row = numberOfColumns * 2; & & & & & & & & & &if (list.size() & countOf2Row) { & & & & & & & & & & & &//超出2行(第三行开始)的数据cut掉
for (int i = countOf2R i & list.size(); i++) {
& & & & & & & & & & & & & &mAdapter.remove(i);
& & & & & & & & & & & &} & & & & & & & & & & & &if (mAdapter != null) mAdapter.notifyDataSetChanged();
& & & & & & & & & &} else { & & & & & & & & & & & &//每次检测到数据集合大小&=countOf2Row的时候就可以移除监听了
ApiVersionCompat.removeOnGlobalLayoutListener(mGridView.getViewTreeObserver(), this);
& & & & & & & & & &}
& & & & & & & &}
& & & & & &}
& & & &});问题3:处理限制行数的时机,或者说监听布局改变的时机好了,代码写好了,自测一下也都OK了,多测几个不一样的数据也正常了。可该死的,不小心按到了home键,当打开recent列表点回app的时候发现大事不好,又整整齐齐得出现三行满满的。原来这个界面是会在onResure刷新数据的,View都还是那些View,但是数据会重新添加,第一次完美显示2行,但数据一刷新,就会先clear掉数据源重新添加数据,而此时的GlobalLayoutListener已经移除了无法监听处理多出2行的逻辑了,所以如上图所示,完完整整的出现了3行数据。因为我addOnGlobalLayoutListener是在initViews时候去注册的,当数据加载完毕就移除监听,原来以为很完美没想到会有这种情况发生。那知道了问题在哪就好对症下药了,直接把添加监听的方法放在拿到数据后执行就好了,每次到数据就监听处理,处理完了就移除监听,下次数据来了依然也可以依次执行。代码就不贴了,说的很清楚了。下期预告:类似淘宝京东商品大图浏览,耍起ViewPager+PhotoView+Fresco的正确姿势!Bvin(gh_913be5f5a454) 
 文章为作者独立观点,不代表微头条立场
的最新文章
前段时间接到一个需求,要求GridView超过两行只显示两行多余的不显示。但是GridView没有设置多少行gh_913be5f5a454个人平台热门文章最新文章gh_913be5f5a454个人平台Android中如何实现单行、水平滚动的分页的Gridview?
[问题点数:20分]
Android中如何实现单行、水平滚动的分页的Gridview?
[问题点数:20分]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
2013年3月 总版技术专家分月排行榜第三
2014年5月 移动开发大版内专家分月排行榜第一2014年4月 移动开发大版内专家分月排行榜第一
匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。查看: 2490|回复: 7
gridview如何控制行数。。。。。
签到天数: 7 天连续签到: 1 天[LV.3]偶尔看看II主题帖子e币
gridview如何控制行数。。。。。
我想让gridview只显示两行,并且可以上下滑动显示其他的数据。
比如我把gridview设成4列,共有20条数据,但只显示出两行,滑动时候显示其他数据。
签到天数: 43 天连续签到: 1 天[LV.5]常住居民I主题帖子e币
只能自己手动控制GridView的高度了,让其只显示俩行。
谢谢,我现在用的就是固定高度
我想自定义的gridview重写gridview的方法&
签到天数: 113 天连续签到: 1 天[LV.6]常住居民II主题帖子e币
该用户从未签到主题帖子e币
试试这个属性android:numColumns
这个是设置列的。&
签到天数: 7 天连续签到: 1 天[LV.3]偶尔看看II主题帖子e币
试试这个属性android:numColumns
这个是设置列的。
签到天数: 7 天连续签到: 1 天[LV.3]偶尔看看II主题帖子e币
只能自己手动控制GridView的高度了,让其只显示俩行。
谢谢,我现在用的就是固定高度
我想自定义的gridview重写gridview的方法
签到天数: 16 天连续签到: 1 天[LV.4]偶尔看看III主题帖子e币
直接定义gridview的高度,让高度是2行的长度
签到天数: 3 天连续签到: 2 天[LV.2]偶尔看看I主题帖子e币
只固定高度不行吧,你上下滑动每次滚动的距离不一定就是正好是两行的高度啊,可能显示的是中间一个整行,上下两个&&半行的情况
推荐阅读热门话题
619991867415415378323273272258254249224215210715
8&分钟前1&小时前2&小时前3&小时前5&小时前6&小时前6&小时前6&小时前7&小时前7&小时前7&小时前8&小时前12&小时前12&小时前12&小时前13&小时前
Powered by获取验证码
暂停使用,请使用开发者账号登录!
秒之内仍未收到,请
积分1348&学分120 &来自广西-桂林市&
Android中如何实现GridView的水平拖动,固定行数,水平滚动!
用HorizontalScrollView包一下GridView
&HorizontalScrollView android:layout_width=&fill_parent&
android:layout_height=&match_parent&&
&FrameLayout android:layout_width=&fill_parent&
android:layout_height=&match_parent&&
&LinearLayout android:layout_width=&fill_parent&
android:layout_height=&match_parent&
android:orientation=&horizontal&&
&?xml version=&1.0& encoding=&utf-8&?&
&LinearLayout xmlns:android=&/apk/res/android&
android:orientation=&vertical&
android:layout_width=&fill_parent&
android:layout_height=&fill_parent&
android:layout_width=&wrap_content&
android:layout_height=&wrap_content&
android:text=&@string/hello& /&&!--
layout=&@layout/foot_navigation&
android:id=&@+id/foot_nav_lv_ll& /&
&HorizontalScrollView android:layout_width=&wrap_content&
android:layout_height=&wrap_content&&
&FrameLayout android:layout_width=&wrap_content&
android:layout_height=&wrap_content&&
&LinearLayout android:layout_width=&wrap_content&
android:layout_height=&wrap_content& android:orientation=&horizontal&&
&include layout=&@layout/foot_navigation_gridview&
android:id=&@+id/foot_nav_gv_ll& /&
&/LinearLayout&
&/FrameLayout&
&/HorizontalScrollView&
&/LinearLayout& 复制代码
积分6386&学分101 &来自安徽-合肥市&
你的等级:
来自:安徽省合肥市
积分9799&学分101 &来自安徽-巢湖市&
积分7952&学分307 &来自湖北-武汉市&
感谢分享!
代码是写出来的!
你的等级:
来自:安徽省合肥市
你的等级:
来自:安徽省合肥市
蓝天白云,彩云追月
积分11278&学分362 &来自安徽-马鞍山市&
积分6&学分0 &来自辽宁-沈阳市&
能否将&include layout=&@layout/foot_navigation_gridview&
android:id=&@+id/foot_nav_gv_ll& /& 处的代码给全,用HorizontalScrollView包GridView后,还没有出现预期的效果}

我要回帖

更多关于 gridview 行数 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信