`

使用ListView应该注意的地方

阅读更多
android:clipToPadding和android:clipChildren
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0317/2613.html

Android ListView优化之局部刷新(更新)(非notifyDataSetChanged)
http://www.see-source.com/blog/300000024/1262.html

在Item布局的根布局加上android:descendantFocusability="blocksDescendants"用于屏蔽子控件抢夺ListView的焦点


解决listview addheader EditText焦点问题

android:transcriptMode="normal" 设置该属性后如果界面中有EditText并且弹出键盘后会滚动到最后

关于ListView加入HeaderView之后,点击条目时获得position参数移位的BUG修正
       今天遇到一个问题,在ListView的时候,要在首部加一个轮播图组件,调用的是ListView的addHeaderView(View v, Object data, boolean isSelectable)方法,这个方法可以把一个view放置到Listview的顶部显示,也可以多次调用,使得多个view按照添加的顺序,依次排列在ListView的顶部显示。
       
        这样做了之后是显示是没问题的,但是遇到一个问题就是在ListView的Adapter的构造方法中,要添加ListView的条目点击事件:mListView.setOnItemClickListener(this);
        然后在Adapter里面实现onItemClick(AdapterView<?> parent, View view, int position,long id)方法,在通过position取数据的时候发现一个问题,就是点击的条目错位了,点击一个条目,结果响应事件变成了下一个条目对应的事件。

        经过探查之后发现,本来ListView条目的position是从0开始计算的:0,1,2...这样,但是添加了一个Header之后,position变成了从1开始,于是需要手动修正一下这个postion的值。
        好在Android中有提供一个对应的API来得到HeaderView的数量,那就是ListView中的一个方法:getHeaderViewsCount(),这个方法可以得到这个ListView添加了多少个HeaderView,然后我们需要做的只是在使用position之前,修正一下:
// TODO 修正有Header的ListView的position的BUG
int headerViewsCount = listView.getHeaderViewsCount();//得到header的总数量
			
//得到新的修正后的position
int newPosition = position - headerViewsCount;


FloatingActionButton
一个类似Android版Google+浮动功能按钮的控件,可以响应ListView的滚动事件。当列表向上滚动的时候会自动显示,向下滚动的时候自动隐藏。
项目地址:https://github.com/makovkastar/FloatingActionButton

Android实现自适应正方形GridView
http://blog.chengyunfeng.com/?p=465

Read more: http://blog.chengyunfeng.com/?p=465#ixzz3REioavcX

关于addHeaderView,addFooterView的问题
当listview需要添加headerview时,可以通过调用listview的addHeaderView(headView, null, false) 方法,该方法还有一个重载方法 addHeaderView(headView);这两个方法的区别是前一个方法可以控制header是否可以被selected,如果不想被selected则将第三个参数设置成false;
addHeaderView方法必须放在listview.setadapter前面,意思很明确就是如果想给listview添加头部则必须在给其绑定adapter前添加,否则会报错。原因是当我们在调用setAdapter方法时会android会判断当前listview是否已经添加header,如果已经添加则会生成一个新的tempadapter,这个新的tempadapter包含我们设置的adapter所有内容以及listview的header和footer。所以当我们在给listview添加了header后在程序中调用listview.getadapter时返回的是tempadapter而不是我们通过setadapter传进去的adapter。如果没有设置adapter则tempadapter与我们自己的adapter是一样的。listview.getadapter().getcount()方法返回值会比我们预期的要大,原因是添加了header。
接着上面的tempadapter说,我们自定义adapter里面的getitem方法里面返回的position是不包括header的,是我们自定义adapter中数据position编号从0开始,也就是说与我们传进去的list的位置是一样的。
@Override  
public View getView(int position, View convertView, ViewGroup parent) {  
// TODO Auto-generated method stub  
Log.i("adapter", "position:"+position);   //这个position就是我们数据的真实位置  
  }  


但是在ListView的onItemClick方法中:
public void onItemClick(AdapterView<?> arg0, View arg1, int position,long arg3) 
 
position是当前click的位置,这个位置是指在tempadapter中的位置,从0开始如果ListView中添加了header则0代表header。所以如果要得到ListView的第一条数据,就必须position-1


ListView的Item中含有Button时无法响应onItemClick()?
解决办法就是将Button的Focus设置为非默认获取

方法一:将ListView的Item Layout的子控件focusable属性设置为false

方法二(推荐):对Item Layout的根控件android:descendantFocusability="blocksDescendant" ,对应的方法为:setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);  

方法三:在实现ListView的Adapter的getView方法时,将button.setFocusable(false);


在ListView中设置Selector为null会报空指针?
mListView.setSelector(null);//空指针
试试下面这种:
mListView.setSelector(new ColorDrawable(Color.TRANSPARENT));

如何让ListView初始化的时候就选中一项?
ListView需要在初始化好数据后,其中一项需要呈选中状态。所谓"选中状态"就是该项底色与其它项不同,setSelection(position)只能定位到某个item,但是无法改变底色呈高亮。setSelection(position)只能让某个item显示在可见Item的最上面(如果Item超过一屏的话)! 就是所谓的firstVisibleItem啦!
如果想要实现效果可以在listview所绑定的adapter里的getView函数里去完成一些具体的工作。可以记下你要高亮的那个item的index,在getView函数里判断index(也就是position),如果满足条件则加载不同的背景。
伪代码:
private int oldPosition = 0;//记录上一次点击的position

gridView.setOnItemClickListener(new GridView.OnItemClickListener()
        {

            @Override
            public void onItemClick(AdapterView<?> parent, View v, int position, long id)
            {
                // TODO Auto-generated method stub

                ((TextView) v).setTextColor(App.res.getColor(R.color.text_color_c6));//当前点击的这个

                ((TextView) parent.getChildAt(oldPosition)).setTextColor(App.res.getColor(R.color.text_color_c2));//上一次点击的那个

                oldPosition = position;//重新赋值
            }
        });

gridView.setAdapter(new CommonAdapter<Unit>(context, instance.getUnits(), R.layout.item_for_food_detail_unit)
        {
            @Override
            public void setValues(ViewHolder helper, Unit item, int position)
            {
                helper.setText(R.id.item_0, item.getName());
//判断显示哪个颜色
                ((TextView) helper.getView(R.id.item_0)).setTextColor(App.res.getColor(position == oldPosition ? R.color.text_color_c6
                        : R.color.text_color_c2));
            }

        });

或者:
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);//api 11 ?
getListView().setItemChecked(position, true);//api 11 ?

或者:
http://www.eoeandroid.com/thread-535829-1-1.html
ListView的右边滚动滑块启用方法?
    很多开发者不知道ListView列表控件的快速滚动滑块是如何启用的,其实辅助滚动滑块只需要一行代码就可以搞定,如果你使用XML布局只需要在ListView节点中加入  android:fastScrollEnabled="true" 这个属性即可,而对于Java代码可以通过myListView.setFastScrollEnabled(true); 来控制启用,参数false为隐藏。
    还有一点就是当你的滚动内容较小,不到当前ListView的3个屏幕高度时则不会出现这个快速滚动滑块,该方法是AbsListView的基础方法,可以在ListView或GridView等子类中使用快速滚动辅助。



1. 更新ListView中的數據,通過調用BaseAdapter對象的notifyDataSetChanged()方法:
      mAdapter.notifyDataSetChanged();

2. 每個listview都有無效的位置,如第一行的前一行,最後一行的後一行,這個無效的位置是一個常量.
     ListView.INVALID_POSITION

3. 有時我們需要在程序中通過點擊按鈕來控制ListView行的選中,這就用到了在程序中如何使用代碼來選擇ListView項.
         mListView.requestFocusFromTouch();
         mListView.setSelection(int index);

     第一條語句並不是必須的,但是若你ListView項中含有Button,RadioButton,CheckBox等比ListView取得 焦點優先級高的控件時,那麼第一條語句是你必須加的.

4.  同樣的,若你ListView項中含有Button,RadioButton,CheckBox等比ListView取得 焦點優先級高的控件時,ListView的setOnItemClickListener是不被執行的,這時你需要在你的xml文件中對這些控件添加  android:focusable="false" 注意這條語句要放在xml文件中修改,在代碼中使用是無效的.

5. 如何保持ListView的滾動條一直顯示,不隱藏呢:  xml文件中做如下修改    android:fadeScrollbars="false"

6. ListView本身有自己的按鍵事件,即你不需要設置方向鍵的標識,按下方向鍵ListView就會有默認的動作,那如何進行控制,編寫自己的onKey呢,你需要在Activity中重寫dispatchKeyEvent(KeyEvent event);方法,在這裡面定義你自己的動作就可以了

ListView 自定义滚动条样式:
<ListView android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="0dip"
        android:layout_weight="1"
        android:stackFromBottom="true"//从下开始显示条目
        android:transcriptMode="normal"
        android:fastScrollEnabled="true"
        android:focusable="true"
        android:scrollbarTrackVertical="@drawable/scrollbar_vertical_track"
        android:scrollbarThumbVertical="@drawable/scrollbar_vertical_thumb"
/>
//scrollbar_vertical_track,crollbar_vertical_thumb自定义的xml文件,放在Drawable中,track是指长条,thumb是指短条
去掉ListView Selector选种时黄色底纹一闪的效果:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@android:color/transparent"/>
    <corners android:radius="0dip" />    
</shape>
//listview.setSelector(R.drawable.thisShape);

或者直接:gridView.setSelector(android.R.color.transparent);
或者还有一种办法:
在Adapter中重写public boolean isEnabled(int position)方法,将其返回false就可以了,推荐采用此种办法,但是这样的话item不响应点击事件了,具体见http://gundumw100.iteye.com/admin/blogs/850654
public boolean isEnabled(int position) {
	// TODO Auto-generated method stub
	return false;
}


ListView几个比较特别的属性
首先是stackFromBottom属性,这只该属性之后你做好的列表就会显示你列表的最下面,值为true和false
android:stackFromBottom="true"            

第二是transciptMode属性,需要用ListView或者其它显示大量Items的控件实时跟踪或者查看信息,并且希望最新的条目可以自动滚动到可视范围内。通过设置的控件transcriptMode属性可以将Android平台的控件(支持ScrollBar)自动滑动到最底部。
android:transcriptMode="alwaysScroll"   

第三cacheColorHint属性,很多人希望能够改变一下它的背景,使他能够符合整体的UI设计,改变背景背很简单只需要准备一张图片然后指定属性 android:background="@drawable/bg",不过不要高兴地太早,当你这么做以后,发现背景是变了,但是当你拖动,或者点击list空白位置的时候发现ListItem都变成黑色的了,破坏了整体效果。
如果你只是换背景的颜色的话,可以直接指定android:cacheColorHint为你所要的颜色,如果你是用图片做背景的话,那也只要将android:cacheColorHint指定为透明(#00000000)就可以了

第四divider属性,该属性作用是每一项之间需要设置一个图片做为间隔,或是去掉item之间的分割线android:divider="@drawable/list_driver"  其中  @drawable/list_driver 是一个图片资源,如果不想显示分割线则只要设置为android:divider="@drawable/@null" 就可以了

第五fadingEdge属性,上边和下边有黑色的阴影android:fadingEdge="none" 设置后没有阴影了~

第五scrollbars属性,作用是隐藏listView的滚动条,android:scrollbars="none"与setVerticalScrollBarEnabled(true);的效果是一样的,不活动的时候隐藏,活动的时候也隐藏

第六fadeScrollbars属性,android:fadeScrollbars="true"  配置ListView布局的时候,设置这个属性为true就可以实现滚动条的自动隐藏和显示。

如何在使用gallery在flinging拖动时候不出现选择的情况?
这时候需要注意使用
gallery.setCallbackDuringFling(false)

如何让ListView自动滚动?
注意stackFromBottom以及transcriptMode这两个属性。类似Market客户端的低端不断滚动。
<ListView android:id="listCWJ" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:stackFromBottom="true"   
     android:transcriptMode="alwaysScroll" 
/>
如何遍历listView 的的单选框?
ListView listView = (ListView)findViewById(R.id.配置文件中ListView的ID);
//全选遍历ListView的选项,每个选项就相当于布局配置文件中的RelativeLayout
for(int i = 0; i < listView.getChildCount(); i++){
      View view = listView.getChildAt(i);
      CheckBox cb = (CheckBox)view.findViewById(R.id.CheckBoxID);
      cb.setChecked(true);
}


如何让ListView中TextView的字体颜色跟随焦点的变化?
我们通常需要ListView中某一项选中时,他的字体颜色和原来的不一样。 如何设置字体的颜色呢? 在布局文件中TextColor一项来设置颜色,但是不是只设置一种颜色,而是在不同的条件下设置不同的颜色: 下面是个例子:
<?xml version="1.0" encoding="utf-8" ?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:color="@color/orange"></item>
<item android:state_window_focused="false" android:color="@color/orange"></item>
<item android:state_pressed="true" android:color="@color/white"></item>
<item android:state_selected="true" android:color="@color/white"></item>
<item android:color="@color/orange"></item>
</selector> 
在获取焦点或者选中的情况下设置为白色,其他情况设置为橘黄色。


如何自定义ListView行间的分割线?
所有基于ListView或者说AbsListView实现的widget控件均可以通过下面的方法设置行间距的分割线,分割线可以自定义颜色、或图片。
在ListView中我们使用属性android:divider="#FF0000" 定义分隔符为红色,当然这里值可以指向一个drawable图片对象,如果使用了图片可能高度大于系统默认的像素,可以自己设置高度比如6个像素android:dividerHeight="6px" ,当然在Java中ListView也有相关方法可以设置。

ListView不通过notifyDataSetChanged()更新指定的Item
Listview一般大都是通过notifyDataSetChanged()來更新listview,但通过notifyDataSetChanged()会把界面上现实的的item都重绘一次,这样会影响ui性能。
可以通过更新指定的Item提高效率,伪代码如下:
private void updateView(int itemIndex){  
  int visiblePosition = yourListView.getFirstVisiblePosition();  
  View v = yourListView.getChildAt(itemIndex - visiblePosition);//Do something fancy with your listitem view  
  TextView tv = (TextView)v.findViewById(R.id.sometextview);
  tv.setText("Hi! I updated you manually");
}


让ListView中长按某些Item时能弹出contextMenu,有些不能
定义了一个listView,并为他设置了setOnCreateContextMenuListener的监听,但这样做只能使这个listView中的所有项在长按的时候弹出contextMenu 。
有时希望的是有些长按时能弹出contextMenu,有些不能。解决这个问题的办法是为这个listView设置setOnItemLongClickListener监听,然后实现
public boolean onItemLongClick(AdapterView<?> parent, View view, 
int position, long id) { 
  if(id == 1){ 
    return true; 
  } 
  return false; 
} 

如果这一项的id=1,就不能长按。 这样就可以了

ListView底部分隔线的问题
      在工作中遇到了一个难题,就是一个listView在最下面的一个item下面没有分割线,要求是必须得有这条分割线。经过一通研究发现了这个奇怪的现象:
      1. ListActivity有这条底部分割线。
      2.在Activity中只有listview,没有别的控件的话也会有。
      其实ListActivity也是一个Activity,只不过在其中使用了SetContentView(listView)方法设置了一个listView作为其显示的View而已。所以结论就是只要这个activity调用了SetContentView(listView)就会有这条底部分割线。
      那么什么情况下才不会有这条分割线呢?在Activity中如果调用setContentView(View)而ListView只是内嵌入到这个View的话有可能会没有这条分割线。
      分析其原因:通过加断点调试发现在listView中,所有的分割线都是通过画一个很窄的矩形来实现的,但是在画分割线前都会都会判断目前的位置A和listView的长度B,如果A=B了,那么就不会画这条分割线了。但是将Listview嵌入到一个View中,一般会设置为高度为wrap_content,这种情况下,最后那条分割线的位置刚好等于listView的高度,所以系统不会画上这条分割线。那要怎么样才会画上呢?很简单,将ListView的高度设置为fill_partent就可以了。
     当然以上所说的都是item很少的情况下,如果item很多以至于必须显示滚动条的话,那最后一个item下面是肯定不会有分割线了。

解决 Android 中使用ListView和CheckBox批量操作时若干问题

关于ListView中加入并选取checkbox错位的问题

ListView之setEmptyView的问题

关于ListView中使用GestureDetector冲突的解决办法
分享到:
评论
5 楼 Questing 2013-02-05  
不错,转贴了
4 楼 tanglibo1987 2012-03-12  
不错很好用
3 楼 ldl8818 2012-01-14  
很有用,转走,备忘
2 楼 gundumw100 2011-11-11  
yuanzhifei89 写道
遇到一个问题,如何在1.5的下通过代码来滚动ListView,像新浪微博那样,在屏幕翻转后,如果之前是处于滚动的,翻转后还是在滚动。不知道他们是不是在翻转前记录下一个滚动条位置,在翻转后activity重新创建后通过代码控制ListView滚动到那个位置的。

你前面一个activity是不是finish掉了?如果finish掉了,也只能这样了。
1 楼 yuanzhifei89 2011-11-11  
遇到一个问题,如何在1.5的下通过代码来滚动ListView,像新浪微博那样,在屏幕翻转后,如果之前是处于滚动的,翻转后还是在滚动。不知道他们是不是在翻转前记录下一个滚动条位置,在翻转后activity重新创建后通过代码控制ListView滚动到那个位置的。

相关推荐

    Listview.rar

    b、在build.gradle(Project: Listview)中 两处地方的 repositories 增加 { flatDir { dirs 'libs' } } c、 在build.gradle(model:app)dependencies中增加 implementation (name: 'hvscrollviewlibrary-1.0...

    VB ListView 自定义可编辑列

    ' 功 能:ListView 自定义可编辑列(特别注意:只能在一个窗体中使用,也只能使用一次!) ' 依 赖:(modLVWRect.bas, modSubClass.bas) ' 作 者:鹤望兰·流 ' 版 权:鹤望兰·流 ' 日 期:2009-08-14 ' 网 站:...

    listview条目里有chexkbox + 横向柱状图 Demo

    这是一个投票的例子,里面主要有两个需要注意的地方 1:listview条目里面有checkbox 抢焦点问题的解决 2:利用listview + progressbar 实现 横向柱状图

    类似微信实现的选人控件.zip

    2.计算水平listView里面最多显示的item的个数,针对不同的屏幕,item显示的个数应该明显不同的。   实现功能: 1.两个list联动 2.水平listView点击item自动取消 3.水平listView自动滑动到最右边   

    Android Studio DuDuMusic实例及源码 音乐播放器实现SQLite用户注册登录 管理员服务器数据交互

    7.我使用的是Android Studio,我把文件布局截图放在压缩包里面,还有几个需要注意的地方,特别的坑,尤其是大家需要注意build.gridle(app)这里面大家需要注册导包,你并且配置好自己的SDK。大家还需要注意就是...

    Android复杂闹钟

    需要注意的地方有两个:listview每次滑动的时候,记得设置背景为透明, mAlarmListView.setCacheColorHint(0);另一个是利用Intent传递广播的Intent的时候,传参数的时候,记得设置PendingIntent sender=...

    自己平时做的android相关的总结

    FrameLayout 需要注意的地方: EditText 禁止弹出按键盘: 获取控件屏幕位置和窗口位置: 为什么MyAdapater的getView没有被调用 XmlSerializer使用总结: ListView中的Item自定义点击后的背景色的方法。 drawable...

    类似微信实现的选人控件

    类似微信实现的选人控件...2.计算水平listView里面最多显示的item的个数,针对不同的屏幕,item显示的个数应该明显不同的。 实现功能: 1.两个list联动 2.水平listView点击item自动取消 3.水平listView自动滑动到最右边

    《Android应用开发》个人总结报告.doc

    如果你觉得只有一个ListView的界面太突兀,你可以为这个ListActivity指定一 个Layout,需要注意的是,你需要提供一个id为@android:id/list的ListView控件,避 免Activity在内部偷偷寻找该控件的时候失败。...

    vfp6.0系统免费下载

    应该注意,在 Internet Explorer 所运行的 Visual FoxPro ActiveDoc 只是一个应用程序文件(.app),它也可以在 Visual FoxPro 中直接运行。也正由于这个原因,需要有 Visual FoxPro 的运行时刻版本。Active ...

    CityGuide:CityGuide Lift Android 练习

    包含应用程序中使用的 2 个自定义视图: StarRow用粉红色和灰色的星星渲染这个地方的评级, SliderSelector显示为列表顶部并用于位置类型选择。 包含Place ,在应用程序的唯一模型对象。 注意:场所类型(“Bar”、...

    delphi 开发经验技巧宝典源码

    0016 使用快捷键打开对象观察器中的“...”按钮 11 1.5 其他相关应用技巧 11 0017 安装合适的Delphi版本 11 0018 熟练掌握Delphi中的菜单项 12 0019 构成Delphi项目的主要文件 12 0020 如何在程序中调用...

    delphi 开发经验技巧宝典源码06

    0016 使用快捷键打开对象观察器中的“...”按钮 11 1.5 其他相关应用技巧 11 0017 安装合适的Delphi版本 11 0018 熟练掌握Delphi中的菜单项 12 0019 构成Delphi项目的主要文件 12 0020 如何在程序中调用...

    asp.net知识库

    .net 2.0 访问Oracle --与Sql Server的差异,注意事项,常见异常 Ado.net 与NHibernate的关系? 动态创建数据库 SQL Server数据库安全规划全攻略 .net通用数据库访问组件SQL Artisan应用简介1 在Framework1.0下...

    giCell zlg-gui

    地方均以延迟过程调用(DPC)方式执行; 10. 任务对象支持异步过程调用(Window用语APC,相当于UNIX中的信号机制),从而可 引导任务异步的执行一个过程(前提是任务栈不小于1024字节),此过程将在该任务 下次...

    android_external_AndroidSwipeLayout

    可以轻松集成在任何地方,ListView、GridView、ViewGroup 等。 可以接收onOpen 、 onClose 、 onUpdate回调。 可以通知隐藏的孩子他们已经展示了多少。 可以互相嵌套。 可以处理复杂的情况,就像。 用法 步骤1 ...

    谷歌师兄的leetcode刷题笔记-AndroidSwipeLayout:Eclipse的AndroidSwipeLayout

    可以轻松集成在任何地方,ListView、GridView、ViewGroup 等。可以接收 onOpen、onClose、onUpdate 回调。 可以通知隐藏的孩子他们已经展示了多少。 可以互相嵌套。 可以处理复杂的情况,就像这样。 用法 步骤1 ...

    谷歌师兄的leetcode刷题笔记-AndroidSwipeLayout:AndroidSwipeLayout

    可以轻松集成在任何地方,ListView、GridView、ViewGroup 等。 可以接收onOpen 、 onClose 、 onUpdate回调。 可以通知隐藏的孩子他们已经展示了多少。 可以互相嵌套。 可以处理复杂的情况,就像 . 用法 步骤1 ...

    谷歌师兄的leetcode刷题笔记-androidDemo:androidDemo

    可以轻松集成在任何地方,ListView、GridView、ViewGroup 等。 可以接收onOpen 、 onClose 、 onUpdate回调。 可以通知隐藏的孩子他们已经展示了多少。 可以互相嵌套。 可以处理复杂的情况,就像 . 用法 步骤1 ...

Global site tag (gtag.js) - Google Analytics