From 5902e77211b99bffd98ebdc53e1683cafae95ac1 Mon Sep 17 00:00:00 2001 From: l465659833 Date: Fri, 5 Aug 2016 23:44:59 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E5=BE=AA=E7=8E=AF?= =?UTF-8?q?=E6=BB=9A=E5=8A=A8=E7=9A=84=E5=BC=80=E5=85=B3=20=E5=AE=8C?= =?UTF-8?q?=E6=88=90=E4=BA=86=E5=BC=80=E5=90=AF=E5=BE=AA=E7=8E=AF=E6=BB=9A?= =?UTF-8?q?=E5=8A=A8=E5=92=8C=E5=85=B3=E9=97=AD=E5=BE=AA=E7=8E=AF=E6=BB=9A?= =?UTF-8?q?=E5=8A=A8=E7=9A=84=E6=95=88=E6=9E=9C=20todo=EF=BC=9A=20?= =?UTF-8?q?=E8=BF=98=E6=9C=89=E4=B8=80=E4=B8=AAbug=E8=A6=81=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=EF=BC=9A=E5=88=9D=E5=A7=8B=E7=8A=B6=E6=80=81=E9=94=99?= =?UTF-8?q?=E4=BD=8D=E4=B8=80=E6=A0=BC=20=E5=AE=8C=E5=96=84=E6=BB=9A?= =?UTF-8?q?=E5=8A=A8=E6=95=88=E6=9E=9C=20=E5=BE=AA=E7=8E=AF=E6=BB=9A?= =?UTF-8?q?=E5=8A=A8=E5=88=B0=E8=BE=B9=E7=BC=98=E6=97=B6=E7=9A=84=E5=9B=9E?= =?UTF-8?q?=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/pl/wheelview/CityPickerLayout.java | 2 +- .../com/pl/wheelview/FromToTimePicker.java | 15 ++ .../main/res/layout/time_picker_situation.xml | 7 +- .../main/java/com/pl/wheelview/WheelView.java | 200 +++++++++++------- wheelview/src/main/res/values/attrs.xml | 1 + 5 files changed, 145 insertions(+), 80 deletions(-) diff --git a/app/src/main/java/com/pl/wheelview/CityPickerLayout.java b/app/src/main/java/com/pl/wheelview/CityPickerLayout.java index 9f2bf47..0a4fed0 100644 --- a/app/src/main/java/com/pl/wheelview/CityPickerLayout.java +++ b/app/src/main/java/com/pl/wheelview/CityPickerLayout.java @@ -51,7 +51,7 @@ protected void onFinishInflate() { String defaultProvince = mProvinceList.get(0); mCityPicker.setData(mAreaDataUtil.getCityByProvince(defaultProvince)); - mCityPicker.setDefault(1); + mCityPicker.setDefault(0); mProvincePicker.setOnSelectListener(new WheelView.OnSelectListener() { @Override diff --git a/app/src/main/java/com/pl/wheelview/FromToTimePicker.java b/app/src/main/java/com/pl/wheelview/FromToTimePicker.java index e82cb41..0670248 100644 --- a/app/src/main/java/com/pl/wheelview/FromToTimePicker.java +++ b/app/src/main/java/com/pl/wheelview/FromToTimePicker.java @@ -161,10 +161,25 @@ public void setCurrentDate(String from,String to){ mFromMinute=TimeUtil.getMinuteFromTime(from); mToHour=TimeUtil.getHourFromTime(to); mToMinute=TimeUtil.getMinuteFromTime(to); + +// mWheelFromHour.setItemNumber(3); +// mWheelFromMinute.setItemNumber(5); +// mWheelToHour.setItemNumber(7); +// mWheelToMinute.setItemNumber(9); + + + mWheelFromHour.setCyclic(false); + mWheelFromMinute.setCyclic(true); + mWheelToHour.setCyclic(false); + mWheelToMinute.setCyclic(true); + mWheelFromHour.setDefault(mFromHour); mWheelFromMinute.setDefault(mFromMinute); mWheelToHour.setDefault(mToHour); mWheelToMinute.setDefault(mToMinute); + + + WeekDay[] allWeekDays=WeekDay.values(); } diff --git a/app/src/main/res/layout/time_picker_situation.xml b/app/src/main/res/layout/time_picker_situation.xml index 7a9165f..cbcadef 100644 --- a/app/src/main/res/layout/time_picker_situation.xml +++ b/app/src/main/res/layout/time_picker_situation.xml @@ -1,5 +1,6 @@ @@ -30,7 +31,7 @@ @@ -46,6 +47,7 @@ @@ -62,6 +64,7 @@ diff --git a/wheelview/src/main/java/com/pl/wheelview/WheelView.java b/wheelview/src/main/java/com/pl/wheelview/WheelView.java index 612e611..362d2f0 100644 --- a/wheelview/src/main/java/com/pl/wheelview/WheelView.java +++ b/wheelview/src/main/java/com/pl/wheelview/WheelView.java @@ -19,7 +19,6 @@ import android.view.View; import android.view.animation.DecelerateInterpolator; import android.view.animation.Interpolator; -import android.widget.Scroller; import com.pl.whellview.R; @@ -88,7 +87,7 @@ public class WheelView extends View { /** * 快速移动的距离 */ - private static final int GOON_MIN_DISTANCE =8;//dp + private static final int GOON_MIN_DISTANCE =5;//dp private int goOnMinDistance;//px /** * 缓慢滚动的时候的速度 @@ -153,6 +152,9 @@ public class WheelView extends View { */ private boolean noEmpty = true; + private boolean isCyclic =true; + private boolean _isCyclic =true; + /** * 正在修改数据,避免ConcurrentModificationException异常 */ @@ -245,6 +247,7 @@ private void init(Context context, AttributeSet attrs) { noEmpty = attribute.getBoolean(R.styleable.WheelView_noEmpty, true); isEnable = attribute.getBoolean(R.styleable.WheelView_isEnable, true); + isCyclic =attribute.getBoolean(R.styleable.WheelView_isCyclic,true); attribute.recycle(); @@ -279,12 +282,19 @@ protected void onDetachedFromWindow() { super.onDetachedFromWindow(); } + private void _setIsCyclic(boolean cyclic){ + if (dataList.size() 0 ?goOnDistance:goOnDistance*(-1)); -// for (ItemObject item : itemList) { -// item.newY(goOnMove > 0 ?goOnDistance:goOnDistance*(-1)); -// } +// Log.d(TAG,"GO_ON_MOVE_INTERRUPTED"); moveDistance+=goOnMove > 0 ?(goOnDistance-lastDistance):(goOnDistance-lastDistance)*(-1); goOnDistance=0; isScrolling = false; @@ -341,18 +345,14 @@ public void handleMessage(Message msg) { */ private synchronized void goonMove(long time, final long move) { showTime=0; -// if (time<=0){ -// time=1; -// } + if (time<=0){ + time=30; + } double n= 5; if (time<100){ n= n*100/time; } // //当时间特别短的时候<50ms,move也不会长,但是用户这时候可能希望滑动的更快一些,此时提高倍数来达到此目的 -// if (time<50 && Math.abs(move)0){ goOnLimit+=newGoonMove; @@ -363,13 +363,9 @@ private synchronized void goonMove(long time, final long move) { isGoOnMove=true; //将MotionEvent.ACTION_MOVE引起的滑动的距离设置为新的起点,然后再开始新的滑动 //防止重复滑动同一次Action_Down中滑动的部分 -// for (ItemObject item : itemList) { -// item.newY((int) (unitHeight*Math.floor(item.move/unitHeight))); -// } -// moveDistance+=move; moveHandler.sendEmptyMessage(GO_ON_MOVE_REFRESH); Log.d(TAG,"goonMove : newGoonMove="+newGoonMove); - Log.d(TAG,"goonMove : goOnLimit="+goOnLimit); +// Log.d(TAG,"goonMove : goOnLimit="+goOnLimit); } @Override @@ -377,7 +373,6 @@ public boolean onTouchEvent(MotionEvent event) { if (!isEnable) return true; int y = (int) event.getY(); - int move = Math.abs(y - lastY); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: //防止被其他可滑动View抢占焦点,比如嵌套到ListView中使用时 @@ -413,7 +408,7 @@ public boolean onTouchEvent(MotionEvent event) { goonMove(time,lastMove); } else { //如果移动距离较小,则认为是点击事件,否则认为是小距离滑动 - if (Math.abs(y-downY)0){ //如果不先move再up,而是直接up,则无法产生点击时的滑动效果 //通过调整move和up的距离,可以调整点击的效果 @@ -452,6 +447,7 @@ private void initData() { itemList.add(itemObject); } isClearing = false; + _setIsCyclic(isCyclic); } @@ -534,7 +530,8 @@ private synchronized void drawList(Canvas canvas) { return; synchronized (toShowItems) { for (ItemObject itemObject : toShowItems) { - itemObject.drawSelf(canvas, getMeasuredWidth()); + if (itemObject!=null) + itemObject.drawSelf(canvas, getMeasuredWidth()); } } } @@ -567,46 +564,46 @@ private void drawMask(Canvas canvas) { * @param moveSymbol 移动的距离,实际上只需要其符号,用于判断当前滑动方向 */ private void noEmpty(int moveSymbol) { - // TODO: 2016/8/1 在边线上的时候会出现多移动一格的问题 ,可能可以通过findToSHowItem只找itemNumber个来解决 if (!noEmpty) return; // 将当前选择项目移动到正中间,防止出现偏差 - Log.d(TAG,"noEmpty start"); +// Log.d(TAG,"noEmpty start"); synchronized (toShowItems) { findItemsToShow(); for (ItemObject item : toShowItems) { - if (item.selected()) { - int move = (int) item.moveToSelected(); - defaultMove(move); - if (onSelectListener != null) - onSelectListener.endSelect(item.id, item.getItemText()); - Log.d(TAG, "noEmpty selected=" + item.id+",movoToSelected= "+move); - return; + if (item!=null) + if (item.selected()) { + int move = (int) item.moveToSelected(); + if (onSelectListener != null) + onSelectListener.endSelect(item.id, item.getItemText()); + defaultMove(move); +// Log.d(TAG, "noEmpty selected=" + item.id+",movoToSelected= "+move); + return; } } // 如果当前没有项目选中,则将根据滑动的方向,将最近的一项设为选中项目,并移动到正中间 if (moveSymbol > 0) { for (int i = 0; i < toShowItems.length; i++) { - if (toShowItems[i].couldSelected()) { + if (toShowItems[i]!=null&&toShowItems[i].couldSelected()) { int move = (int) toShowItems[i].moveToSelected(); - defaultMove(move); if (onSelectListener != null) { onSelectListener.endSelect(toShowItems[i].id,toShowItems[i].getItemText()); } - Log.d(TAG, "noEmpty couldSelected=" + toShowItems[i].id+",movoToSelected= "+move); + defaultMove(move); +// Log.d(TAG, "noEmpty couldSelected=" + toShowItems[i].id+",movoToSelected= "+move); return; } } } else { for (int i =toShowItems.length - 1; i >= 0; i--) { - if (toShowItems[i].couldSelected()) { + if (toShowItems[i]!=null&&toShowItems[i].couldSelected()) { int move = (int)toShowItems[i].moveToSelected(); - defaultMove(move); if (onSelectListener != null) { onSelectListener.endSelect(toShowItems[i].id, toShowItems[i].getItemText()); } - Log.d(TAG, "noEmpty couldSelected=" + toShowItems[i].id+",movoToSelected= "+move); + defaultMove(move); +// Log.d(TAG, "noEmpty couldSelected=" + toShowItems[i].id+",movoToSelected= "+move); return; } } @@ -622,7 +619,7 @@ private void noEmpty(int moveSymbol) { */ private void actionMove(int move) { moveDistance-=move; - Log.d(TAG,"move="+move+",moveDistance="+moveDistance); +// Log.d(TAG,"move="+move+",moveDistance="+moveDistance); findItemsToShow(); invalidate(); } @@ -643,33 +640,72 @@ private void actionThreadMove(int move) { */ private ItemObject[] toShowItems; private void findItemsToShow(){ - if (moveDistance>itemList.size()){ - moveDistance=moveDistance%((int)unitHeight*itemList.size()); - }else if (moveDistance<0){ - moveDistance=moveDistance%((int)unitHeight*itemList.size())+(int)unitHeight*itemList.size(); - } - int move=moveDistance; - // TODO: 2016/8/2 java.lang.IndexOutOfBoundsException: Invalid index 2, size is 1 - ItemObject center= itemList.get(itemNumber/2); - - int centerY=center.y+move; - int centerNumber=(int) (Math.abs(centerY/unitHeight)); - int restMove= (int) (move-unitHeight*centerNumber); - int takeNumberStart=centerNumber-(itemNumber/2+1); - synchronized (toShowItems) { - for (int i = 0; i < toShowItems.length; i++) { - int takeNumber = takeNumberStart + i; - int realNumber = takeNumber; - if (takeNumber < 0) { - realNumber = itemList.size() + takeNumber; - } else if (takeNumber >= itemList.size()) { - realNumber = takeNumber - itemList.size(); - } - toShowItems[i] = itemList.get(realNumber); - toShowItems[i].move = (int) (unitHeight * (i - realNumber - itemNumber / 2)) - restMove; + if (_isCyclic) { + if (moveDistance > unitHeight * itemList.size()) { + moveDistance = moveDistance % ((int) unitHeight * itemList.size()); + } else if (moveDistance < 0) { + moveDistance = moveDistance % ((int) unitHeight * itemList.size()) + (int) unitHeight * itemList.size(); + } + int move = moveDistance; + ItemObject center = itemList.get(itemNumber / 2); + + // TODO: 2016/8/5 向上错位一个位置 + int centerY = center.y + move; + int centerNumber = (int) (Math.abs(centerY / unitHeight)); + int restMove = (int) (centerY - unitHeight * centerNumber); + int takeNumberStart = centerNumber - (itemNumber / 2 + 1); + synchronized (toShowItems) { + for (int i = 0; i < toShowItems.length; i++) { + int takeNumber = takeNumberStart + i; + int realNumber = takeNumber; + if (takeNumber < 0) { + realNumber = itemList.size() + takeNumber; + } else if (takeNumber >= itemList.size()) { + realNumber = takeNumber - itemList.size(); + } + toShowItems[i] = itemList.get(realNumber); + toShowItems[i].move = (int) (unitHeight * ((i - realNumber)%itemList.size())) - restMove; // Log.e(TAG," toShowItems["+i+"] = "+ toShowItems[i].id); + } +// Log.e(TAG,"---------------------------------------------------------------------------------------------------------"); + } + }else { + if (moveDistance > unitHeight * itemList.size()-itemNumber/2*unitHeight-unitHeight) { + moveDistance = (int)( unitHeight * itemList.size()-itemNumber/2*unitHeight-unitHeight); + moveHandler.removeMessages(GO_ON_MOVE_REFRESH); + moveHandler.sendEmptyMessage(GO_ON_MOVE_INTERRUPTED); + } else if (moveDistance < -itemNumber/2*unitHeight) { + moveDistance = (int) (-itemNumber/2*unitHeight); + moveHandler.removeMessages(GO_ON_MOVE_REFRESH); + moveHandler.sendEmptyMessage(GO_ON_MOVE_INTERRUPTED); } + + int move = moveDistance; + ItemObject first = itemList.get(0); + + int firstY = first.y + move; + int firstNumber = (int) (firstY / unitHeight); + int restMove = (int) (firstY - unitHeight * firstNumber); + int takeNumberStart = firstNumber ; + synchronized (toShowItems) { + for (int i = 0; i < toShowItems.length; i++) { + int takeNumber = takeNumberStart + i; + int realNumber = takeNumber; + if (takeNumber < 0) { + realNumber = -1; + } else if (takeNumber >= itemList.size()) { + realNumber = -1; + } + if (realNumber==-1){ + toShowItems[i]=null; + }else { + toShowItems[i] = itemList.get(realNumber); + toShowItems[i].move = (int) (unitHeight * (i - realNumber)) - restMove; + } +// Log.e(TAG," toShowItems["+i+"] = "+ toShowItems[i].id); + } // Log.e(TAG,"---------------------------------------------------------------------------------------------------------"); + } } @@ -690,29 +726,29 @@ private synchronized void slowMove(final int move) { moveHandler.post(new Runnable() { @Override public void run() { - Log.d(TAG,"slowMove run start"); +// Log.d(TAG,"slowMove run start"); int newMove = 0; findItemsToShow(); //根据当前滑动方向,选择选中项来移到中心显示 int selected=getSelected(); if (selected!=-1){ newMove= (int) itemList.get(selected).moveToSelected(); - Log.e(TAG,"getSelected:"+selected+" , newMove="+newMove); +// Log.e(TAG,"getSelected:"+selected+" , newMove="+newMove); }else { synchronized (toShowItems){ if (move > 0) { for (int i = 0; i < toShowItems.length; i++) { - if (toShowItems[i].couldSelected()) { + if (toShowItems[i]!=null&&toShowItems[i].couldSelected()) { newMove = (int) toShowItems[i].moveToSelected(); - Log.e(TAG, "move > 0 couldSelected:" + toShowItems[i].id); +// Log.e(TAG, "move > 0 couldSelected:" + toShowItems[i].id); break; } } } else { for (int i = toShowItems.length - 1; i >= 0; i--) { - if (toShowItems[i].couldSelected()) { + if (toShowItems[i]!=null&&toShowItems[i].couldSelected()) { newMove = (int) toShowItems[i].moveToSelected(); - Log.e(TAG, "move < 0 couldSelected:" + toShowItems[i].id); +// Log.e(TAG, "move < 0 couldSelected:" + toShowItems[i].id); break; } } @@ -746,11 +782,11 @@ public void run() { e.printStackTrace(); } } - Log.d(TAG,"slowMove run end"); +// Log.d(TAG,"slowMove run end"); noEmpty(move); } }); - Log.d(TAG,"slowMove end move="+move); +// Log.d(TAG,"slowMove end move="+move); } /** @@ -772,7 +808,7 @@ private void onSelectListener() { return; { for (ItemObject item : toShowItems) { - if (item.couldSelected()) { + if (item!=null&&item.couldSelected()) { onSelectListener.selecting(item.id, item.getItemText()); } } @@ -808,7 +844,7 @@ public void refreshData(ArrayList data) { public int getSelected() { synchronized (toShowItems) { for (ItemObject item : toShowItems) { - if (item.selected()) + if (item!=null&&item.selected()) return item.id; } return -1; @@ -823,7 +859,7 @@ public int getSelected() { public String getSelectedText() { synchronized (toShowItems) { for (ItemObject item : toShowItems) { - if (item.selected()) + if (item!=null&&item.selected()) return item.getItemText(); } return ""; @@ -918,9 +954,19 @@ public int getItemNumber() { public void setItemNumber(int itemNumber) { this.itemNumber = itemNumber; controlHeight = itemNumber * unitHeight; + toShowItems=new ItemObject[itemNumber+2]; requestLayout(); } + public boolean isCyclic() { + return isCyclic; + } + + public void setCyclic(boolean cyclic) { + isCyclic=cyclic; + _setIsCyclic(cyclic); + } + private class ItemObject { /** * id diff --git a/wheelview/src/main/res/values/attrs.xml b/wheelview/src/main/res/values/attrs.xml index 83434f1..373eb14 100644 --- a/wheelview/src/main/res/values/attrs.xml +++ b/wheelview/src/main/res/values/attrs.xml @@ -9,6 +9,7 @@ +