Android的ViewGroup添加GridView实现Launcher滑动GridView的item点击无效

黄青 发布于 2013/05/01 11:30
阅读 2K+
收藏 0

实现了ViewGroup中动态创建GridView的功能,类似Launcher展示应用,但是动态添加的GridView的OnItemOnItemClickListener,事件始终无效。请各位大侠帮忙看看是什么原因造成的。

 scrollLayout.java

 

/**
 * 仿Launcher中的WorkSapce,可以左右滑动切换屏幕的类
 * 
 */
public class AppScrollLayout extends ViewGroup {

	private static final String TAG = "ScrollLayout";
	private Scroller mScroller;
	private VelocityTracker mVelocityTracker;

	private int mCurScreen;
	private int mDefaultScreen = 0;

	private static final int TOUCH_STATE_REST = 0;
	private static final int TOUCH_STATE_SCROLLING = 1;

	private static final int SNAP_VELOCITY = 600;

	private int mTouchState = TOUCH_STATE_REST;
	private int mTouchSlop;
	private float mLastMotionX;
	private float mLastMotionY;

	private int currentScreenIndex = 0;

	private Context mContext;
	LayoutInflater mInflater;

	public int getCurrentScreenIndex() {
		return currentScreenIndex;
	}

	public void setCurrentScreenIndex(int currentScreenIndex) {
		this.currentScreenIndex = currentScreenIndex;
	}

	public AppScrollLayout(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
		// TODO Auto-generated constructor stub
	}

	public AppScrollLayout(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// TODO Auto-generated constructor stub
		mScroller = new Scroller(context);
		mContext = context;
		mInflater = LayoutInflater.from(mContext);
		mCurScreen = mDefaultScreen;
		mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
	}

	private List<AppInfo> data;
	private int pageSize = 12;

	/**
	 * 构建数据
	 */
	public void CreateView(List<AppInfo> list) {
		// 清空所有的视图
		this.removeAllViews();
		data = list;
		// 根据数据创建GridView
		List<AppInfo> item = new ArrayList<AppInfo>();
		for (int j = 0; j < data.size(); j++) {
			item.add(data.get(j));
			if (item.size() == pageSize) {
				View v = mInflater.inflate(R.layout.gridview, null);
				GridView gv = (GridView) v.findViewById(R.id.GridView01);
				gv.setOnItemClickListener(new onItemClickListener());
				addGridView(gv, list);
				item.clear();
			}
		}
		if (item.size() > 0) {
			View v = mInflater.inflate(R.layout.gridview, null);
			MyGridView gv = (MyGridView) v.findViewById(R.id.GridView01);
			addGridView(gv, list);
			item.clear();
		}

		// invalidate();
	}

	class onItemClickListener implements AdapterView.OnItemClickListener {
//		final List<AppInfo> mList;
//		public onItemClickListener(List<AppInfo> list) {
//			// TODO Auto-generated constructor stub
//			mList = list;
//		}

