
不多说了,直接上代码:
CycleWheelView.java:
/** * Copyright (C) 2015 * * CycleWheelView.java * * Description:* * Author: Liao Longhui* * Ver 1.0, 2015-07-15, Liao Longhui, Create file */package com.example.wheelviewdemo;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.os.Handler;import android.util.AttributeSet;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.AbsListView;import android.widget.BaseAdapter;import android.widget.ListView;import android.widget.TextView;import java.util.ArrayList;import java.util.List;/** * 可循环滚动的选择器 * @author Liao Longhui * */public class CycleWheelView extends ListView { public static final String TAG = CycleWheelView.class.getSimpleName(); private static final int COLOR_DIVIDER_DEFALUT = Color.parseColor("#747474"); private static final int HEIGHT_DIVIDER_DEFAULT = 2; private static final int COLOR_SOLID_DEFAULT = Color.parseColor("#3e4043"); private static final int COLOR_SOLID_SELET_DEFAULT = Color.parseColor("#323335"); private static final int WHEEL_SIZE_DEFAULT = 3; private Handler mHandler; private CycleWheelViewAdapter mAdapter; /*** Labels*/ private List<String> mLabels; /*** Color Of Selected Label*/ private int mLabelSelectColor = Color.WHITE; /*** Color Of Unselected Label*/ private int mLabelColor = Color.GRAY; /*** Gradual Alph*/ private float mAlphaGradual = 0.7f; /*** Color Of Divider*/ private int dividerColor = COLOR_DIVIDER_DEFALUT; /*** Height Of Divider*/ private int dividerHeight = HEIGHT_DIVIDER_DEFAULT; /*** Color of Selected Solid*/ private int seletedSolidColor = COLOR_SOLID_SELET_DEFAULT; /*** Color of Unselected Solid*/ private int solidColor = COLOR_SOLID_DEFAULT; /*** Size Of Wheel , it should be odd number like 3 or greater*/ private int mWheelSize = WHEEL_SIZE_DEFAULT; /*** res Id of Wheel Item Layout*/ private int mItemLayoutId; /*** res Id of Label TextView*/ private int mItemLabelTvId; /*** Height of Wheel Item*/ private int mItemHeight; private boolean cylceEnable; private int mCurrentPositon; private WheelItemSelectedListener mItemSelectedListener; public CycleWheelView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle); } public CycleWheelView(Context context, AttributeSet attrs) {super(context, attrs);init(); } public CycleWheelView(Context context) {super(context); } private void init() {mHandler = new Handler();mItemLayoutId = R.layout.item_cyclewheel;mItemLabelTvId = R.id.tv_label_item_wheel;mAdapter = new CycleWheelViewAdapter();setVerticalScrollBarEnabled(false);setScrollingCacheEnabled(false);setCacheColorHint(Color.TRANSPARENT);setFadingEdgeLength(0);setOverScrollMode(OVER_SCROLL_NEVER);setDividerHeight(0);setAdapter(mAdapter);setOnScrollListener(new OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) {if (scrollState == SCROLL_STATE_IDLE) { View itemView = getChildAt(0); if (itemView != null) {float deltaY = itemView.getY();if (deltaY == 0) { return;}if (Math.abs(deltaY) < mItemHeight / 2) { smoothScrollBy(getDistance(deltaY), 50);} else { smoothScrollBy(getDistance(mItemHeight + deltaY), 50);} }} } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {refreshItems(); }}); } private int getDistance(float scrollDistance) {if (Math.abs(scrollDistance) <= 2) { return (int) scrollDistance;} else if (Math.abs(scrollDistance) < 12) { return scrollDistance > 0 ? 2 : -2;} else { return (int) (scrollDistance / 6);} } private void refreshItems() {int offset = mWheelSize / 2;int firstPosition = getFirstVisiblePosition();int position = 0;if (getChildAt(0) == null) { return;}if (Math.abs(getChildAt(0).getY()) <= mItemHeight / 2) { position = firstPosition + offset;} else { position = firstPosition + offset + 1;}if (position == mCurrentPositon) { return;}mCurrentPositon = position;if (mItemSelectedListener != null) { mItemSelectedListener.onItemSelected(getSelection(), getSelectLabel());}resetItems(firstPosition, position, offset); } private void resetItems(int firstPosition, int position, int offset){for (int i = position - offset - 1; i < position + offset + 1; i++) { View itemView = getChildAt(i - firstPosition); if (itemView == null) {continue; } TextView labelTv = (TextView) itemView.findViewById(mItemLabelTvId); if (position == i) {labelTv.setTextColor(mLabelSelectColor);itemView.setAlpha(1f); } else {labelTv.setTextColor(mLabelColor);int delta = Math.abs(i - position);double alpha = Math.pow(mAlphaGradual, delta);itemView.setAlpha((float) alpha); }} }/*** 设置滚轮的刻度列表* * @param labels*/ public void setLabels(List<String> labels) {mLabels = labels;mAdapter.setData(mLabels);mAdapter.notifyDataSetChanged();initView(); } /*** 设置滚轮滚动监听* * @param mItemSelectedListener*/ public void setOnWheelItemSelectedListener(WheelItemSelectedListener mItemSelectedListener) {this.mItemSelectedListener = mItemSelectedListener; } /*** 获取滚轮的刻度列表* * @return*/ public List<String> getLabels() {return mLabels; } /*** 设置滚轮是否为循环滚动* * @param enable true-循环 false-单程*/ public void setCycleEnable(boolean enable) {if (cylceEnable != enable) { cylceEnable = enable; mAdapter.notifyDataSetChanged(); setSelection(getSelection());} } /** 滚动到指定位置*/ @Override public void setSelection(final int position) {mHandler.post(new Runnable() { @Override public void run() {CycleWheelView.super.setSelection(getPosition(position)); }}); } private int getPosition(int positon) {if (mLabels == null || mLabels.size() == 0) { return 0;}if (cylceEnable) { int d = Integer.MAX_VALUE / 2 / mLabels.size(); return positon + d * mLabels.size();}return positon; } /*** 获取当前滚轮位置* * @return*/ public int getSelection() {if (mCurrentPositon == 0) { mCurrentPositon = mWheelSize / 2;}return (mCurrentPositon - mWheelSize / 2) % mLabels.size(); } /*** 获取当前滚轮位置的刻度* * @return*/ public String getSelectLabel() {int position = getSelection();position = position < 0 ? 0 : position;try { return mLabels.get(position);} catch (Exception e) { return "";} } /*** 如果需要自定义滚轮每个Item,调用此方法设置自定义Item布局,自定义布局中需要一个TextView来显示滚轮刻度* * @param itemResId 布局文件Id* @param labelTvId 刻度TextView的资源Id*/ public void setWheelItemLayout(int itemResId, int labelTvId) {mItemLayoutId = itemResId;mItemLabelTvId = labelTvId;mAdapter = new CycleWheelViewAdapter();mAdapter.setData(mLabels);setAdapter(mAdapter);initView(); } /*** 设置未选中刻度文字颜色* * @param labelColor*/ public void setLabelColor(int labelColor) {this.mLabelColor = labelColor;resetItems(getFirstVisiblePosition(), mCurrentPositon, mWheelSize/2); } /*** 设置选中刻度文字颜色* * @param labelSelectColor*/ public void setLabelSelectColor(int labelSelectColor) {this.mLabelSelectColor = labelSelectColor;resetItems(getFirstVisiblePosition(), mCurrentPositon, mWheelSize/2); } /*** 设置滚轮刻度透明渐变值* * @param alphaGradual*/ public void setAlphaGradual(float alphaGradual) {this.mAlphaGradual = alphaGradual;resetItems(getFirstVisiblePosition(), mCurrentPositon, mWheelSize/2); } /*** 设置滚轮可显示的刻度数量,必须为奇数,且大于等于3* * @param wheelSize* @throws CycleWheelViewException 滚轮数量错误*/ public void setWheelSize(int wheelSize) throws CycleWheelViewException {if (wheelSize < 3 || wheelSize % 2 != 1) { throw new CycleWheelViewException("Wheel Size Error , Must Be 3,5,7,9...");} else { mWheelSize = wheelSize; initView();} }/*** 设置块的颜色* @param unselectedSolidColor 未选中的块的颜色* @param selectedSolidColor 选中的块的颜色*/ public void setSolid(int unselectedSolidColor, int selectedSolidColor){this.solidColor = unselectedSolidColor;this.seletedSolidColor = selectedSolidColor;initView(); }/*** 设置分割线样式* @param dividerColor 分割线颜色* @param dividerHeight 分割线高度(px)*/ public void setDivider(int dividerColor, int dividerHeight){this.dividerColor = dividerColor;this.dividerHeight = dividerHeight; } @SuppressWarnings("deprecation") private void initView() {mItemHeight = measureHeight();ViewGroup.LayoutParams lp = getLayoutParams();lp.height = mItemHeight * mWheelSize;mAdapter.setData(mLabels);mAdapter.notifyDataSetChanged();Drawable backgroud = new Drawable() { @Override public void draw(Canvas canvas) {int viewWidth = getWidth();Paint dividerPaint = new Paint();dividerPaint.setColor(dividerColor);dividerPaint.setStrokeWidth(dividerHeight);Paint seletedSolidPaint = new Paint();seletedSolidPaint.setColor(seletedSolidColor);Paint solidPaint = new Paint();solidPaint.setColor(solidColor);canvas.drawRect(0, 0, viewWidth, mItemHeight * (mWheelSize / 2), solidPaint);canvas.drawRect(0, mItemHeight * (mWheelSize / 2 + 1), viewWidth, mItemHeight* (mWheelSize), solidPaint);canvas.drawRect(0, mItemHeight * (mWheelSize / 2), viewWidth, mItemHeight* (mWheelSize / 2 + 1), seletedSolidPaint);canvas.drawLine(0, mItemHeight * (mWheelSize / 2), viewWidth, mItemHeight* (mWheelSize / 2), dividerPaint);canvas.drawLine(0, mItemHeight * (mWheelSize / 2 + 1), viewWidth, mItemHeight* (mWheelSize / 2 + 1), dividerPaint); } @Override public void setAlpha(int alpha) { } @Override public void setColorFilter(ColorFilter cf) { } @Override public int getOpacity() {return 0; }};setBackgroundDrawable(backgroud); } private int measureHeight() {View itemView = LayoutInflater.from(getContext()).inflate(mItemLayoutId, null);itemView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT));int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);itemView.measure(w, h);int height = itemView.getMeasuredHeight();// int width = view.getMeasuredWidth();return height; } public interface WheelItemSelectedListener {public void onItemSelected(int position, String label); } public class CycleWheelViewException extends Exception {private static final long serialVersionUID = 1L;public CycleWheelViewException(String detailMessage) { super(detailMessage);} } public class CycleWheelViewAdapter extends BaseAdapter {private List<String> mData = new ArrayList<String>();public void setData(List<String> mWheelLabels) { mData.clear(); mData.addAll(mWheelLabels);}@Overridepublic int getCount() { if (cylceEnable) {return Integer.MAX_VALUE; } return mData.size() + mWheelSize - 1;}@Overridepublic Object getItem(int position) { return "";}@Overridepublic long getItemId(int position) { return position;}@Overridepublic boolean isEnabled(int position) { return false;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) {convertView = LayoutInflater.from(getContext()).inflate(mItemLayoutId, null); } TextView textView = (TextView) convertView.findViewById(mItemLabelTvId); if (position < mWheelSize / 2 || (!cylceEnable && position >= mData.size() + mWheelSize / 2)) {textView.setText("");convertView.setVisibility(View.INVISIBLE); } else {textView.setText(mData.get((position - mWheelSize / 2) % mData.size()));convertView.setVisibility(View.VISIBLE); } return convertView;} }} MainActivity.java: public class MainActivity extends Activity { private CycleWheelView cycleWheelView0,cycleWheelView1, cycleWheelView2; @Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);cycleWheelView0 = (CycleWheelView) findViewById(R.id.cycleWheelView);List<String> labels = new ArrayList<>();for (int i = 0; i < 12; i++) { labels.add("" + i);}cycleWheelView0.setLabels(labels);cycleWheelView0.setAlphaGradual(0.5f);cycleWheelView0.setOnWheelItemSelectedListener(new WheelItemSelectedListener() { @Override public void onItemSelected(int position, String label) {Log.d("test", label); }});cycleWheelView1 = (CycleWheelView) findViewById(R.id.cycleWheelView1);List<String> labels1 = new ArrayList<>();for (int i = 0; i < 24; i++) { labels1.add("" + i);}cycleWheelView1.setLabels(labels1);try { cycleWheelView1.setWheelSize(5);} catch (CycleWheelViewException e) { e.printStackTrace();}cycleWheelView1.setSelection(2);cycleWheelView1.setWheelItemLayout(R.layout.item_cyclewheel_custom, R.id.tv_label_item_wheel_custom);cycleWheelView1.setOnWheelItemSelectedListener(new WheelItemSelectedListener() { @Override public void onItemSelected(int position, String label) {Log.d("test", label); }});cycleWheelView2 = (CycleWheelView) findViewById(R.id.cycleWheelView2);List<String> labels2 = new ArrayList<>();for (int i = 0; i < 60; i++) { labels2.add("" + i);}cycleWheelView2.setLabels(labels2);try { cycleWheelView2.setWheelSize(7);} catch (CycleWheelViewException e) { e.printStackTrace();}cycleWheelView2.setCycleEnable(true);cycleWheelView2.setSelection(30);cycleWheelView2.setAlphaGradual(0.6f);cycleWheelView2.setDivider(Color.parseColor("#abcdef"), 2);cycleWheelView2.setSolid(Color.WHITE,Color.WHITE);cycleWheelView2.setLabelColor(Color.BLUE);cycleWheelView2.setLabelSelectColor(Color.RED);cycleWheelView2.setOnWheelItemSelectedListener(new WheelItemSelectedListener() { @Override public void onItemSelected(int position, String label) {Log.d("test", label); }}); }}Item_cyclewheel.xml: <?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="16dp" android:background="@android:color/transparent" > <TextViewandroid:id="@+id/tv_label_item_wheel"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="20sp"android:singleLine="true"android:layout_centerHorizontal="true"android:layout_centerVertical="true" /></RelativeLayout>Item_cyclewheel_custom.xml:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="16dp" android:background="@android:color/transparent" > <TextViewandroid:id="@+id/tv_label_item_wheel_custom"android:layout_width="wrap_content"android:layout_height="wrap_content"android:singleLine="true"android:layout_alignParentLeft="true"android:layout_centerVertical="true" /> <ImageViewandroid:layout_width="25dp"android:layout_height="25dp"android:layout_centerVertical="true"android:layout_alignParentRight="true"android:src="@drawable/ic_launcher" /></RelativeLayout>activity_main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <com.example.wheelviewdemo.CycleWheelViewandroid:id="@+id/cycleWheelView"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1" > </com.example.wheelviewdemo.CycleWheelView><com.example.wheelviewdemo.CycleWheelViewandroid:id="@+id/cycleWheelView1"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1" > </com.example.wheelviewdemo.CycleWheelView> <com.example.wheelviewdemo.CycleWheelViewandroid:id="@+id/cycleWheelView2"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1" > </com.example.wheelviewdemo.CycleWheelView> </LinearLayout>以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。