调用需要 API 级别 29(当前最低为 21):`android.widget.NumberPicker#setTextColor`

2024-04-01

我想使用 setTextColor 更改选定的文本颜色字段。但是 Android Studio 给了我这个错误。我应该怎么办?最小 SDK 为 21。 这是我的 CustomNumberPicker 类的代码:

import android.annotation.TargetApi
import android.content.Context
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Typeface
import android.graphics.drawable.Drawable
import android.os.Build
import android.os.Build.VERSION
import android.os.Build.VERSION_CODES
import android.util.AttributeSet
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import android.widget.NumberPicker
import android.widget.NumberPicker.OnScrollListener
import androidx.annotation.ColorInt
import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.drawable.DrawableCompat
import androidx.core.widget.TextViewCompat
import ir.partsoftware.cup.R
import timber.log.Timber

class CustomNumberPicker : NumberPicker {

    constructor(context: Context?) : super(context) {
        init()
    }

    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
        init()
    }

    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
        init()
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    constructor(
        context: Context?,
        attrs: AttributeSet?,
        defStyleAttr: Int,
        defStyleRes: Int
    ) : super(context, attrs, defStyleAttr, defStyleRes) {
        init()
    }

    private fun init() {
        setDividerColor(ContextCompat.getColor(context, R.color.color_secondary))
        setNumberPickerTextColor(this, ContextCompat.getColor(context, R.color.color_secondary))
        this.setOnValueChangedListener { picker, oldVal, newVal ->
            setNumberPickerTextColor(this, ContextCompat.getColor(context, R.color.color_secondary))
        }
        this.setOnScrollListener { numberPicker, scrollState ->
            setNumberPickerTextColor(this, ContextCompat.getColor(context, R.color.color_secondary))
        }
    }

    private fun setNumberPickerTextColor(numberPicker: NumberPicker, color: Int) {
        if (VERSION.SDK_INT >= VERSION_CODES.Q) {
            numberPicker.textColor = color
        } else {
            val count = numberPicker.childCount
            for (i in 0 until count) {
                val child = numberPicker.getChildAt(i)
                if (child is EditText) {
                    try {
                        child.setTextColor(color)
                        val fieldSelectorWheelPaint = numberPicker.javaClass.getDeclaredField("mSelectorWheelPaint")
                        val paint = fieldSelectorWheelPaint[numberPicker] as Paint
                        paint.color = color
                        fieldSelectorWheelPaint.isAccessible = true
                        numberPicker.invalidate()
                    } catch (ex: java.lang.Exception) {
                        // Ignore
                    }
                }
            }
        }
    }

    private fun setDividerColor(@ColorInt color: Int) {
        try {
            val fDividerDrawable =
                NumberPicker::class.java.getDeclaredField("mSelectionDivider")
            fDividerDrawable.isAccessible = true
            val d = fDividerDrawable[this] as Drawable
            DrawableCompat.setTint(d, color)
            d.invalidateSelf()
            postInvalidate()
        } catch (e: Exception) {
            Timber.d(e)
        }
    }

    override fun addView(
        child: View,
        index: Int,
        params: ViewGroup.LayoutParams
    ) {
        super.addView(child, index, params)
        updateView(child)
    }

    private fun updateView(view: View) {
        if (view is EditText) {
            try {
                TextViewCompat.setTextAppearance(view, R.style.TextAppearance_PartPay_NumPicker)
                val customFont: Typeface? = ResourcesCompat.getFont(context, R.font.iran_yekan)
                view.typeface = customFont
                //  setNumberPickerTextColor(ContextCompat.getColor(context, R.color.color_secondary))
            } catch (e: Exception) {
                Timber.d(e)
            }
        }
    }
}

尝试下一个代码。当 API 不可访问时将使用反射:

