您的位置:首页 > 移动开发 > Android开发

Android随记------GalleryView禁止选中项目向中间滑动

2012-04-01 15:59 375 查看
相册控件Gallery里,点击选中其中的项目,会自动将选中的项目滑动到中间。不过最近项目中遇到需要实现禁止这种滑动,大致折腾一番基本实现这种效果。

Gallery类本身没有提供能直接设置这种效果的方法,setXXX或onXXX方法之类的,基本确立得自定义一个Gallery了。

首先,Gallery里出发点击事件会响应Gallery的onSingleTapUp方法(无论点击到项目还是空白部分),andriod 官方的说明为“Notified when a tap occurs with the up MotionEvent
that triggered it.”

看一下源码,android.widget.Gallery---(注:这边看的都是2.2的源码)

public boolean onSingleTapUp(MotionEvent e) {

if (mDownTouchPosition >= 0) {

// An item tap should make it selected, so scroll to this child.
scrollToChild(mDownTouchPosition - mFirstPosition);

// Also pass the click so the client knows, if it wants to.
if (mShouldCallbackOnUnselectedItemClick || mDownTouchPosition == mSelectedPosition) {
performItemClick(mDownTouchView, mDownTouchPosition, mAdapter
.getItemId(mDownTouchPosition));
}

return true;
}

return false;
}


注意到这里的红色部分的scrollToChild方法,这名字.........跟进去看

private boolean scrollToChild(int childPosition) {
View child = getChildAt(childPosition);

if (child != null) {
int distance = getCenterOfGallery() - getCenterOfView(child);
mFlingRunnable.startUsingDistance(distance);
return true;
}

return false;
}


很清楚看到,Gallery响应点击事件会自动把选中项目滚到中间的原因了....

另外,Gallery不是还有个OnItemClickListener能去自定义吗?看一下onSingleTapUp方法中,scrollToChild执行之后才会调用的performItemClick方法,这个时候才会响应OnItemClickListener的onItemClick方法

android.widget.AdapterView

public boolean performItemClick(View view, int position, long id) {
if (mOnItemClickListener != null) {
playSoundEffect(SoundEffectConstants.CLICK);
mOnItemClickListener.onItemClick(this, view, position, id);
return true;
}

return false;
}


所以我们要做的事情就是自定义一个Gallery重写这个onSingleTapUp方法了

test.view.CustomGallery

public class CustomGallery extends Gallery {

// 自定义的构造方法至少包含这种带两个参数的,不然使用时会报错
public EffectGallery(Context context, AttributeSet attrs) {
super(context, attrs);
}

@Override
public boolean onSingleTapUp(MotionEvent e) {

// 此处添加需要的逻辑
return false;
}

}












注意,方法返回false来隔断后面的操作,不要用true

自定义View在layout里面的使用方法和普通控件类似,只是名字改成 包名+类名即可,例如<test.view.CustomGallery />

做到这里相当于只是屏蔽Gallery本身的点击处理,而且这个方法里并不能得到选中的项目的position之类的信息....

这边采取的做法是,Gallery所绑定的数据Adaptor(自定义)的getView方法中,设置onTouch监听事件来取得点击的postion之类相关信息

大致的代码:

public class MenuEffectGridAdapter extends BaseAdapter {

private Activity mActivity;

private List<CustomDto> mResList;

private int touchPositon = -1;

public MenuEffectGridAdapter(Activity pActivity, List<CustomDto> pResList) {
mActivity = pActivity;
mResList = pResList;
}

@Override
public int getCount() {
return mResList.size();
}

@Override
public Object getItem(int position) {
return mResList.get(position);
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

View view = convertView;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.customLayout, null);
}

final int selectPostion = position;
view.setOnTouchListener(new OnTouchListener() {

@Override
public boolean onTouch(View v, MotionEvent event) {
touchPositon = selectPostion;
return false;
}
});

// 如果使用onClick监听,会导致Gallery里,触及子项目View无法进行滑动,原因不明,待查
//view.setOnClickListener(new OnClickListener() {

//	@Override
//	public void onClick(View v) {
//
//	}
//});
return view;
}

public int getTouchPositon() {
return touchPositon;
}

public void setTouchPostion(int position) {
touchPositon = position;
}
}


这样,基本绕开了Gallery本身的点击后自动滑动到中间的现象,其中需要注意的是,Gallery中点击空白区域小心position的处理。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: