package com.streamlet.common.widget;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
/**
*
*/
public class WheelView extends ScrollView {
/**
* 绘制分割线的画笔
*/
private Paint mPaintBorder;
/**
* 在ScrollView中使用Linearlayout存放Item
*/
private LinearLayout mLinearContainer;
/**
* 每个item的高度
*/
private int mItemHeight;
/**
* 每个item的宽度
*/
private int mItemWidth;
private List<String> mItems = new ArrayList<String>();
/**
* 中心点上下各显示多少个,
*/
private int mOffset;
/**
* 当前选中的位置
*/
private int mSelection;
/**
* 显示item的个数
*/
private int mDisplayCount;
private int[] mBorderHeight = new int[2];
public static final int DEFAULT_OFFSET = 2;
public static final long DELAY = 20;
public static final int TEXT_SIZE_NORMAL = 20;
public static final int TEXT_SIZE_SELECTED = 24;
private int mInitY;
private AutoScrollRunnable mAutoRunnable = new AutoScrollRunnable();
public static final int COLOR_NORMAL = Color.parseColor("#FFADADAD");
public static final int COLOR_SELECT = Color.parseColor("#FF929AFF");
private OnWheelPickerListener mPickerListener;
public WheelView(Context context) {
this(context, null);
}
public WheelView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public WheelView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
@SuppressLint("NewApi")
private void initView() {
mPaintBorder = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaintBorder.setDither(true);
mPaintBorder.setStrokeWidth(dpToPx(1));
mPaintBorder.setColor(COLOR_NORMAL);
mOffset = DEFAULT_OFFSET;
mDisplayCount = mOffset * 2 + 1;
this.setVerticalScrollBarEnabled(false);
this.setOverScrollMode(OVER_SCROLL_NEVER);
mLinearContainer = new LinearLayout(getContext());
mLinearContainer.setOrientation(LinearLayout.VERTICAL);
addView(mLinearContainer);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mItemWidth = w;
setBackgroundDrawable(null);
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
refreshSelectedUI(t);
}
@Override
public void setBackgroundDrawable(Drawable background) {
background = new Drawable() {
@Override
public void draw(Canvas canvas) {
int left = (int) (mItemWidth / 6f);
int right = (int) (mItemWidth * 5 / 6f);
//设置横线的长度mItemWidth屏幕长度
canvas.drawLine(0, mBorderHeight[0], mItemWidth, mBorderHeight[0], mPaintBorder);
canvas.drawLine(0, mBorderHeight[1], mItemWidth, mBorderHeight[1], mPaintBorder);
}
@Override
public void setAlpha(int alpha) {
}
@Override
public void setColorFilter(ColorFilter cf) {
}
@Override
public int getOpacity() {
return 0;
}
};
super.setBackgroundDrawable(background);
}
private int dpToPx(int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
getResources().getDisplayMetrics());
}
/**
* 外部传入的item数据,
* 注意:这里需要在头部和尾部额外增加offset个空余位置
*/
public void setItems(List<String> listItem) {
mItems.clear();
mItems.addAll(listItem);
for (int i = 0; i < mOffset; i++) {
mItems.add(0, "");
mItems.add("");
}
addItemView();
refreshSelectedUI(0);
}
/**
* 更新中间选中的文字的颜色和大小
*/
private void refreshSelectedUI(int y) {
int position = y / mItemHeight + mOffset;
int remain = y % mItemHeight;
if (remain > mItemHeight / 2) {
position = position + 1;
}
int size = mLinearContainer.getChildCount();
for (int i = 0; i < size; i++) {
View textView = mLinearContainer.getChildAt(i);
if (textView instanceof TextView) {
if (i == position) {
((TextView) textView).setTextColor(COLOR_SELECT);
((TextView) textView).setTextSize(TypedValue.COMPLEX_UNIT_SP, TEXT_SIZE_SELECTED);
} else {
((TextView) textView).setTextColor(COLOR_NORMAL);
((TextView) textView).setTextSize(TypedValue.COMPLEX_UNIT_SP, TEXT_SIZE_NORMAL);
}
}
}
}
/**
* 设置默认选择的位置
*/
public void setSelection(int selection) {
final int index = selection;
this.mSelection = selection+mOffset;
this.post(new Runnable() {
@Override
public void run() {
smoothScrollTo(0, mItemHeight * index);
}
});
}
/**
* 设置偏移量
*/
public void setOffset(int offset) {
this.mOffset = offset;
this.mDisplayCount = mOffset * 2 + 1;
}
/**
* 添加所有的item到布局中
*/
private void addItemView() {
int size = mItems.size();
for (int i = 0; i < size; i++) {
TextView textView = createView(mItems.get(i));
mLinearContainer.addView(textView);
}
mBorderHeight[0] = mItemHeight * mOffset;
mBorderHeight[1] = mItemHeight * (mOffset + 1);
}
/**
* 创建TextView,并且设置父布局的尺寸
*/
private TextView createView(String title) {
TextView textView = new TextView(getContext());
textView.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
textView.setGravity(Gravity.CENTER);
textView.setSingleLine();
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 21);
textView.setText(title);
textView.setTextColor(COLOR_NORMAL);
int padding = dpToPx(15);
textView.setPadding(padding, padding, padding, padding);
if (mItemHeight == 0) {
mItemHeight = measureItemHeight(textView);
mLinearContainer.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
mItemHeight * mDisplayCount));
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) this.getLayoutParams();
this.setLayoutParams(new LinearLayout.LayoutParams(lp.width,
mItemHeight * mDisplayCount));
}
return textView;
}
/**
* 测量每个item的高度(重点)
*/
private int measureItemHeight(View view) {
int childWidthSpec;
int childHeightSpec;
ViewGroup.LayoutParams params = view.getLayoutParams();
if (params == null) {
params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0, params.width);
int height = params.height;
if (height > 0) {
childHeightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
} else {
childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
view.measure(childWidthSpec, childHeightSpec);
return view.getMeasuredHeight();
}
/**
* 设置滑动的速度,这里速度放慢
*/
@Override
public void fling(int velocityY) {
super.fling(velocityY / 3);
}
/**
* 当触摸结束后,重新计算位置
*/
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_UP:
startScrollAtPosition();
break;
}
return super.onTouchEvent(ev);
}
private void startScrollAtPosition() {
mInitY = getScrollY();
postDelayed(mAutoRunnable, DELAY);
}
private class AutoScrollRunnable implements Runnable {
int tempY;
@Override
public void run() {
tempY = getScrollY();
if (tempY - mInitY == 0) {
int remain = tempY % mItemHeight;
int position = tempY / mItemHeight;
if (remain == 0) {
mSelection = position+mOffset;
onCallBack();
}else{
if(remain>mItemHeight/2){
mSelection = position+mOffset+1;
WheelView.this.smoothScrollTo(0, (position + 1) * mItemHeight);
onCallBack();
}else{
mSelection = position+mOffset;
WheelView.this.smoothScrollTo(0, position * mItemHeight);
onCallBack();
}
}
} else {
mInitY = getScrollY();
postDelayed(this, DELAY);
}
}
}
private void onCallBack() {
if (mPickerListener != null) {
mPickerListener.wheelSelect(mSelection-mOffset, mItems.get(mSelection));
}
}
/**
* 滑动事件的回调
*/
public interface OnWheelPickerListener {
void wheelSelect(int position, String content);
}
public void setOnWheelPickerListener(OnWheelPickerListener listener) {
this.mPickerListener = listener;
}
}