public void setNumberPickerTextColor(final NumberPicker numberPicker, final int color){

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        numberPicker.setTextColor(color);
    }
    else {
        final int count = numberPicker.getChildCount();

        for (int i = 0; i < count; i++) {

            final View child = numberPicker.getChildAt(i);

            if (child instanceof EditText) {
                try {
                    ((EditText)child).setTextColor(color);
                    numberPicker.invalidate();

                    final Field fieldSelectorWheelPaint = numberPicker.getClass().getDeclaredField("mSelectorWheelPaint");
                    boolean     isAccessible            = fieldSelectorWheelPaint.isAccessible();
                    fieldSelectorWheelPaint.setAccessible(true);
                    final Paint paint = (Paint)fieldSelectorWheelPaint.get(numberPicker);

                    if (paint != null){
                        paint.setColor(color);
                        fieldSelectorWheelPaint.setAccessible(isAccessible);
                        numberPicker.invalidate();
                    }

                    final Field fieldSelectionDivider = numberPicker.getClass().getDeclaredField("mSelectionDivider");
                    isAccessible = fieldSelectionDivider.isAccessible();
                    fieldSelectionDivider.setAccessible(true);
                    fieldSelectionDivider.set(numberPicker, null);
                    fieldSelectionDivider.setAccessible(isAccessible);
                    numberPicker.invalidate();
                }
                catch (Exception ex) {
                    // Ignore
                }
            }
        }
    }
}

您可以在第一次获得对该控件的引用时调用此方法,此外,如果滚动后颜色没有持续存在,则挂钩侦听器,例如 next:

numberPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
    @Override
    public void onValueChange(final NumberPicker picker, final int oldVal, final int newVal) {
        setNumberPickerTextColor(numberPicker, Color.RED);
    }
});

或者,您也可以挂钩滚动侦听器,尽管上面的 setOnValueChangedListener 示例更加优化,因为它只会在值更改时执行更新。要改进下一个滚动方法,您可以检查scrollState是否处于空闲状态,因此仅在滚动结束时调用它:

numberPicker.setOnScrollListener(new NumberPicker.OnScrollListener() {
    @Override
    public void onScrollStateChange(final NumberPicker numberPicker, final int scrollState) {
        setNumberPickerTextColor(numberPicker, Color.RED);
    }
});

UPDATE: 下一部分仅针对您更新的问题代码。

问题是您正在扩展 NumberPicker 类,在这种情况下您需要使用获取声明字段 on the 超一流。我的上述答案只能在不扩展 NumberPicker 类时使用。 此外,您还放置了是可访问的在错误的行中,需要稍微靠前才能访问。

接下来是对代码的更正,可以在扩展 NumberPicker 类时完美使用。你可以看到获取声明字段前面是超类, and 是可访问的位于正确的位置:

