android 重写GridView,让子View能够按指定的大小展示

现在回过头里看,这篇文章真是写的没有意义,还是我的见识太短了,只需设置android:columnWidth="65dp"就可以搞定我的需求,惭愧!还是不删除这文章了,警示用。


最近涉及到gridView的用处,但是之前之一都是指定每行展示的个数,android:numColumns="4",用android:numColumns="auto_fit"感觉不太好用,我实际给每个子View设置的宽和高都是65dp,但是展示的时候却只给我展示两列,我觉得很恼火,怎么弄就弄不好,于是下决心自己写。照样先放代码:

package com.fyr.rouhome.ui.view;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.GridView;

import com.fyr.rouhome.util.DensityUtil;

public class MyGridView extends GridView{
	Context context;
	boolean isTouch;//防止点击的时候滑动
	int child_w;
	int per = 15;//间隔
	public MyGridView(Context context) {
		super(context);
		initParams(context);
	}
	public MyGridView(Context context, AttributeSet attrs) {
		super(context, attrs);
		initParams(context);
	}
	private void initParams(Context context){
		this.context = context;
		child_w = DensityUtil.dipTopx(context, 65);
	}
	/**通过重新dispatchTouchEvent方法来禁止滑动*/
	@Override
	public boolean dispatchTouchEvent(MotionEvent ev) {
	// TODO Auto-generated method stub
		isTouch = true;
		/**禁止Gridview进行滑动*/
		if (ev.getAction() == MotionEvent.ACTION_MOVE) {
              return true;
		}
		return super.dispatchTouchEvent(ev);
	}
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		// TODO Auto-generated method stub
		int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
	}
	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		super.onLayout(changed, l, t, r, b);
		int count = getChildCount();
		int width = getWidth();
		int child_x = 0;
		int child_y = 0;
		for(int i=0;i<count;i++){
			View child = getChildAt(i);
			if(child_x+child_w>width){
				child_y = child_y+child_w+per;
				child_x = 0;
			}
			child.measure(child_w, child_w);
			child.layout(child_x, child_y, child_x+child_w, child_y+child_w);
			child_x = child_x+ child_w + per;
		}
	}
	@Override
	protected void layoutChildren() {
		// TODO Auto-generated method stub
		if(!isTouch){
			super.layoutChildren();
		}
		isTouch = false;
	}
	
}


说明:这里我给每个子View设置的宽高都是65dp,然后根据屏幕的宽度自适应展示。这里我屏蔽掉了GridView的滑动事件,因为我的需求不需要滑动。其实这里可以自己继承ViewGroup,但是自己比较懒,没有去那么做,有兴趣的同学可以去试试。另外说一下layoutChildren()方法,每次触摸GridView的时候都会出发这个方法,然后会重新布局,且不走onLayout()方法,然后我就给屏蔽了,不然显示会乱。

再有一个坑就是往adapter中添加数据的时候在onMeasure中得到子View的个数还是添加之前的。这也是个坑,后来没办法,把测量children的方法放到了onLayout()里。

鼓捣了半天终于实现了,小伙伴们也自己试试吧,总感觉应该有更好的方法,只是目前我想不到,希望知道的朋友能够交流一下。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值