天天看點

ios 橫向滾輪效果_[紀錄]仿IOS滾輪效果(豎直滑動選擇器)

public class WheelView extendsScrollView {public static final String TAG = WheelView.class.getSimpleName();public static classOnWheelViewListener {public void onSelected(intselectedIndex, String item) {

}

}privateContext context;privateLinearLayout views;publicWheelView(Context context) {super(context);

init(context);

}publicWheelView(Context context, AttributeSet attrs) {super(context, attrs);

init(context);

}public WheelView(Context context, AttributeSet attrs, intdefStyle) {super(context, attrs, defStyle);

init(context);

}//String[] items;

Listitems;private ListgetItems() {returnitems;

}public void setItems(Listlist) {if (null ==items) {

items= new ArrayList();

}

items.clear();

items.addAll(list);//前面和後面補全

for (int i = 0; i < offset; i++) {

items.add(0, "");

items.add("");

}

initData();

}public static final int OFF_SET_DEFAULT = 1;int offset = OFF_SET_DEFAULT; //偏移量(需要在最前面和最後面補全)

public intgetOffset() {returnoffset;

}public void setOffset(intoffset) {this.offset =offset;

}int displayItemCount; //每頁顯示的數量

int selectedIndex = 1;private voidinit(Context context) {this.context =context;

Log.d(TAG,"parent: " + this.getParent());this.setVerticalScrollBarEnabled(false);

views= newLinearLayout(context);

views.setOrientation(LinearLayout.VERTICAL);this.addView(views);

scrollerTask= newRunnable() {public voidrun() {int newY =getScrollY();if (initialY - newY == 0) { //stopped

final int remainder = initialY %itemHeight;final int divided = initialY /itemHeight;if (remainder == 0) {

selectedIndex= divided +offset;

onSeletedCallBack();

}else{if (remainder > itemHeight / 2) {

WheelView.this.post(newRunnable() {

@Overridepublic voidrun() {

WheelView.this.smoothScrollTo(0, initialY - remainder +itemHeight);

selectedIndex= divided + offset + 1;

onSeletedCallBack();

}

});

}else{

WheelView.this.post(newRunnable() {

@Overridepublic voidrun() {

WheelView.this.smoothScrollTo(0, initialY -remainder);

selectedIndex= divided +offset;

onSeletedCallBack();

}

});

}

}

}else{

initialY=getScrollY();

WheelView.this.postDelayed(scrollerTask, newCheck);

}

}

};

}intinitialY;

Runnable scrollerTask;int newCheck = 50;public voidstartScrollerTask() {

initialY=getScrollY();this.postDelayed(scrollerTask, newCheck);

}private voidinitData() {

displayItemCount= offset * 2 + 1;for(String item : items) {

views.addView(createView(item));

}

refreshItemView(0);

}int itemHeight = 0;

privateTextView createView(String item) {

TextView tv= newTextView(context);

tv.setLayoutParams(newLayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));

tv.setSingleLine(true);//設定字型大小為20sp

tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20);//設定文字内容

tv.setText(item);//設定文字居中

tv.setGravity(Gravity.CENTER);//設定内邊距

int padding = dip2px(15);

tv.setPadding(padding, padding, padding, padding);if (0 ==itemHeight) {

itemHeight=getViewMeasuredHeight(tv);

Log.d(TAG,"itemHeight: " +itemHeight);

views.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, itemHeight *displayItemCount));

LinearLayout.LayoutParams lp= (LinearLayout.LayoutParams) this.getLayoutParams();this.setLayoutParams(new LinearLayout.LayoutParams(lp.width, itemHeight *displayItemCount));

}returntv;

}

