`

使用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 嵌套 ListView demo

    在这个方法里,你会为每个主列表项创建视图,并在需要的地方插入子ListView。 3. **子ListView的Adapter**:对于子ListView,也需要一个独立的Adapter,它负责处理子列表的数据。通常,这个Adapter会作为主Adapter...

    android 嵌套的listview示例

    通过以上步骤,你应该能够实现一个基本的嵌套ListView示例。不过,实际应用中可能还需要根据具体需求进行更多的定制和优化。在开发过程中,参考Android官方文档、开发者博客(如给出的CSDN博客链接)和其他开源项目...

    ListView+EditText混乱问题

    5. **使用RecyclerView替换ListView**:虽然这是一个更现代的解决方案,但值得注意的是,RecyclerView虽然在很多方面改进了ListView,但它仍然可能遇到类似的问题。处理方式基本相同,但RecyclerView提供了更多的...

    订单Listview嵌套的实现

    9. **内存管理**:注意内存泄漏问题,尤其是在持有对内外ListView引用的地方,例如匿名内部类的实现中。 10. **项目实践**:在"我的订单AS项目"中,你可以找到一个实际的案例,研究其代码结构、布局文件以及Adapter...

    新listView联动示例

    例如,如果数据加载较慢,可以考虑使用异步加载策略,或者在ListView之外的地方进行数据处理,然后再更新视图。 总结来说,"新listView联动示例"提供了实现多个ListView同步滚动的解决方案,这对于创建多列展示、...

    ListView根据不同选择加载不同数据实战

    最后,确保在适当的地方调用`notifyDataSetChanged()`方法,通知ListView数据已更新,以便ListView刷新显示。 在代码实现过程中,你还需要注意异常处理,确保程序的健壮性。同时,通过注释和良好的代码结构,使代码...

    ListView 对话效果

    这样,只需传入必要的数据和配置,就能轻松地在任何地方使用这个对话框ListView。这将极大地提高代码的可维护性和开发效率。 综上所述,"ListView 对话效果"是Android开发中的一个高级技巧,涉及到自定义Adapter、...

    ListView批量删除demo

    六、注意事项 1. 在删除数据后,记得通知Adapter,否则ListView可能无法正确显示更新。 2. 避免在主线程执行耗时操作,如删除大量数据,这可能导致应用无响应。最好在子线程中处理这些操作,并通过Handler或...

    ListView下拉刷新实现

    6. **注意事项**:确保在数据加载完成前,不要让ListView滚动。否则,可能会与下拉刷新冲突。在`onRefresh()`回调开始时,可以暂停ListView的滚动,加载完成后再恢复。 通过以上步骤,你就可以在自己的应用中实现...

    Listview.rar

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

    listview嵌套listview制作目录

    - 注意,嵌套ListView可能导致性能问题,因为每个外部ListView条目都会有自己的内部ListView。可以使用`convertView`机制在`getView()`中复用视图,减少对象创建。 - 如果目录层级很深,可以考虑使用其他控件,如...

    安卓listview相关相关-横竖都能滑动的listview嵌套在一起的.zip

    主要关注的地方包括:Adapter的实现,触摸事件的处理,以及如何协调内外两个ListView的滚动。此外,注意观察和学习如何避免嵌套滑动中的冲突,确保用户体验流畅。这将是一个很好的学习机会,有助于提升你在Android ...

    ListView 表格动态设置控件宽度 代码法

    在这个Adapter中,我们将重写`getView()`方法,因为这是ListView绘制每个项的地方。 2. **测量控件**:在`getView()`方法内,获取到要调整宽度的控件实例,然后调用`measure()`方法进行测量。这个方法接受两个参数...

    VB ListView 自定义可编辑列

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

    listview嵌套checkbox

    3. 考虑使用RecyclerView 替换ListView,因为它有更好的性能和更灵活的布局管理。 五、注意事项 1. 避免在CheckBox的监听事件中直接修改数据源,否则可能触发ListView的刷新,导致不必要的性能开销。 2. 如果有大量...

    listview批量删除例子

    注意,删除数据源中的元素后,可能需要对后面的元素重新调整索引,以保持与ListView的一致性。 6. **更新视图**:调用`notifyDataSetChanged()`通知适配器数据源已改变,ListView会自动更新视图。避免直接调用`...

    android自定义dialog+listview自适应屏幕显示.zip

    此外,对于这个项目,还要注意的是如何使ListView与Dialog结合使用。这通常意味着在Dialog的布局文件中包含ListView,然后在Dialog类中设置适配器和监听器。同时,要确保Dialog的大小和位置调整得当,以便于用户查看...

    ListView中的item带单选

    通常我们会使用BaseAdapter或者ArrayAdapter作为ListView的数据源。这里以BaseAdapter为例,我们需要维护一个变量来记录当前选中的位置,并在getView方法中根据该位置设置RadioButton的状态: ```java public class...

    ListView控件

    - 在使用`ListView`控件之前,确保已经包含了`MSCOMCTL.OCX`文件,并且在发布应用程序时将此文件安装到用户的`Microsoft Windows System`或`System32`目录下。 - 详细了解控件的每个属性和方法,以便更好地利用它们...

    listview滑动删除

    需要注意的是,为了保持性能,避免在滑动过程中执行耗时的操作,应该尽可能地在主线程之外处理数据删除和动画播放。此外,考虑到不同设备的屏幕尺寸和触摸灵敏度,滑动删除的阈值可能需要根据实际情况进行调整。

Global site tag (gtag.js) - Google Analytics