android 自定义wheelview,自定义wheelview

本文介绍如何在Android中自定义WheelView组件,详细展示了继承ScrollView并实现滚动选择效果的代码,包括设置显示数量、滚轮偏移、监听选中事件等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

根据项目需求修改了下

效果图如下:

63c4aa90122c5f2f415de59e8ad2b452.png

代码如下:

1、写个类继承ScrollViewpublic class WheelView extends ScrollView {

private int displayItemCount,// 每页显示的数量

viewWidth,initialY;

private int selectedIndex = 1,itemHeight = 0,scrollDirection = -1,

newCheck = 50,offset = OFF_SET_DEFAULT;

private int[] selectedAreaBorder;

private Context context;

private LinearLayout views;

private List items;

private Paint paint;

private Runnable scrollerTask;

private OnWheelViewListener onWheelViewListener;

private static final int OFF_SET_DEFAULT = 1;

private static final int SCROLL_DIRECTION_UP = 0;

private static final int SCROLL_DIRECTION_DOWN = 1;

public static class OnWheelViewListener {

public void onSelected(int selectedIndex, String item) {

}

}

public WheelView(Context context) {

super(context);

init(context);

}

public WheelView(Context context, AttributeSet attrs) {

super(context, attrs);

init(context);

}

public WheelView(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

init(context);

}

public void setItems(List list) {

if (null == items) {

items = new ArrayList();

}

items.clear();

items.addAll(list);

// 前面和后面补全

for (int i = 0; i 

items.add(0, "");

items.add("");

}

initData();

}

public void setOffset(int offset) {

this.offset = offset;

}

private void init(Context context) {

this.context = context;

this.setVerticalScrollBarEnabled(false);

views = new LinearLayout(context);

views.setOrientation(LinearLayout.VERTICAL);

this.addView(views);

scrollerTask = new Runnable() {

public void run() {

int newY = getScrollY();

if (initialY - newY == 0) {

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(new Runnable() {

@Override

public void run() {

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

selectedIndex = divided + offset + 1;

onSeletedCallBack();

}

});

} else {

WheelView.this.post(new Runnable() {

@Override

public void run() {

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

selectedIndex = divided + offset;

onSeletedCallBack();

}

});

}

}

} else {

initialY = getScrollY();

WheelView.this.postDelayed(scrollerTask, newCheck);

}

}

};

}

public void startScrollerTask() {

initialY = getScrollY();

this.postDelayed(scrollerTask, newCheck);

}

private void initData() {

displayItemCount = offset * 2 + 1;

for (String item : items) {

views.addView(createView(item));

}

refreshItemView(0);

}

private TextView createView(String item) {

TextView tv = new TextView(context);

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

tv.setSingleLine(true);

tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);

tv.setText(item);

tv.setGravity(Gravity.CENTER);

int padding = dip2px(3);

tv.setPadding(padding, padding, padding, padding);

if (0 == itemHeight) {

itemHeight = getViewMeasuredHeight(tv);

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));

}

return tv;

}

@Override

protected void onScrollChanged(int l, int t, int oldl, int oldt) {

super.onScrollChanged(l, t, oldl, oldt);

refreshItemView(t);

if (t > oldt) {

scrollDirection = SCROLL_DIRECTION_DOWN;

} else {

scrollDirection = SCROLL_DIRECTION_UP;

}

}

private void refreshItemView(int y) {

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 

TextView itemView = (TextView) views.getChildAt(i);

if (null == itemView) {

return;

}

TextPaint tp = itemView.getPaint();

if (position == i) {

itemView.setTextColor(Color.parseColor("#2c2c2c"));

tp.setFakeBoldText(true);

} else {

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

tp.setFakeBoldText(false);

}

}

}

private int[] obtainSelectedAreaBorder() {

if (null == selectedAreaBorder) {

selectedAreaBorder = new int[2];

selectedAreaBorder[0] = itemHeight * offset;

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

}

return selectedAreaBorder;

}

@Override

public void setBackgroundDrawable(Drawable background) {

if (viewWidth == 0) {

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

}

if (null == paint) {

paint = new Paint();

paint.setColor(Color.parseColor("#d8d8d8"));

paint.setStrokeWidth(dip2px(1f));

}

background = new Drawable() {

@Override

public void draw(Canvas canvas) {

canvas.drawLine(0, obtainSelectedAreaBorder()[0], viewWidth , obtainSelectedAreaBorder()[0], paint);

canvas.drawLine(0, obtainSelectedAreaBorder()[1], viewWidth , obtainSelectedAreaBorder()[1], paint);

}

@Override

public void setAlpha(int alpha) {

}

@Override

public void setColorFilter(ColorFilter cf) {

}

@Override

public int getOpacity() {

return 0;

}

};

super.setBackgroundDrawable(background);

}

@Override

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

super.onSizeChanged(w, h, oldw, oldh);

viewWidth = w;

setBackgroundDrawable(null);

}

/**

* 选中回调

*/

private void onSeletedCallBack() {

if (null != onWheelViewListener) {

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

}

}

public void setSeletion(int position) {

final int p = position;

selectedIndex = p + offset;

this.post(new Runnable() {

@Override

public void run() {

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

}

});

}

@Override

public void fling(int velocityY) {

super.fling(velocityY / 3);

}

@Override

public boolean onTouchEvent(MotionEvent ev) {

if (ev.getAction() == MotionEvent.ACTION_UP) {

startScrollerTask();

}

return super.onTouchEvent(ev);

}

public OnWheelViewListener getOnWheelViewListener() {

return onWheelViewListener;

}

public void setOnWheelViewListener(OnWheelViewListener onWheelViewListener) {

this.onWheelViewListener = onWheelViewListener;

}

private int dip2px(float dpValue) {

final float scale = context.getResources().getDisplayMetrics().density;

return (int) (dpValue * scale + 0.5f);

}

private int getViewMeasuredHeight(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);

return view.getMeasuredHeight();

}

}

2、在主界面中调用View outerView = LayoutInflater.from(mActivity).inflate(R.layout.wheel_view, null);

WheelView wv = (WheelView) outerView.findViewById(R.id.wheel_view_wv);

wv.setOffset(2);

wv.setItems(Arrays.asList(mTimes));

wv.setSeletion(3);

wv.setOnWheelViewListener(new WheelView.OnWheelViewListener() {

@Override

public void onSelected(int selectedIndex, String item) {

time = item;

}

});

//以对话框的形式出现。

Builder builder = new MyDialog.Builder(mActivity);

builder.setTitle(getResources().getString(R.string.tv_config_lock_time));

builder.setPositiveButton(getResources().getString(R.string.ok),new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

// TODO Auto-generated method stub

tv_setlocktime.setText(time);

dialog.dismiss();

}

});

builder.create(outerView);

其中MyDialog为自定义对话框。按确认键设置tv_setlocktime的值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值