[Android]在ListView嵌套GridView中出现的点击事件处理以及gridview显示不全的问题
html
写这篇博文也是出于偶然看到本身好久之前写的一堆“烂码”,目的是为了实现一个ListView中可以嵌入GridView的功能,为了展现图文的一个Item,这是一个很普通的功能,但在那时候什么都不懂的我还在本身摸索摔了不少跟头,如今看看确实难堪,并且还有有不少的bug,因此就想挑出一两个解决一下,为了一些像当年我通常的小伙伴提供可行性高的解决方式,特意写了这篇整理性质的博文。(高手就没必要看了)java
就是想实现相似这个效果。(由于的demo,不要关注好很差看了)android
那先讲讲主要出现的几个问题吧:ide
1.listview出现点击控件无效的状况,onItemClick事件无响应的状况,再自定义item的视图的过程当中加入了gridview、checkbox、imageButton等控件,而后就可能出现这种没法触发onItemClickListener的问题。布局
个人解决方法是 在本身定义的item的布局最外层的layout 加入 这个标签 android:descendantFocusability="blocksDescendants",就能够点击了,这是什么意思呢?就好像是把布局中全部抢viewgroup焦点的控件所有覆盖了先,意味着这个自定义布局就不会受其中的子控件的影响而失去点击时间吧,我是这么想的。this
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@color/white" android:descendantFocusability="blocksDescendants" android:orientation="vertical" > ...........
2.在嵌套gridview的时候,gridview只显示一行的问题。在使用中发现这个问题,而后试着指定gridview的height,发现他尽然只显示一行,我认为这是由于嵌套的外层listview是具备scroll的功能,以致于listview不关注内部控件,如gridview的高度,并不会去自增加gridview的高度,因此解决方法很简单,就是咱们必须重写gridview的onMeasue()方法了。spa
我是这么作的先继承Gridvewi,而后重写onMeasure.以下代码:code
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); }
3.嵌套了GridView以后,发现无图的空白区域里面没有触发点击事件,既不能触发girdview的onItemClick,也不触发Listview的onItemClick怎么回事呢,后来发现,原来能够本身去监听GridView的无效区域的触发事件的。orm
下面是我实现的gridview代码:xml
package com.example.testlistview; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.widget.GridView; public class MyGridView extends GridView { private OnTouchInvalidPositionListener onTouchInvalidPositionListener; public MyGridView(Context context) { super(context); } public MyGridView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); } @Override public boolean onTouchEvent(MotionEvent ev) { //先建立一个监听接口,一旦点击了无效区域,便实现onTouchInvalidPosition方法,返回true or false来确认是否消费了这个事件 if(onTouchInvalidPositionListener!=null){ if(!isEnabled()){ return isClickable()||isLongClickable(); } int motionPosition = pointToPosition((int)ev.getX(), (int)ev.getY()); if(ev.getAction()==MotionEvent.ACTION_UP&&motionPosition == INVALID_POSITION){ super.onTouchEvent(ev); return onTouchInvalidPositionListener.onTouchInvalidPosition(motionPosition); } } return super.onTouchEvent(ev); } public void setOnTouchInvalidPositionListener( OnTouchInvalidPositionListener onTouchInvalidPositionListener) { this.onTouchInvalidPositionListener = onTouchInvalidPositionListener; } public interface OnTouchInvalidPositionListener{ public boolean onTouchInvalidPosition(int motionEvent); } }