private fun setNumberPickerTextColor(numberPicker: NumberPicker, color: Int) {
    if (VERSION.SDK_INT >= VERSION_CODES.Q) {
        numberPicker.textColor = color
    } else {
        val count = numberPicker.childCount
        for (i in 0 until count) {
            val child = numberPicker.getChildAt(i)
            if (child is EditText) {
                try {
                    child.setTextColor(color)
                    val fieldSelectorWheelPaint = numberPicker.javaClass.superclass.getDeclaredField("mSelectorWheelPaint")
                    fieldSelectorWheelPaint.isAccessible = true
                    val paint = fieldSelectorWheelPaint[numberPicker] as Paint
                    paint.color = color
                    numberPicker.invalidate()
                } catch (ex: java.lang.Exception) {
                    // Ignore
                }
            }
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

调用需要 API 级别 29(当前最低为 21):`android.widget.NumberPicker#setTextColor` 的相关文章

  • 如何从 SDK 实现每个会话的 Google Places 自动完成功能?

    是否可以从 Android 和 iOS 应用程序的 place sdk 实现基于会话的自动完成 根据 6 月 11 日生效的新 Google 地图框架定价 对自动完成的请求可以分为基于击键 会话的请求 我找不到描述实施步骤的文档 除了这个参
  • Android短音的正确播放方法?

    我正在创建一个应用程序 屏幕上将有多个图像 这些图像将是按钮 点击时会播放短促的声音 我对此进行了研究 只能找到我当前用来播放声音的方法 这似乎根本没有响应 我希望声音能够快速播放并且能够响应多次快速点击 我不确定这在 Android 中是
  • Android Studio:XML 布局中的“包装在容器中”

    编辑 XML 布局文件时 Eclipse 有一项称为 包裹在容器中 的功能 重新格式化 gt Android gt 可让您选择一个或多个视图并在其周围包裹您选择的布局 Android Studio中有类似的东西吗 目前正在实施中 问题 69
  • Recyclerview 动态部分不使用任何第三个库

    我想将标头添加到 recyclerview 我正在尝试使用来实现它 Override public int getItemViewType int position depends on your problem if position 0
  • 将现有 VARCHAR 列与 Room 结合使用

    我正在尝试将现有的数据库与 Android Room 一起使用 但是 我的一个表有一个 VARCHAR 列 Room 似乎只支持 TEXT 不支持 VARCHAR 而且 sqlite 不允许修改列类型 那么 有没有办法使用Room中现有的带
  • Android 深度链接至 Instagram 应用

    Instagram 已经发布了 iOS 深层链接的 url 方案 但尚未为 Android 创建文档 有没有办法深入链接到 Android 上的 Instagram 应用程序 以转到 Instagram 应用程序中的特定位置 例如 Inst
  • Android:后台Activity可以执行代码吗?

    后台的活动是否被视为 正在运行 并且可以执行代码 还是处于挂起状态 他们暂停了 活动生命周期 http developer android com reference android app Activity html ActivityLi
  • Android Studio 与本地网络共享上的项目文件

    这是我的设置 Android Studio 项目文件位于 Ubuntu 14 10 盒子上的共享文件夹中 尝试在 Windows 8 机器上运行 Android Studio 1 0 2 并将 U 驱动器映射到包含项目文件的 Ubuntu
  • 从 BroadcastReceiver 类调用活动方法

    我知道我可以做一个内部接收器类来调用接收器中的任何方法 但我的主要活动太大了 要做的事情也很多 因此 我需要一个扩展广播接收器的类 但它不是内部类 并且可以从我的主要活动中调用一种方法 我不知道是否可能 但我的活动是家庭活动和 single
  • 如何在谷歌地图android上显示多个标记

    我想在谷歌地图android上显示带有多个标记的位置 问题是当我运行我的应用程序时 它只显示一个位置 标记 这是我的代码 public class koordinatTask extends AsyncTask
  • Android 构建发布失败,原因为:java.lang.ArrayIndexOutOfBoundsException:213(pr​​oguard 问题)

    我的项目使用调试构建变体构建得很好 但使用发布变体 Android Studio 会抛出 引起原因 java lang ArrayIndexOutOfBoundsException 213 可能是什么问题 如果我设置minifyEnable
  • okhttp 获取失败响应

    我已经在我的 android 客户端中实现了 okhttp 来进行网络调用 当我收到失败响应时 我会收到失败代码以及与该代码相关的文本作为消息 但我没有收到服务器发送给我的自定义失败响应 在我实施的代码中的失败响应中 我收到的消息只是 错误
  • logcat 中 mSecurityInputMethodService 为 null

    我写了一点android应显示智能手机当前位置 最后已知位置 的应用程序 尽管我复制了示例代码 并尝试了其他几种解决方案 但似乎每次都有相同的错误 我的应用程序由一个按钮组成 按下按钮应该log经度和纬度 但仅对数 mSecurityInp
  • WorkManager 或 AlarmManager 用于日常请求然后通知工作?

    这是用例 用户设置具有特定时间的每日通知 在指定时间 发出网络请求以获取一些数据 然后使用检索到的数据显示通知 我不确定是否应该使用 AlarmManager 还是 WorkManager 来实现这个用例 据我了解 AlarmManager
  • 我应该释放或重置 MediaPlayer 吗?

    我有自己的自定义适配器类 称为 WordAdapter 并且我正在使用媒体播放器 名为pronounce WordAdapter 类中的全局变量 我有不同的活动 其中每个列表项都有线性布局 名为linearLayout 我正在设置onCli
  • 如何在 Android 中从 WorkManager 取消工作?

    我已经保存了 WorkManagerUUID转换成String在领域数据库中 这是代码 Constraints constraints new Constraints Builder setRequiredNetworkType Netwo
  • Android 中的处理程序与异步调用

    目前我正在使用处理程序来调用 Web 服务方法以使其在后台运行 问题是它需要更多的时间来给出响应 在性能方面似乎更昂贵 现在我计划使用异步调用 哪一个是最好的 Android 中的处理程序和异步调用有什么区别 请帮我想出一个最好的解决方案
  • 上网本上可以进行Android开发吗? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我想使用我的上网本进行 Android 开发 但是当我尝试使用 Eclipse 运行 SDK 时 没有加载任何内容 上网本对于 Android 开发来
  • 卡片视图 单击卡片移至新活动

    我是 Android 编程新手 正在研究卡片布局 我想知道如何使其可点击 android clickable true android foreground android attr selectableItemBackground 我的卡
  • 通过电子邮件发送文本文件附件

    我正在尝试附加一个文本文件以便通过电子邮件发送 但每当我打开电子邮件应用程序时 它都会说该文件不存在 请帮助 Intent i new Intent Intent ACTION SEND i setType text plain i put

随机推荐