@Overrideprotected void onScrollChanged(int l, int t, int oldl, intoldt) {super.onScrollChanged(l, t, oldl, oldt);

refreshItemView(t);if (t >oldt) {

Log.d(TAG,"向下滾動");

scrollDirection=SCROLL_DIRECTION_DOWN;

}else{

Log.d(TAG,"向上滾動");

scrollDirection=SCROLL_DIRECTION_UP;

}

}private void refreshItemView(inty) {int position = y / itemHeight +offset;int remainder = y %itemHeight;int divided = y /itemHeight;if (remainder == 0) {

position= divided +offset;

}else{if (remainder > itemHeight / 2) {

position= divided + offset + 1;

}

}int childSize =views.getChildCount();for (int i = 0; i < childSize; i++) {

TextView itemView=(TextView) views.getChildAt(i);if (null ==itemView) {return;

}if (position ==i) {

itemView.setTextColor(Color.parseColor("#0288ce"));

}else{

itemView.setTextColor(Color.parseColor("#bbbbbb"));

}

}

}

int[] selectedAreaBorder;private int[] obtainSelectedAreaBorder() {if (null ==selectedAreaBorder) {

selectedAreaBorder= new int[2];

selectedAreaBorder[0] = itemHeight *offset;

selectedAreaBorder[1] = itemHeight * (offset + 1);

}returnselectedAreaBorder;

}private int scrollDirection = -1;private static final int SCROLL_DIRECTION_UP = 0;private static final int SCROLL_DIRECTION_DOWN = 1;

Paint paint;intviewWidth;

@Overridepublic voidsetBackgroundDrawable(Drawable background) {if (viewWidth == 0) {

viewWidth=((Activity) context).getWindowManager().getDefaultDisplay().getWidth();

Log.d(TAG,"viewWidth: " +viewWidth);

}if (null ==paint) {

paint= newPaint();

paint.setColor(Color.parseColor("#83cde6"));

paint.setStrokeWidth(dip2px(1f));

}

background= newDrawable() {

@Overridepublic voiddraw(Canvas canvas) {

canvas.drawLine(viewWidth* 1 / 6, obtainSelectedAreaBorder()[0], viewWidth * 5 / 6, obtainSelectedAreaBorder()[0], paint);

canvas.drawLine(viewWidth* 1 / 6, obtainSelectedAreaBorder()[1], viewWidth * 5 / 6, obtainSelectedAreaBorder()[1], paint);

}

@Overridepublic void setAlpha(intalpha) {

}

@Overridepublic voidsetColorFilter(ColorFilter cf) {

}

@Overridepublic intgetOpacity() {return 0;

}

};super.setBackgroundDrawable(background);

}

@Overrideprotected void onSizeChanged(int w, int h, int oldw, intoldh) {super.onSizeChanged(w, h, oldw, oldh);

Log.d(TAG,"w: " + w + ", h: " + h + ", oldw: " + oldw + ", oldh: " +oldh);

viewWidth=w;

setBackgroundDrawable(null);

}

private voidonSeletedCallBack() {if (null !=onWheelViewListener) {

onWheelViewListener.onSelected(selectedIndex, items.get(selectedIndex));

}

}public void setSeletion(intposition) {final int p =position;

selectedIndex= p +offset;this.post(newRunnable() {

@Overridepublic voidrun() {

WheelView.this.smoothScrollTo(0, p *itemHeight);

}

});

}publicString getSeletedItem() {returnitems.get(selectedIndex);

}public intgetSeletedIndex() {return selectedIndex -offset;

}

@Overridepublic void fling(intvelocityY) {super.fling(velocityY / 3);

}

@Overridepublic booleanonTouchEvent(MotionEvent ev) {if (ev.getAction() ==MotionEvent.ACTION_UP) {

startScrollerTask();

}return super.onTouchEvent(ev);

}privateOnWheelViewListener onWheelViewListener;publicOnWheelViewListener getOnWheelViewListener() {returnonWheelViewListener;

}public voidsetOnWheelViewListener(OnWheelViewListener onWheelViewListener) {this.onWheelViewListener =onWheelViewListener;

}private int dip2px(floatdpValue) {final float scale =context.getResources().getDisplayMetrics().density;return (int) (dpValue * scale + 0.5f);

}private intgetViewMeasuredHeight(View view) {int width = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);int expandSpec = View.MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, View.MeasureSpec.AT_MOST);

view.measure(width, expandSpec);returnview.getMeasuredHeight();

}

}