[关闭]
@natsumi 2016-08-26T02:00:53.000000Z 字数 2797 阅读 1201

天天的微博客户端——GridView

天天的微博客户端


总结一下写微博客户端显示图片的gridview时遇到的问题

1. gridview空白处点击事件的处理

图片用gridview显示时,如果图片数量为{2,4,6,9}时,gridview会被填满,而图片数量为其他数时,gridview中会有grid是空着的。
点击图片时可以正常响应gridview的onItemClick,点击空白处不会触发gridview的onItemClick也不会触发外层view的onClick
但是我希望空白处的点击事件可以传递给parent view

解决:
参考:点击空白地方事件扩展
继承gridview重载onTouchEvent方法。
判断点击位置处于空白处:用pointToPosition方法将touch位置坐标转化成gridview的position,当这个方法返回的position为-1就表示点击的位置是没有放图片的

2. GridView和其他ScrollView嵌套的问题

gridview外层是用recyclerview显示的微博列表,gridview每次智能显示一行图片。

解决:
参考: 笔记12--GridView--且解决与ScrollView共用的冲突问题
在继承的gridview中重载onMeasure函数即可
调用super.onMeasure方法时将第二个参数由heightMeasureSpec换成修改后的expandSpec
,expandSpec由MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST)获得,即这个高度最大不能超过Integer.MAX_VALUE >> 2,MeasureSpec高两位是SpecMode(这里是AT_MOST),后面三十位是SpecSize。Integer.MAX_VALUE >> 2即最大的三十位有符号整数,所以就是对尺寸上限不限制。expandSpec可以理解为真正的wrap_content(在布局文件里设置GridView高度wrap_content,GridView控件也不会改变宽高,显示不全时,会以滚动条的方式出现,而且你不去拖动他不会出现滚动条)

所以最后GridView的代码如下~
xml中也直接用package.name.NoScrollGridView替代GridView

  1. /**
  2. * Created by tiantian on 16-7-5.
  3. */
  4. public class NoScrollGridView extends GridView {
  5. private OnTouchInvalidPositionListener mTouchInvalidPosListener;
  6. public NoScrollGridView(Context context) {
  7. super(context);
  8. }
  9. public NoScrollGridView(Context context, AttributeSet attrs) {
  10. super(context, attrs);
  11. }
  12. public NoScrollGridView(Context context, AttributeSet attrs, int defStyleAttr) {
  13. super(context, attrs, defStyleAttr);
  14. }
  15. @Override
  16. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  17. int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
  18. super.onMeasure(widthMeasureSpec, expandSpec);
  19. }
  20. public interface OnTouchInvalidPositionListener {
  21. /**
  22. * motionEvent 可使用 MotionEvent.ACTION_DOWN 或者 MotionEvent.ACTION_UP等来按需要进行判断
  23. *
  24. * @return 是否要终止事件的路由
  25. */
  26. boolean onTouchInvalidPosition(int motionEvent);
  27. }
  28. /**
  29. * 点击空白区域时的响应和处理接口
  30. */
  31. public void setOnTouchInvalidPositionListener(OnTouchInvalidPositionListener listener) {
  32. mTouchInvalidPosListener = listener;
  33. }
  34. @Override
  35. public boolean onTouchEvent(MotionEvent event) {
  36. if (mTouchInvalidPosListener == null) {
  37. return super.onTouchEvent(event);
  38. }
  39. if (!isEnabled()) {
  40. // A disabled view that is clickable still consumes the touch
  41. // events, it just doesn't respond to them.
  42. return isClickable() || isLongClickable();
  43. }
  44. final int motionPosition = pointToPosition((int) event.getX(), (int) event.getY());
  45. if (motionPosition == INVALID_POSITION) {
  46. super.onTouchEvent(event);
  47. return mTouchInvalidPosListener.onTouchInvalidPosition(event.getActionMasked());
  48. }
  49. return super.onTouchEvent(event);
  50. }
  51. }

发现点击空白处时返回mTouchInvalidPosListener.onTouchInvalidPosition(event.getActionMasked()),这里mTouchInvalidPosListener是通过setOnTouchInvalidPositionListener方法设置的。

  1. holder.gridStatusImg.setOnTouchInvalidPositionListener(new NoScrollGridView.OnTouchInvalidPositionListener() {
  2. @Override
  3. public boolean onTouchInvalidPosition(int motionEvent) {
  4. return false; //不终止路由事件让父级控件处理事件
  5. }
  6. });

这样就可以将点击事件传递下去啦~

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注