美文网首页
Android-ListView开发注意细节

Android-ListView开发注意细节

作者: 沉淀者 | 来源:发表于2020-05-12 18:56 被阅读0次

    一、当listview中item含有button或者checkbox等控件时,item点击无效。

    原因:被button或者checkbox等控件获得了焦点,导致item没有获得控件

    解决办法:

    1.在button或者checkbox布局文件里面定义下面属性
    android:clickable="false"
    android:focusable="false"
    android:focusableInTouchMode="false"
    
    2.在item的根布局里面定义这个属性:android:descendantFocusability="blocksDescendants"
    这个函数是在ViewGroup里定义的,主要用于控制child View获取焦点的能力,比如是否阻止child View获取焦点。
    他有三个常量可供设置
    FOCUS_BEFORE_DESCENDANTS ViewGroup本身先对焦点进行处理,如果没有处理则分发给child View进行处理
    FOCUS_AFTER_DESCENDANTS 先分发给Child View进行处理,如果所有的Child View都没有处理,则自己再处理
    FOCUS_BLOCK_DESCENDANTS ViewGroup本身进行处理,不管是否处理成功,都不会分发给ChildView进行处理
    

    二、Listview的onItemClick函数说明

    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
           parent.getAdapter().getItem(position);
           (CircleImageView) view.findViewById(R.id.img_jobberinfo_head);
       }
    
    后面有4个参数,乍看直接晕菜,那么每个参数究竟是何意义呢.
    举个例子会理解的更快:X, Y两个listview,X里有1,2,3,4这4个item,Y里有a,b,c,d这4个item。
    如果你点了b这个item。如下:
    

    / /parent相当于listview Y适配器的一个指针,可以通过它来获得Y里装着的一切东西,再通俗点就是说告诉你,你点的是Y,不是X
    // view是你点的b这个view的句柄,就是你可以用这个view,来获得b里的控件的id后操作控件
    // position是b在Y适配器里的位置(生成listview时,适配器一个一个的做item,然后把他们按顺序排好队,在放到listview里,意思就是这个b是第position号做好的)
    // id是b在listview Y里的第几行的位置(很明显是第2行),大部分时候position和id的值是一样的.

    1、通过parent获取ListView的Adapter<EllipsoidBean >里面的泛型数据
    EllipsoidBean bean= (EllipsoidBean) parent.getItemAtPosition(position);
    
    2、通过view获取item中的控件
    CheckBox checkbox=view.findViewById(R.id.checkbox);
    

    三、点击Listview的某一项数据变色item变色

    1.在Adapter里面定义两个方法

        private int mCurrentItem=0;
        private boolean isClick=false;
        public void setCurrentItem(int currentItem){
            this.mCurrentItem=currentItem;
        }
    
        public void setClick(boolean click){
            this.isClick=click;
        }
    

    2.在Adapter的getView方法里面,这个parentItem就是每一个item的根布局

           RelativeLayout parentItem;
           parentItem= (RelativeLayout)convertView.findViewById(R.id.parent);
           parentItem.setBackgroundColor(getContext().getResources().getColor(R.color.white,null));
            if (mCurrentItem==position&&isClick){
                parentItem.setBackgroundColor(getContext().getResources().getColor(R.color.green,null));
            }
    

    3.在listview的点击item事件中

    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    adapter.setCurrentItem(position);
                    adapter.setClick(true);
                    adapter.notifyDataSetChanged();
                }
            });
    

    四、当手指在listview滑动时listview又去重新加载数据,保持原先的位置不会跳回第一行

    1.设置listview的滑动监听setOnScrollListener

                //记住上一次滚动时的位置信息
                listView.setOnScrollListener(new AbsListView.OnScrollListener(){
                @Override
                public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                    //滚动时一直回调,直到停止滚动时才停止回调。单击时回调一次。
                    //firstVisibleItem:当前能看见的第一个列表项ID(从0开始)
                    //visibleItemCount:当前能看见的列表项个数(小半个也算)
                    //totalItemCount:列表项共数
    
                    //手指滑动时一直回调
                    firstVisibleId = firstVisibleItem;
                    View item = listView.getChildAt(0);
                    firstVisiblePositionTop = (item == null) ? 0 : item.getTop();
                }
                @Override
                public void onScrollStateChanged(AbsListView view , int scrollState){
                    //正在滚动时回调,回调2-3次,手指没抛则回调2次。scrollState = 2的这次不回调
                    //回调顺序如下
                    //第1次:scrollState = SCROLL_STATE_TOUCH_SCROLL(1) 正在滚动
                    //第2次:scrollState = SCROLL_STATE_FLING(2) 手指做了抛的动作(手指离开屏幕前,用力滑了一下)
                    //第3次:scrollState = SCROLL_STATE_IDLE(0) 停止滚动
                    //只有停止滑动时才会回调,可以使用上面额那个函数滑动时一直回调
                    if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE ) {
                        //获得当前可见的第一个item,然后计算离最顶部的y轴的偏移量
                        firstVisibleId = listView.getFirstVisiblePosition();
                        View item = listView.getChildAt(0);
                        firstVisiblePositionTop = (item == null) ? 0 : item.getTop();
                    }
                }
            });
    

    getChildAt(index)获取某个指定position的view,并对该view进行刷新。

    注意:在ListView中,使用getChildAt(index)的取值,只能是当前可见区域(列表可滚动)的子项! 
    即取值范围在 >= ListView.getFirstVisiblePosition() &&  <= ListView.getLastVisiblePosition(); 
    1)所以如果想获取前部的将会出现返回Null值空指针问题; 
    2)getChildCount跟getCount获取的值将会不一样(数量多时); 
    3 )如果使用了getChildAt(index).findViewById(...)设置值的话,滚动列表时值就会改变了。 
       需要使用getFirstVisiblePosition()获得第一个可见的位置,再用当前的position-它,再用getChildAt取值!即getChildAt(position - ListView。getFirstVisiblePosition()).findViewById(...)去设置值 
    2.如果想更新某一行数据,需要配合ListView的滚动状态使用,一般不滚动时才加载更新数据 
    

    2.设置位置

    //(上一次滑动的可见的位置,这个位置Y轴的偏移量)
    listView.setSelectionFromTop(firstVisibleId , firstVisiblePositionTop);
    

    五、布局中ScrollerView中嵌套Listview

    1.问题

    ScrollView中嵌套使用ListView,ListView只会显示一行多一点。两者进行嵌套,即会发生冲突。

    2.原因

    由于ListView本身都继承于ScrollView,一旦在ScrollView中嵌套ScrollView,
    那么里面的ScrollView高度计算就会出现问题。我们也就无法得到想要的效果。

    3.解决办法

    重写ListView的omMeasure的高度

    public class MyListView extends ListView {
    
        public MyListView(Context context) {
            super(context);
        }
    
        public MyListView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public MyListView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
                    MeasureSpec.AT_MOST);
    
            super.onMeasure(widthMeasureSpec, expandSpec);
        }
    
    }
    
    

    六、android:divider="@null"去掉自带的分割线

    相关文章

      网友评论

          本文标题:Android-ListView开发注意细节

          本文链接:https://www.haomeiwen.com/subject/qyjinhtx.html