开发者社区> 问答> 正文

添加GridView实现Launcher滑动GridView的item点击无效 : 配置报错 

Android的ViewGroup添加GridView实现Launcher滑动GridView的item点击无效 实现了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;
}

}

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

展开
收起
kun坤 2020-06-04 11:59:14 478 0
1 条回答
写回答
取消 提交回答
  • 已解决! ######最好能发布解决办法。谢谢。###### 把解决方案说一下吧。
    我的猜测应该是onTouchEvent 最后一行改为:
    return mTouchState != TOUCH_STATE_REST;

    2020-06-05 13:13:48
    赞同 展开评论 打赏
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载