无限循环的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
原创粉丝点击