zyyoona7/WheelPicker

华为Meta20滑动停止后无法即刻获取值

devzwy opened this issue · 12 comments

华为Meta20滑动停止后无法即刻获取值;
在滑动停止后需要等待1s左右才能有值。

@devzwy 你好,可以详细描述一下吗?提供一下什么场景,调用的什么方法获取值等信息。

这是一个底部弹出的对话框,就放一个wheelview和一个取消一个确定按钮

@SuppressLint("ValidFragment")
class AmountSelectorPop @SuppressLint("ValidFragment") constructor
(private val onAmountResultListener: OnAmountResultListener) : BaseBottomDialog() {
    override fun getLayoutRes(): Int {
        return R.layout.popu_amount_selecter
    }

    override fun bindView(view: View) {
        view.findViewById<TextView>(R.id.tv_cancle).setOnClickListener { dismiss() }

        val wheel = view.findViewById<WheelView<String>>(R.id.money_wheelview)
        wheel.data = listOf<String>("100元", "200元", "300元", "400元", "500元", "600元", "700元", "800元", "900元", "1000元")
        wheel.setTextSize(18f, true)
//        wheel.isAutoFitTextSize = true
        wheel.isSoundEffect = true
        wheel.setSelectedItemPosition(3, true)
//        wheelDay.setSelectedItemTextColorRes(R.color.order_text_red)
        wheel.setLineSpacing(3f, true)
        view.findViewById<TextView>(R.id.tv_submit).setOnClickListener {
            dismiss()
            onAmountResultListener.onResult(wheel.selectedItemData.split("")[0])
        }
    }
}

interface OnAmountResultListener {
    fun onResult(amount: String)
}

这是调用的地方

  AmountSelectorPop(object : OnAmountResultListener {
                    override fun onResult(amount: String) {
                        tv_money.text = "${amount}"
                        money = amount
                    }

                }).show(supportFragmentManager)

在所有手机上都没有问题,只有在华为mete20手机上,滑动等待停止后点击确定键,还是400元(代码如上,默认选中index=3),比如滑动到1000元,点击确定,还是回传的400元,但是如果滑动到1000元后等待1.5s左右再点击确定键时,就有结果回传。麻烦了。 @zyyoona7

@devzwy 我测试了一下,这个问题应该是 OverScroller 中 startScroll() 方法默认的滚动持续时间导致的,默认的持续时间为 250ms;

当手指抬起的时候,会通过 OverScroller 的 startScroll() 方法修正滚动位置,只有当滚动位置修正成功的时候选中的数据才会变更为已经选中的下标,即使你觉得滑动的位置就是在 item 正中间位置,这时候手指抬起还是会去修正位置的;

我在 Demo 中的 Main2Activity 中添加了解决方法,即在滚动没有停止的时候将按钮状态置为不可点击,可以参照一下。

在滑动结束后(肉眼感觉结束)到拿到结果的延迟有点严重。
目前测试只有一款设备:华为mete20.延迟太严重,大约1s
过了。 @zyyoona7

@devzwy 按照上面那种方式滚动完获取值?你的需求是什么样子的,需要停止滚动的时候立刻拿到选中的值吗?通过对滚动状态监听,然后获取值不可以吗?如果不可以的话,等我有时间找个 mate 20 测试一下~

@zyyoona7 谢谢您的及时回复,我的情况是这样的。
一个价格选择器,上面一个取消按钮,一个确认按钮,我按照你的意思判断了滑动的状态,对确定按钮进行了可点击和不可点击的设置,在滑动结束后点击确定按钮回传选中的值,其他手机都是可以的,但是只有mete20在滑动结束后点击确定按钮时半天没反应,需要等待回传状态以后按钮才能点击。这样子。

view.findViewById<TextView>(R.id.tv_submit).isEnabled = state == WheelView.SCROLL_STATE_IDLE

这是全部代码:

package com.xinlian.cy.mvp.ui.widget.popview

import android.annotation.SuppressLint
import android.view.View
import android.widget.TextView
import com.xinlian.cy.R
import com.xinlian.cy.app.listener.ErrorSubscrib
import com.zyyoona7.wheel.WheelView
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import me.shaohui.bottomdialog.BaseBottomDialog
import java.util.concurrent.TimeUnit

@SuppressLint("ValidFragment")
class AmountSelectorPop @SuppressLint("ValidFragment") constructor
    (private val onAmountResultListener: OnAmountResultListener) : BaseBottomDialog() {
    override fun getLayoutRes(): Int {
        return R.layout.popu_amount_selecter
    }

    override fun bindView(view: View) {
        view.findViewById<TextView>(R.id.tv_cancle).setOnClickListener { dismiss() }

        val wheel = view.findViewById<WheelView<String>>(R.id.money_wheelview)
        wheel.data = listOf<String>("100元", "200元", "300元", "400元", "500元", "600元", "700元", "800元", "900元", "1000元")
        wheel.setTextSize(18f, true)
//        wheel.isAutoFitTextSize = true
        wheel.isSoundEffect = true
        wheel.setSelectedItemPosition(3, true)
        wheel.setLineSpacing(3f, true)


        wheel.onWheelChangedListener = object : WheelView.OnWheelChangedListener {
            /**
             * WheelView 滚动
             *
             * @param scrollOffsetY 滚动偏移
             */
            override fun onWheelScroll(scrollOffsetY: Int) {

            }

            /**
             * WheelView 选中
             *
             * @param position 选中的下标
             */
            override fun onWheelSelected(position: Int) {

            }

            /**
             * WheelView 滚动状态
             *
             * @param state 滚动状态
             * [WheelView.SCROLL_STATE_IDLE]
             * [WheelView.SCROLL_STATE_DRAGGING]
             * [WheelView.SCROLL_STATE_SCROLLING]
             */
            override fun onWheelScrollStateChanged(state: Int) {
                view.findViewById<TextView>(R.id.tv_submit).isEnabled = state == WheelView.SCROLL_STATE_IDLE
            }

            /**
             * WheelView 条目变化
             *
             * @param oldPosition 旧的下标
             * @param newPosition 新下标
             */
            override fun onWheelItemChanged(oldPosition: Int, newPosition: Int) {

            }
        }
        var d = System.currentTimeMillis()
        view.findViewById<TextView>(R.id.tv_submit).setOnClickListener {
            if (System.currentTimeMillis() - d < 200) return@setOnClickListener
            d = System.currentTimeMillis()
            Observable.timer(100, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())
                .subscribe(object : ErrorSubscrib<Long> {
                    override fun onNext() {
                        dismiss()
                        onAmountResultListener.onResult(wheel.selectedItemData.split("")[0])
                    }
                })
        }
    }
}

interface OnAmountResultListener {
    fun onResult(amount: String)
}

好的,我有时间找个 mate 20 测试一下是什么原因~

@zyyoona7 老哥方便留个联系方式么,或者你加下我Q 3648415?

@zyyoona7 请问有没有方法解决这个问题?

今晚我回去解决一下,然后给你答复,最近工作太忙了~ @devzwy

@devzwy 这个问题已经修复了,欢迎更新到最新版体验~

这个问题主要是 OverScroller 的问题,可能华为对 OverScroller 做了别的优化处理?具体不太清楚,最新版中将 OverScroller 替换成了 Scroller 解决了问题。