		@Override
		public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
				long arg3) {
			// TODO Auto-generated method stub
//			AppInfo info = mList.get(arg2);
			ToastUtil.ShowToast(mContext, "应用:", Toast.LENGTH_LONG);
		}

	}

	// 添加GridView
	private void addGridView(GridView gv, List<AppInfo> list) {
		SimpleAdapter adapter = getMenuAdapter(list);
		// gv.setAdapter(new MyAdapter(mContext, list));
		gv.setAdapter(adapter);

		adapter.setViewBinder(new ViewBinder() {

			@Override
			public boolean setViewValue(View view, Object data,
					String textRepresentation) {
				// TODO Auto-generated method stub
				if (view instanceof ImageView && data instanceof Drawable) {
					ImageView iv = (ImageView) view;
					iv.setImageDrawable((Drawable) data);
					return true;
				} else
					return false;
			}
		});
		this.addView(gv);
	}

	private SimpleAdapter getMenuAdapter(List<AppInfo> list) {
		ArrayList<HashMap<String, Object>> data = new ArrayList<HashMap<String, Object>>();
		for (int i = 0; i < list.size(); i++) {
			final AppInfo info = list.get(i);
			HashMap<String, Object> map = new HashMap<String, Object>();
			map.put("itemImage", ImageUtil.BitmapTodrawable(info.getIcon()));
			map.put("itemText", info.getAppName());
			data.add(map);
		}
		SimpleAdapter simperAdapter = new SimpleAdapter(mContext, data,
				R.layout.griditem, new String[] { "itemImage", "itemText" },
				new int[] { R.id.item_image, R.id.item_text });

		return simperAdapter;
	}
	/**
	 * 构造分页视图
	 * @param linearLayout
	 */
	public void CreatePageView(LinearLayout linearLayout) {
		linearLayout.removeAllViews();
		final int childCount = getChildCount();
		for (int i = 0; i < childCount; i++) {
			ImageView iv = new ImageView(mContext);
			LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(
					LinearLayout.LayoutParams.WRAP_CONTENT,
					LinearLayout.LayoutParams.WRAP_CONTENT);
			p.gravity = Gravity.CENTER_VERTICAL;
			iv.setLayoutParams(p);
			iv.setClickable(true);
			iv.setPadding(15, 15, 15, 15);
			iv.setImageResource(R.drawable.notcurrent);
			linearLayout.addView(iv);
		}

	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		// TODO Auto-generated method stub
		int childLeft = 0;
		final int childCount = getChildCount();
		System.out.println("childCount=" + childCount);
		for (int i = 0; i < childCount; i++) {
			final View childView = getChildAt(i);
			if (childView.getVisibility() != View.GONE) {
				final int childWidth = childView.getMeasuredWidth();
				childView.layout(childLeft, 0, childLeft + childWidth,
						childView.getMeasuredHeight());
				childLeft += childWidth;
			}
		}
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		Log.e(TAG, "onMeasure");
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);

		final int width = MeasureSpec.getSize(widthMeasureSpec);
		final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
		if (widthMode != MeasureSpec.EXACTLY) {
			throw new IllegalStateException(
					"ScrollLayout only canmCurScreen run at EXACTLY mode!");
		}

		final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
		if (heightMode != MeasureSpec.EXACTLY) {
			throw new IllegalStateException(
					"ScrollLayout only can run at EXACTLY mode!");
		}

		// The children are given the same width and height as the scrollLayout
		final int count = getChildCount();
		for (int i = 0; i < count; i++) {
			getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
		}
		System.out.println("moving to screen " + mCurScreen);
		scrollTo(mCurScreen * width, 0);
	}

	/**
	 * According to the position of current layout scroll to the destination
	 * page.
	 */
	public void snapToDestination() {
		final int screenWidth = getWidth();
		final int destScreen = (getScrollX() + screenWidth / 2) / screenWidth;
		snapToScreen(destScreen);
		onScreenChangeListener.onScreenChange(mCurScreen);
		// onScreenChangeListenerDataLoad.onScreenChange(mCurScreen);
	}

	public void snapToScreen(int whichScreen) {
		// get the valid layout page
		whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1));
		if (getScrollX() != (whichScreen * getWidth())) {

			final int delta = whichScreen * getWidth() - getScrollX();
			mScroller.startScroll(getScrollX(), 0, delta, 0,
					Math.abs(delta) * 2);
			mCurScreen = whichScreen;
			invalidate(); // Redraw the layout
		}
	}

	public void setToScreen(int whichScreen) {
		whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1));
		mCurScreen = whichScreen;
		scrollTo(whichScreen * getWidth(), 0);
	}

	public int getCurScreen() {
		return mCurScreen;
	}

	@Override
	public void computeScroll() {
		// TODO Auto-generated method stub
		if (mScroller.computeScrollOffset()) {
			scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
			postInvalidate();
		}
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub

		if (mVelocityTracker == null) {
			mVelocityTracker = VelocityTracker.obtain();
		}
		mVelocityTracker.addMovement(event);

		final int action = event.getAction();
		final float x = event.getX();
		final float y = event.getY();

		switch (action) {
		case MotionEvent.ACTION_DOWN:
			Log.e(TAG, "event down!");
			if (!mScroller.isFinished()) {
				mScroller.abortAnimation();
			}
			mLastMotionX = x;
			break;

		case MotionEvent.ACTION_MOVE:
			int deltaX = (int) (mLastMotionX - x);
			mLastMotionX = x;

			scrollBy(deltaX, 0);
			break;

		case MotionEvent.ACTION_UP:
			Log.e(TAG, "event : up");

			// if (mTouchState == TOUCH_STATE_SCROLLING) {
			final VelocityTracker velocityTracker = mVelocityTracker;
			velocityTracker.computeCurrentVelocity(1000);
			int velocityX = (int) velocityTracker.getXVelocity();

			Log.e(TAG, "velocityX:" + velocityX);

			if (velocityX > SNAP_VELOCITY && mCurScreen > 0) {
				// Fling enough to move left
				Log.e(TAG, "snap left");
				onScreenChangeListener.onScreenChange(mCurScreen - 1);
				System.out.println("mCurScreen=" + (mCurScreen - 1));
				snapToScreen(mCurScreen - 1);
			} else if (velocityX < -SNAP_VELOCITY
					&& mCurScreen < getChildCount() - 1) {
				// Fling enough to move right
				Log.e(TAG, "snap right");
				onScreenChangeListener.onScreenChange(mCurScreen + 1);
				// //只往右移动才加载数据
				// onScreenChangeListenerDataLoad.onScreenChange(mCurScreen+1);
				snapToScreen(mCurScreen + 1);
			} else {
				snapToDestination();
			}

			if (mVelocityTracker != null) {
				mVelocityTracker.recycle();
				mVelocityTracker = null;
			}
			// }
			mTouchState = TOUCH_STATE_REST;
			break;
		case MotionEvent.ACTION_CANCEL:
			mTouchState = TOUCH_STATE_REST;
			break;
		}

		return true;
	}

	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		// TODO Auto-generated method stub
		Log.e(TAG, "onInterceptTouchEvent-slop:" + mTouchSlop);

		final int action = ev.getAction();
		if ((action == MotionEvent.ACTION_MOVE)
				&& (mTouchState != TOUCH_STATE_REST)) {
			Log.i(TAG, "onInterceptTouchEvent-move1:" + mTouchState);
			return true;
		}

		final float x = ev.getX();
		final float y = ev.getY();

		switch (action) {
		case MotionEvent.ACTION_MOVE:
			final int xDiff = (int) Math.abs(mLastMotionX - x);
			if (xDiff > mTouchSlop) {
				mTouchState = TOUCH_STATE_SCROLLING;
				Log.i(TAG, "onInterceptTouchEvent-move:" + mTouchState);
			}
			break;

		case MotionEvent.ACTION_DOWN:
			mLastMotionX = x;
			mLastMotionY = y;
			mTouchState = mScroller.isFinished() ? TOUCH_STATE_REST
					: TOUCH_STATE_SCROLLING;
			Log.i(TAG, "onInterceptTouchEvent-down:" + mTouchState);
			break;

		case MotionEvent.ACTION_CANCEL:
		case MotionEvent.ACTION_UP:
			mTouchState = TOUCH_STATE_REST;
			Log.i(TAG, "onInterceptTouchEvent-up:" + mTouchState);
			break;
		}

		return mTouchState != TOUCH_STATE_REST;
	}

	// 分页监听
	public interface OnScreenChangeListener {
		void onScreenChange(int currentIndex);
	}

	private OnScreenChangeListener onScreenChangeListener;

	public void setOnScreenChangeListener(
			OnScreenChangeListener onScreenChangeListener) {
		this.onScreenChangeListener = onScreenChangeListener;
	}

	// 动态数据监听
	public interface OnScreenChangeListenerDataLoad {
		void onScreenChange(int currentIndex);
	}

	private OnScreenChangeListenerDataLoad onScreenChangeListenerDataLoad;

	public void setOnScreenChangeListenerDataLoad(
			OnScreenChangeListenerDataLoad onScreenChangeListenerDataLoad) {
		this.onScreenChangeListenerDataLoad = onScreenChangeListenerDataLoad;
	}

}
以上是代码,请各位帮个忙!!谢谢!!

加载中
0
黄青
黄青

已解决!

kongnanlive
kongnanlive
最好能发布解决办法。谢谢。
0
只求一醉

把解决方案说一下吧。

我的猜测应该是onTouchEvent 最后一行改为:

return mTouchState != TOUCH_STATE_REST;

返回顶部
顶部