3

I am using custom string in NumberPicker. The problem is the text comes in center, while I want it to align to the Left.

I tried extracting the TextView and setting the gravity there, using the following code -

TextView npTextView = (TextView) numberPicker.getChildAt(1);
npTextView.setGravity(Gravity.LEFT);

But it sets the gravity of selected Text only. The text which is in scrolling position, still comes at center.

Is there any way to align the text to left?

PS: I am using API Level 15.

4

2 回答 2

2

自提出问题以来已经过去了八年,因此您可能拥有 +8 年的 Android 经验,并且可能能够自己开发所需的数字选择器 :)

无论如何,我遇到了类似的问题并升级了 Android NumberPicker 以满足我的需求。最初的 NumberPicker 远非完美,我的也是如此,但经过一些调整后它对我有用。

使用示例:

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View = LinearLayout(requireContext()).apply {
    isBaselineAligned = false

    val divider = ColorDrawable(0xFFDBDBDB.toInt()).apply {
        // share drawable, don't mind Callback, invalidation etc
        setBounds(0, 0, 0, dp2Px(context, 1)) // 1dp dividers
    }
    val pad = dp2Px(context, 16)
    val selectorWheelPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        typeface = ResourcesCompat.getFont(context, R.font.roboto_light)
        textSize = sp(22f)
    }
    val scaleI = TimeInterpolator { cos(3.1415926535897932384f / 2f * it) }
    val alphaI = TimeInterpolator { cos(3.1415926535897932384f / 1.5f * it) }

    val cmPicker = FlexibleNumberPicker(context).apply {
        minValue = 0
        maxValue = 1000 // 10 metres is enough, I hope
        value = valueMm / 100
        setup(divider, selectorWheelPaint, scaleI, alphaI)
        setPadding(0, 0, pad, 0)
        val cm = resources.getString(R.string.cm)
        setFormatter { cm.format(it.toFloat()) }
        wrapSelectorWheel = false
        setGravity(Gravity.RIGHT)
    }
    addView(cmPicker, LinearLayout.LayoutParams(0, WRAP_CONTENT, 1f))

    addView(FlexibleNumberPicker(context).apply {
        minValue = 0
        maxValue = 9
        value = valueMm % 100
        setup(divider, selectorWheelPaint, scaleI, alphaI)
        setPadding(pad, 0, 0, 0)
        val mm = resources.getString(R.string.mm)
        setFormatter { mm.format(it.toFloat()) }
        setOnValueChangedListener(cmPicker.fractionListener)
        setGravity(Gravity.LEFT)
    }, LinearLayout.LayoutParams(0, WRAP_CONTENT, 1f))
}

private fun FlexibleNumberPicker.setup(
    divider: ColorDrawable, paint: Paint,
    scaleI: TimeInterpolator, alphaI: TimeInterpolator,
) {
    setSelectionDivider(divider)
    setSelectorWheelPaint(paint)
    setWheelItemCount(5)
    setDividerOffset(.33f)
    setLineHeight(TypedValue.COMPLEX_UNIT_SP, 27f)
    solidColor = Color.WHITE
    setScaleInterpolator(scaleI)
    setAlphaInterpolator(alphaI)
}

val FlexibleNumberPicker.fractionListener: FlexibleNumberPicker.OnValueChangeListener
    get() = FlexibleNumberPicker.OnValueChangeListener { picker, oldVal, newVal ->
        val min = picker.minValue
        val max = picker.maxValue
        when {
            oldVal == min && newVal == max -> changeValueByOne(false)
            oldVal == max && newVal == min -> changeValueByOne(true)
        }
    }

示例渲染

于 2021-11-03T15:54:43.783 回答
-1

您不能确定 NumberPicker 的第二个孩子是正确的 TextView,因为 NumberPicker 在不同 API 中的实现是不同的。试试这个代码。

    for (int i = 0; i < numberPicker.getChildCount(); i++) {
        View child = numberPicker.getChildAt(i);
        if (child instanceof EditText) {
            ((EditText) child).setGravity(Gravity.LEFT);
            break;
        }
    }
于 2013-10-09T13:15:22.167 回答