如何在android中自定义滚轴选择器
如何在android中自定义滚轴选择器?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。
创新互联是一家专业提供白银区企业网站建设,专注与成都网站制作、成都做网站、H5建站、小程序制作等业务。10年已为白银区众多企业、政府机构等服务。创新互联专业网站设计公司优惠进行中。
点击选择餐具弹出底部弹窗
private Dialog dialog; private View inflate; PickValueView pickString; case R.id.rl_cj_num://餐具数量选择 //选择对话框 dialog = new Dialog(this, R.style.ActionSheetDialogStyle); View contentView = LayoutInflater.from(this).inflate(R.layout.dialog_cj_num, null); //获取组件 tv_cancel = contentView.findViewById(R.id.tv_cancel); pickString = contentView.findViewById(R.id.pickString); //获取Dialog的监听 tv_cancel.setOnClickListener(this); pickString.setOnSelectedChangeListener(this); String[] valueStr = new String[]{"无需餐具", "1人", "2人", "3人", "4人", "5人", "6人", "7人", "8人"}; pickString.setValueData(valueStr, valueStr[1]); dialog.setContentView(contentView); ViewGroup.LayoutParams layoutParams = contentView.getLayoutParams(); layoutParams.width = getResources().getDisplayMetrics().widthPixels; contentView.setLayoutParams(layoutParams); dialog.getWindow().setGravity(Gravity.BOTTOM);//弹窗位置 dialog.getWindow().setWindowAnimations(R.style.ActionSheetDialogStyle);//弹窗样式 dialog.show();//显示弹窗 break;
styles.xml中的样式:
弹入弹出动画效果:
anim下新建:弹入资源文件actionsheet_dialog_in和弹出资源文件actionsheet_dialog_out
自定义弹窗布局dialog_cj_num:
自定义视图PickValueView和引用类MyNumberPicker:
package com.shanjing.mymeishi.View; import android.content.Context; import android.graphics.Color; import android.util.AttributeSet; import android.view.Gravity; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.NumberPicker; import android.widget.TextView; /** * 选择日期视图 */ public class PickValueView extends LinearLayout implements NumberPicker.OnValueChangeListener { private Context mContext; /** * 组件 标题、单位、滚轮 */ private TextView mTitleLeft, mTitleMiddle, mTitleRight; private TextView mUnitLeft, mUnitMiddle, mUnitRight; private MyNumberPicker mNpLeft, mNpMiddle, mNpRight; /** * 数据个数 1列 or 2列 or 3列 */ private int mViewCount = 1; /** * 一组数据长度 */ private final int DATA_SIZE = 3; /** * 需要设置的值与默认值 */ private Object[] mLeftValues; private Object[] mMiddleValues; private Object[] mRightValues; private Object mDefaultLeftValue; private Object mDefaultMiddleValue; private Object mDefaultRightValue; /** * 当前正在显示的值 */ private Object[] mShowingLeft = new Object[DATA_SIZE]; private Object[] mShowingMiddle = new Object[DATA_SIZE]; private Object[] mShowingRight = new Object[DATA_SIZE]; /** * 步长 */ private int mLeftStep = 5; private int mMiddleStep = 1; private int mRightStep = 1; /** * 回调接口对象 */ private onSelectedChangeListener mSelectedChangeListener; public PickValueView(Context context) { super(context); this.mContext = context; generateView(); } public PickValueView(Context context, AttributeSet attrs) { super(context, attrs); this.mContext = context; generateView(); } public PickValueView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.mContext = context; generateView(); } /** * 生成视图 */ private void generateView() { //标题 LinearLayout titleLayout = new LinearLayout(mContext); LayoutParams titleParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); titleParams.setMargins(0, 0, 0, dip2px(12)); titleLayout.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); titleLayout.setOrientation(HORIZONTAL); mTitleLeft = new TextView(mContext); mTitleMiddle = new TextView(mContext); mTitleRight = new TextView(mContext); LayoutParams params = new LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1); TextView[] titles = new TextView[]{mTitleLeft, mTitleMiddle, mTitleRight}; for (int i = 0; i < titles.length; i++) { titles[i].setLayoutParams(params); titles[i].setGravity(Gravity.CENTER); titles[i].setTextColor(Color.parseColor("#000000")); titles[i].setTextSize(12); } titleLayout.addView(mTitleLeft); titleLayout.addView(mTitleMiddle); titleLayout.addView(mTitleRight); //内容 LinearLayout contentLayout = new LinearLayout(mContext); contentLayout.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); contentLayout.setOrientation(HORIZONTAL); contentLayout.setGravity(Gravity.CENTER); mNpLeft = new MyNumberPicker(mContext); mNpMiddle = new MyNumberPicker(mContext); mNpRight = new MyNumberPicker(mContext); mUnitLeft = new TextView(mContext); mUnitMiddle = new TextView(mContext); mUnitRight = new TextView(mContext); MyNumberPicker[] nps = new MyNumberPicker[]{mNpLeft, mNpMiddle, mNpRight}; for (int i = 0; i < nps.length; i++) { nps[i].setLayoutParams(params); nps[i].setDescendantFocusability(FOCUS_BLOCK_DESCENDANTS); nps[i].setOnValueChangedListener(this); } contentLayout.addView(mNpLeft); contentLayout.addView(mUnitLeft); contentLayout.addView(mNpMiddle); contentLayout.addView(mUnitMiddle); contentLayout.addView(mNpRight); contentLayout.addView(mUnitRight); this.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); this.setOrientation(VERTICAL); this.addView(titleLayout); this.addView(contentLayout); } /** * 初始化数据和值 */ private void initViewAndPicker() { if (mViewCount == 1) { this.mNpMiddle.setVisibility(GONE); this.mNpRight.setVisibility(GONE); this.mUnitMiddle.setVisibility(GONE); this.mUnitRight.setVisibility(GONE); } else if (mViewCount == 2) { this.mNpRight.setVisibility(GONE); this.mUnitRight.setVisibility(GONE); } //初始化数组值 if (mLeftValues != null && mLeftValues.length != 0) { if (mLeftValues.length < DATA_SIZE) { for (int i = 0; i < mLeftValues.length; i++) { mShowingLeft[i] = mLeftValues[i]; } for (int i = mLeftValues.length; i < DATA_SIZE; i++) { mShowingLeft[i] = -9999; } } else { for (int i = 0; i < DATA_SIZE; i++) { mShowingLeft[i] = mLeftValues[i]; } } mNpLeft.setMinValue(0); mNpLeft.setMaxValue(DATA_SIZE - 1); if (mDefaultLeftValue != null) updateLeftView(mDefaultLeftValue); else updateLeftView(mShowingLeft[0]); } /** * 中间控件 */ if (mViewCount == 2 || mViewCount == 3) { if (mMiddleValues != null && mMiddleValues.length != 0) { if (mMiddleValues.length < DATA_SIZE) { for (int i = 0; i < mMiddleValues.length; i++) { mShowingMiddle[i] = mMiddleValues[i]; } for (int i = mMiddleValues.length; i < DATA_SIZE; i++) { mShowingMiddle[i] = -9999; } } else { for (int i = 0; i < DATA_SIZE; i++) { mShowingMiddle[i] = mMiddleValues[i]; } } mNpMiddle.setMinValue(0); mNpMiddle.setMaxValue(DATA_SIZE - 1); if (mDefaultMiddleValue != null) updateMiddleView(mDefaultMiddleValue); else updateMiddleView(mShowingMiddle[0]); } } /** * 右侧控件 */ if (mViewCount == 3) { if (mRightValues != null && mRightValues.length != 0) { if (mRightValues.length < DATA_SIZE) { for (int i = 0; i < mRightValues.length; i++) { mShowingRight[i] = mRightValues[i]; } for (int i = mRightValues.length; i < DATA_SIZE; i++) { mShowingRight[i] = -9999; } } else { for (int i = 0; i < DATA_SIZE; i++) { mShowingRight[i] = mRightValues[i]; } } mNpRight.setMinValue(0); mNpRight.setMaxValue(DATA_SIZE - 1); if (mDefaultRightValue != null) updateRightView(mDefaultRightValue); else updateRightView(mShowingRight[0]); } } } private void updateLeftView(Object value) { updateValue(value, 0); } private void updateMiddleView(Object value) { updateValue(value, 1); } private void updateRightView(Object value) { updateValue(value, 2); } /** * 更新滚轮视图 * * @param value * @param index */ private void updateValue(Object value, int index) { String showStr[] = new String[DATA_SIZE]; MyNumberPicker picker; Object[] showingValue; Object[] values; int step; if (index == 0) { picker = mNpLeft; showingValue = mShowingLeft; values = mLeftValues; step = mLeftStep; } else if (index == 1) { picker = mNpMiddle; showingValue = mShowingMiddle; values = mMiddleValues; step = mMiddleStep; } else { picker = mNpRight; showingValue = mShowingRight; values = mRightValues; step = mRightStep; } if (values instanceof Integer[]) { for (int i = 0; i < DATA_SIZE; i++) { showingValue[i] = (int) value - step * (DATA_SIZE / 2 - i); int offset = (int) values[values.length - 1] - (int) values[0] + step; if ((int) showingValue[i] < (int) values[0]) { showingValue[i] = (int) showingValue[i] + offset; } if ((int) showingValue[i] > (int) values[values.length - 1]) { showingValue[i] = (int) showingValue[i] - offset; } showStr[i] = "" + showingValue[i]; } } else { int strIndex = 0; for (int i = 0; i < values.length; i++) { if (values[i].equals(value)) { strIndex = i; break; } } for (int i = 0; i < DATA_SIZE; i++) { int temp = strIndex - (DATA_SIZE / 2 - i); if (temp < 0) { temp += values.length; } if (temp >= values.length) { temp -= values.length; } showingValue[i] = values[temp]; showStr[i] = (String) values[temp]; } } picker.setDisplayedValues(showStr); picker.setValue(DATA_SIZE / 2); picker.postInvalidate(); } @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal) { if (picker == mNpLeft) { updateLeftView(mShowingLeft[newVal]); } else if (picker == mNpMiddle) { updateMiddleView(mShowingMiddle[newVal]); } else if (picker == mNpRight) { updateRightView(mShowingRight[newVal]); } if (mSelectedChangeListener != null) { mSelectedChangeListener.onSelected(this, mShowingLeft[DATA_SIZE / 2], mShowingMiddle[DATA_SIZE / 2], mShowingRight[DATA_SIZE / 2]); } } /** * 设置数据--单列数据 * * @param leftValues * @param mDefaultLeftValue */ public void setValueData(Object[] leftValues, Object mDefaultLeftValue) { this.mViewCount = 1; this.mLeftValues = leftValues; this.mDefaultLeftValue = mDefaultLeftValue; initViewAndPicker(); } /** * 设置数据--两列数据 * * @param leftValues * @param mDefaultLeftValue * @param middleValues * @param defaultMiddleValue */ public void setValueData(Object[] leftValues, Object mDefaultLeftValue, Object[] middleValues, Object defaultMiddleValue) { this.mViewCount = 2; this.mLeftValues = leftValues; this.mDefaultLeftValue = mDefaultLeftValue; this.mMiddleValues = middleValues; this.mDefaultMiddleValue = defaultMiddleValue; initViewAndPicker(); } /** * 设置数据--三列数据 * * @param leftValues * @param mDefaultLeftValue * @param middleValues * @param defaultMiddleValue * @param rightValues * @param defaultRightValue */ public void setValueData(Object[] leftValues, Object mDefaultLeftValue, Object[] middleValues, Object defaultMiddleValue, Object[] rightValues, Object defaultRightValue) { this.mViewCount = 3; this.mLeftValues = leftValues; this.mDefaultLeftValue = mDefaultLeftValue; this.mMiddleValues = middleValues; this.mDefaultMiddleValue = defaultMiddleValue; this.mRightValues = rightValues; this.mDefaultRightValue = defaultRightValue; initViewAndPicker(); } /** * 设置左边数据步长 * * @param step */ public void setLeftStep(int step) { this.mLeftStep = step; initViewAndPicker(); } /** * 设置中间数据步长 * * @param step */ public void setMiddleStep(int step) { this.mMiddleStep = step; initViewAndPicker(); } /** * 设置右边数据步长 * * @param step */ public void setRightStep(int step) { this.mRightStep = step; initViewAndPicker(); } /** * 设置标题 * * @param left * @param middle * @param right */ public void setTitle(String left, String middle, String right) { if (left != null) { mTitleLeft.setVisibility(VISIBLE); mTitleLeft.setText(left); } else { mTitleLeft.setVisibility(GONE); } if (middle != null) { mTitleMiddle.setVisibility(VISIBLE); mTitleMiddle.setText(middle); } else { mTitleMiddle.setVisibility(GONE); } if (right != null) { mTitleRight.setVisibility(VISIBLE); mTitleRight.setText(right); } else { mTitleRight.setVisibility(GONE); } this.postInvalidate(); } public void setUnitLeft(String unitLeft) { setUnit(unitLeft, 0); } public void setmUnitMiddle(String unitMiddle) { setUnit(unitMiddle, 1); } public void setUnitRight(String unitRight) { setUnit(unitRight, 2); } private void setUnit(String unit, int index) { TextView tvUnit; if (index == 0) { tvUnit = mUnitLeft; } else if (index == 1) { tvUnit = mUnitMiddle; } else { tvUnit = mUnitRight; } if (unit != null) { tvUnit.setText(unit); } else { tvUnit.setText(" "); } initViewAndPicker(); } /** * 设置回调 * * @param listener */ public void setOnSelectedChangeListener(onSelectedChangeListener listener) { this.mSelectedChangeListener = listener; } /** * dp转px * * @param dp * @return */ private int dip2px(int dp) { float scale = mContext.getResources().getDisplayMetrics().density; return (int) (scale * dp + 0.5f); } /** * 回调接口 */ public interface onSelectedChangeListener { void onSelected(PickValueView view, Object leftValue, Object middleValue, Object rightValue); } }
package com.shanjing.mymeishi.View; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.SparseArray; import android.util.TypedValue; import android.view.View; import android.view.ViewGroup; import android.widget.EditText; import android.widget.NumberPicker; import java.lang.reflect.Field; public class MyNumberPicker extends NumberPicker { private Context mContext; NumberPicker picker; public MyNumberPicker(Context context) { super(context); picker = this; mContext = context; } public MyNumberPicker(Context context, AttributeSet attrs) { super(context, attrs); picker = this; mContext = context; } public MyNumberPicker(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); picker = this; mContext = context; } @Override public void addView(View child) { super.addView(child); updateView(child); } @Override public void addView(View child, int index, ViewGroup.LayoutParams params) { super.addView(child, index, params); updateView(child); } @Override public void addView(View child, ViewGroup.LayoutParams params) { super.addView(child, params); updateView(child); } private void updateView(View view) { if (view instanceof EditText) { ((EditText) view).setTextSize(TypedValue.COMPLEX_UNIT_SP, 20); ((EditText) view).setTextColor(Color.parseColor("#000000"));//进入时滚轴显示颜色 } } private int mRight, mLeft, mBottom; private int mTopSelectionDividerTop; private int mBottomSelectionDividerBottom; private int[] mSelectorIndices; private int mScrollState; private SparseArraymSelectorIndexToStringCache; private EditText mInputText; private Paint mSelectorWheelPaint; private int mSelectorElementHeight; private int mCurrentScrollOffset; private boolean mHasSelectorWheel; private boolean mHideWheelUntilFocused; private Drawable mSelectionDivider; /** * 通过反射获取值 */ private void getMyValue() { mLeft = super.getLeft(); mRight = super.getRight(); mBottom = super.getBottom(); Field[] pickerFields = NumberPicker.class.getDeclaredFields(); for (Field field : pickerFields) { field.setAccessible(true); if (field.getName().equals("mSelectorWheelPaint")) { try { mSelectorWheelPaint = (Paint) field.get(picker); } catch (IllegalAccessException e) { e.printStackTrace(); } break; } } for (Field field : pickerFields) { field.setAccessible(true); if (field.getName().equals("mSelectorElementHeight")) { try { mSelectorElementHeight = (int) field.get(picker); } catch (IllegalAccessException e) { e.printStackTrace(); } break; } } for (Field field : pickerFields) { field.setAccessible(true); if (field.getName().equals("mCurrentScrollOffset")) { try { mCurrentScrollOffset = (int) field.get(picker); } catch (IllegalAccessException e) { e.printStackTrace(); } break; } } for (Field field : pickerFields) { field.setAccessible(true); if (field.getName().equals("mInputText")) { try { mInputText = (EditText) field.get(picker); } catch (IllegalAccessException e) { e.printStackTrace(); } break; } } for (Field field : pickerFields) { field.setAccessible(true); if (field.getName().equals("mSelectorIndexToStringCache")) { try { mSelectorIndexToStringCache = (SparseArray ) field.get(picker); } catch (IllegalAccessException e) { e.printStackTrace(); } break; } } for (Field field : pickerFields) { field.setAccessible(true); if (field.getName().equals("mSelectorIndices")) { try { mSelectorIndices = (int[]) field.get(picker); } catch (IllegalAccessException e) { e.printStackTrace(); } break; } } for (Field field : pickerFields) { field.setAccessible(true); if (field.getName().equals("mHasSelectorWheel")) { try { mHasSelectorWheel = (boolean) field.get(picker); } catch (IllegalAccessException e) { e.printStackTrace(); } break; } } for (Field field : pickerFields) { field.setAccessible(true); if (field.getName().equals("mHideWheelUntilFocused")) { try { mHideWheelUntilFocused = (boolean) field.get(picker); } catch (IllegalAccessException e) { e.printStackTrace(); } break; } } // for (Field field : pickerFields) { // field.setAccessible(true); // if (field.getName().equals("mDecrementVirtualButtonPressed")) { // try { // mDecrementVirtualButtonPressed = (boolean) field.get(picker); // } catch (IllegalAccessException e) { // e.printStackTrace(); // } // break; // } // } // for (Field field : pickerFields) { // field.setAccessible(true); // if (field.getName().equals("mIncrementVirtualButtonPressed")) { // try { // mIncrementVirtualButtonPressed = (boolean) field.get(picker); // } catch (IllegalAccessException e) { // e.printStackTrace(); // } // break; // } // } // for (Field field : pickerFields) { // field.setAccessible(true); // if (field.getName().equals("mVirtualButtonPressedDrawable")) { // try { // mVirtualButtonPressedDrawable = (Drawable) field.get(picker); // } catch (IllegalAccessException e) { // e.printStackTrace(); // } // break; // } // } for (Field field : pickerFields) { field.setAccessible(true); if (field.getName().equals("mScrollState")) { try { mScrollState = (int) field.get(picker); } catch (IllegalAccessException e) { e.printStackTrace(); } break; } } for (Field field : pickerFields) { field.setAccessible(true); if (field.getName().equals("mTopSelectionDividerTop")) { try { mTopSelectionDividerTop = (int) field.get(picker); } catch (IllegalAccessException e) { e.printStackTrace(); } break; } } for (Field field : pickerFields) { field.setAccessible(true); if (field.getName().equals("mBottomSelectionDividerBottom")) { try { mBottomSelectionDividerBottom = (int) field.get(picker); } catch (IllegalAccessException e) { e.printStackTrace(); } break; } } for (Field field : pickerFields) { field.setAccessible(true); if (field.getName().equals("mSelectionDivider")) { try { mSelectionDivider = (Drawable) field.get(picker); } catch (IllegalAccessException e) { e.printStackTrace(); } break; } } } @Override protected void onDraw(Canvas canvas) { // super.onDraw(canvas); getMyValue(); mSelectorWheelPaint.setColor(Color.BLUE); if (!mHasSelectorWheel) { super.onDraw(canvas); return; } final boolean showSelectorWheel = mHideWheelUntilFocused ? hasFocus() : true; float x = (mRight - mLeft) / 2; float y = mCurrentScrollOffset; // if (showSelectorWheel && mVirtualButtonPressedDrawable != null // && mScrollState == OnScrollListener.SCROLL_STATE_IDLE) { // if (mDecrementVirtualButtonPressed) { // mVirtualButtonPressedDrawable.setState(View.PRESSED_STATE_SET); // mVirtualButtonPressedDrawable.setBounds(0, 0, mRight, mTopSelectionDividerTop); // mVirtualButtonPressedDrawable.draw(canvas); // } // if (mIncrementVirtualButtonPressed) { // mVirtualButtonPressedDrawable.setState(PRESSED_STATE_SET); // mVirtualButtonPressedDrawable.setBounds(0, mBottomSelectionDividerBottom, mRight, // mBottom); // mVirtualButtonPressedDrawable.draw(canvas); // } // } int[] selectorIndices = mSelectorIndices; for (int i = 0; i < selectorIndices.length; i++) { int selectorIndex = selectorIndices[i]; String scrollSelectorValue = mSelectorIndexToStringCache.get(selectorIndex); if (i != 1) { mSelectorWheelPaint.setColor(Color.BLACK); mSelectorWheelPaint.setTextSize(sp2px(16)); } else { mSelectorWheelPaint.setColor(Color.parseColor("#000000"));//滑动时当前滚轴上的内容颜色 mSelectorWheelPaint.setTextSize(sp2px(20)); } if ((showSelectorWheel && i != 1) || (i == 1 && mInputText.getVisibility() != VISIBLE)) { Rect mRect = new Rect(); mSelectorWheelPaint.getTextBounds(scrollSelectorValue, 0, scrollSelectorValue.length(), mRect); canvas.drawText(scrollSelectorValue, x, y, mSelectorWheelPaint); } y += mSelectorElementHeight; } // draw the selection dividers if (showSelectorWheel && mSelectionDivider != null) { mSelectionDivider = new ColorDrawable(Color.parseColor("#a0c4c4c4"));//滚轴线的颜色 // draw the top divider int topOfTopDivider = mTopSelectionDividerTop; int bottomOfTopDivider = topOfTopDivider + 2; mSelectionDivider.setBounds(0, topOfTopDivider, mRight, bottomOfTopDivider); mSelectionDivider.draw(canvas); // draw the bottom divider int bottomOfBottomDivider = mBottomSelectionDividerBottom; int topOfBottomDivider = bottomOfBottomDivider - 2; mSelectionDivider.setBounds(0, topOfBottomDivider, mRight, bottomOfBottomDivider); mSelectionDivider.draw(canvas); } } private int sp2px(int sp) { float scale = mContext.getResources().getDisplayMetrics().scaledDensity; return (int) (scale * sp + 0.5f); } }
用法:
先实现PickValueView.onSelectedChangeListener
然后TextView显示:
@Override public void onSelected(PickValueView view, Object leftValue, Object middleValue, Object rightValue) { String selectedStr = (String) leftValue; tv_cj_num.setText(selectedStr); }
看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注创新互联行业资讯频道,感谢您对创新互联的支持。
名称栏目:如何在android中自定义滚轴选择器
链接地址:http://azwzsj.com/article/ihiooi.html