无限循环的LinearLayout
来源:互联网 发布:大数据的国外研究现状 编辑:程序博客网 时间:2024/05/16 02:10
程序猿最讨厌的事情不是需求多难实现,而是设计师不断蛋疼的改变需求。。上文的童鞋无限循环的scrollview的需求在设计师的要求下必须换掉,这次的需求改成了主屏幕上三个button,实现无限循环滑动,每次滑动只能滑出来一个,不死心的我在上文scrollview上奋战了一天,还是敌不过不停出现的BUG,忍无可忍,于是重写。。这次被重写的控件是很熟悉的LinearLayout,需求的实现近乎完美,但是赶工的缘故,里面会有一些hardcode,接口基本没加,有需求的童鞋自行修改,废话少说,源码奉上:
public class NewHorizontalLinearlayout extends LinearLayout implements
OnGestureListener {
private int mScreenWidth;private int mChildWidth;private int mFirstPos;private int mMiddlePos;private int mLastPos;private float lastX;private GestureDetector mDetector;private Map<View, Integer> mViewPos = new HashMap<View, Integer>();private static final int BUTTTON_COUNT = 5;LayoutParams params;public NewHorizontalLinearlayout(Context context, AttributeSet attrs) { super(context, attrs); WindowManager wm = (WindowManager) context .getSystemService(Context.WINDOW_SERVICE); DisplayMetrics outMetrics = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(outMetrics); mScreenWidth = outMetrics.widthPixels; mDetector = new GestureDetector(getContext(), this); init();}public void init() { mChildWidth = mScreenWidth / 3; params = new LayoutParams(mChildWidth, LayoutParams.WRAP_CONTENT); Button b; for (int i = 0; i < BUTTTON_COUNT; i++) { b = new Button(getContext()); b.setText("button" + i); // b.setEnabled(false); addView(b, params); mViewPos.put(b, i); } scrollTo(mChildWidth, 0); mFirstPos = 1; mMiddlePos = 2; mLastPos = 3;}@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) { return true;}@Overridepublic boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: lastX = event.getRawX(); break; case MotionEvent.ACTION_UP: float nowX = event.getRawX(); float delta = lastX - nowX; if (delta >= 0) { if ((delta) >= mChildWidth / 3) { loadNext(); } else { // scrollback scrollBy((int) -delta, 0); } } else { if ((delta) <= -mChildWidth / 3) { loadPre(); } else { scrollBy((int) -delta, 0); } } default: break; } mDetector.onTouchEvent(event); return true;}private void loadPre() { int addIndex = mViewPos.get(getChildAt(getChildCount() - 1)); Button addButton = new Button(getContext()); addButton.setText("button" + addIndex); removeViewAt(getChildCount() - 1); if (mFirstPos == 0) { mFirstPos = BUTTTON_COUNT - 1; } else { mFirstPos = mFirstPos - 1; } countIndex(mFirstPos); scrollTo(mChildWidth, 0); addView(addButton, 0, params); mViewPos.put(addButton, addIndex);}private void loadNext() { int addIndex = mViewPos.get(getChildAt(0)); Button addButton = new Button(getContext()); addButton.setText("button" + addIndex); removeViewAt(0); mFirstPos = mMiddlePos; mMiddlePos = mLastPos; if (mMiddlePos == BUTTTON_COUNT - 1) { mLastPos = 0; } else { mLastPos = mMiddlePos + 1; } scrollTo(mChildWidth, 0); addView(addButton, BUTTTON_COUNT - 1, params); mViewPos.put(addButton, addIndex);}private void countIndex(int firstIndex) { if (firstIndex == BUTTTON_COUNT - 1) { mMiddlePos = 0; mLastPos = 1; } if (firstIndex == BUTTTON_COUNT - 2) { mMiddlePos = BUTTTON_COUNT - 1; mLastPos = 0; } else { mMiddlePos = firstIndex + 1; mLastPos = firstIndex + 2; }}@Overridepublic boolean onDown(MotionEvent arg0) { // TODO Auto-generated method stub return false;}@Overridepublic boolean onFling(MotionEvent mCurrentDownEvent, MotionEvent ev, float scrollX, float scrollY) { // scrollTo((int) scrollX, (int) scrollY); return false;}@Overridepublic void onLongPress(MotionEvent arg0) { // TODO Auto-generated method stub}@Overridepublic boolean onScroll(MotionEvent mCurrentDownEvent, MotionEvent ev, float scrollX, float scrollY) { scrollBy((int) scrollX, 0); return false;}@Overridepublic void onShowPress(MotionEvent arg0) { // TODO Auto-generated method stub}private boolean inChild(int x, int y, View child) { int[] loc = new int[2]; child.getLocationOnScreen(loc); int childX = loc[0]; int childY = loc[1]; return (y > childY && y <= childY + child.getHeight() && x > childX && x <= childX + child.getWidth());}@Overridepublic boolean onSingleTapUp(MotionEvent ev) { // Toast.makeText(getContext(), "show", 0).show(); int x = (int) ev.getRawX(); int y = (int) ev.getRawY(); for (int i = 0; i < 3; i++) { View v = getChildAt(i + 1); if (inChild(x, y, v)) { int pos = mViewPos.get(v); Toast.makeText(getContext(), "b" + pos, Toast.LENGTH_SHORT) .show(); } } return false;}
}
核心部分的处理还是在loadNext和loadPre,主要的设计思想就是3个view占据主屏,另外两个view分别在屏幕左右侧不可见位置,瑕疵是对view点击事件的处理,如果使用setOnclickListener方式处理,会出现很难处理的触摸冲突,为了赶工采用了取巧的方式,计算了点击位置,并响应对应位置的点击事件(OnGestureListener 点击事件),缺点就是Button失去了点击效果,并非真正的点击。
0 0
- 无限循环的LinearLayout
- 无限循环的ViewPager
- 无限循环的计时器
- 无限循环的HorizontalScrollview
- 无限循环的Viewpager
- for结构的无限循环
- 无限循环的一种表示
- 终止无限循环的线程
- 无限循环小数的循环节
- viewpager的无限循环方法
- 无限循环的图片浏览器
- 无限循环的图片轮播器
- 轮播图的伪无限循环
- ViewPage的无限循环(五)
- viewpager无限循环的问题
- 删除无限循环的文件夹。
- 循环的中断与无限循环
- 无限循环
- GCC编译器和GDB调试器
- xcode安装facebook pop开源框架
- android翻书效果实现原理( 贝塞尔曲线绘制原理/点坐标计算)
- StringUtil类的用法
- Ant入门教程之安装配置
- 无限循环的LinearLayout
- Linux网络编程--6. 高级套接字函数
- 验证视图状态 MAC 失败的解决办法
- volley okhttp universal-image-loader对比分析
- Xcode 下删除Provisioning Profiles文件
- 不要在init和dealloc函数中使用accessor
- OGG-03510问题处理
- C#读取某个目录下的所有excel文件名
- PHP的APC组件