Android Weex 自定义 Component 具体实现(WEEX SDK 0.19.0)

本文详细介绍了如何为Weex注册SeekBar组件,通过Kotlin代码实现并分享了在项目中使用SeekBar的具体方法,包括进度变化监听、不同类型的SeekBar样式定制及与Vue的交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

不知不觉使用weex已经大半年了,但每次需要查相关资料的时候都忍不住的想吐槽相关资料实在是太少了(包括文档也是,能没有就尽量没有)。所以想将自己摸索到的总结给需要的朋友们。下面我将分享我在项目中使用的的seekbar为大家讲解如何去给weex注册一个组件。不多说直接上代码(已kotlin代码为例)


class WeexSeekBar(instance: WXSDKInstance, parent: WXVContainer<*>  , basic: BasicComponentData<AppCompatSeekBar>) : WXComponent<AppCompatSeekBar>(instance, parent,basic), SeekBar.OnSeekBarChangeListener {


    companion object {
        private const val KEY_MAX = "max"
        private const val KEY_MIN = "min"
        private const val KEY_PROGRESS = "progress"

        private const val EVENT_ON_START_SLIDE = "startSlide"
        private const val EVENT_ON_SLIDE = "slide"
        private const val EVENT_ON_STOP_SLIDE = "stopSlide"

        private const val TYPE_BRIGHTNESS = "normal"
        private const val TYPE_COLOR = "horizontal_hux_color"
        private const val TYPE_SHADE = "horizontal_linear_gradient"
    }
    //注册hostview  此方法必须重写
    override fun initComponentHostView(context: Context): AppCompatSeekBar {
        val tempView = AppCompatSeekBar(context).apply {
            val pxValue = dp2px(context, 16f).toInt();
            setPadding(pxValue, 0, pxValue, 0)
            thumb = ContextCompat.getDrawable(context, R.drawable.button_slide)
        }
        tempView.setOnSeekBarChangeListener(this)
        return tempView
    }

    override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
           //key值为vue中的响应标签如key 为slide  在vue中的标签为 @slide="funtionname" 
          //当fireevent 发送数据时weex会转到你标签中的对应的方法
        fireEvent(EVENT_ON_SLIDE, seekBar.getSeekBarInfo())
    }

    override fun onStartTrackingTouch(seekBar: SeekBar) {
        fireEvent(EVENT_ON_START_SLIDE, seekBar.getSeekBarInfo())
    }

    override fun onStopTrackingTouch(seekBar: SeekBar) {
//        Log.e("seekbar",GsonHelp.gson().toJson(seekBar.getSeekBarInfo()))
        fireEvent(EVENT_ON_STOP_SLIDE, seekBar.getSeekBarInfo())
    }

     
    @WXComponentProp(name = "max")
    fun max(maximum:Int){
        hostView?.max = maximum
    }
    //注册vue中的props 属性 name 为vue中使用的标签
    @WXComponentProp(name = "progress")
    fun progress(progress:Int){
        Log.e("wx",progress.toString())
        hostView?.progress = progress
    }

    override fun bindData(component: WXComponent<*>?) {
        super.bindData(component)

    }
  // 此标注标识注册为weex端代码使用  调用方法在下方给出 下面同理
    @JSMethod 
    fun setProgress(progress:Int){
        hostView?.progress = progress
    }

    @JSMethod
    fun setMax(max:Int){
        hostView?.max = max
    }

    @WXComponentProp(name = "type")
    fun setType(type:String){
        when(type){
            TYPE_BRIGHTNESS -> {
//                hostView.progressDrawable=context.resources.getDrawable(R.drawable.seekbar_bg)
            }
            TYPE_COLOR -> {
                hostView.progressDrawable = PaintDrawable().apply {
                    shape = RectShape()
                    setCornerRadius(10f)
                    shaderFactory = object : ShapeDrawable.ShaderFactory(){
                        override fun resize(width: Int, height: Int): Shader
                                = LinearGradient(0f,0f,width.toFloat(),height.toFloat(),
                                ColorPickGradient.PICKCOLORBAR_COLORS,ColorPickGradient.PICKCOLORBAR_POSITIONS,
                                Shader.TileMode.REPEAT)
                    }
                }
            }
            TYPE_SHADE -> {
                hostView.progressDrawable = ContextCompat.getDrawable(context, R.drawable.seek_bar_bg1)
            }
        }
    }

    @JSMethod
    fun setProgressDrawable(hue:Int){
        //设置的颜色
        val hueVal = (hue.toFloat() / 100f * 360f)
        val PICKCOLORBAR_COLORS = intArrayOf(Color.HSVToColor(floatArrayOf(hueVal, 0f, 1f)),
                Color.HSVToColor(floatArrayOf(hueVal, 1f, 1f)))
        val shaderFactory = object : ShapeDrawable.ShaderFactory() {
            override fun resize(width: Int, height: Int): Shader {
                return LinearGradient(0f, 0f, width.toFloat(), height.toFloat(), PICKCOLORBAR_COLORS, floatArrayOf(0f, 1f), Shader.TileMode.REPEAT)
            }
        }
        val paint = PaintDrawable()
        paint.shape = RectShape()
        paint.setCornerRadius(10f)
        paint.shaderFactory = shaderFactory
        hostView?.progressDrawable = paint
    }

    fun SeekBar.getSeekBarInfo():HashMap<String, Any>{
        return HashMap<String, Any>().apply {
            put(KEY_MAX, this@getSeekBarInfo.max)
            put(KEY_PROGRESS, this@getSeekBarInfo.progress)
            put(KEY_MIN, if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
                this@getSeekBarInfo.min
            }else{
                0
            })
        }
    }

    fun <T : Any> HashMap<String,T>.getValue(key:String, defaultValue:T):T
            = this.get(key) ?: defaultValue

    private fun dp2px(context: Context, size:Float):Float{
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, size, context.getResources().getDisplayMetrics())
    }

    class ColorPickGradient {
        companion object {
            //设置的颜色
            val PICKCOLORBAR_COLORS = intArrayOf(0xFFff0000.toInt(), 0xFFffff00.toInt(), 0xFF00ff00.toInt(),
                    0xFF00ffff.toInt(), 0xFF0000ff.toInt(),
                    0xFFff00ff.toInt(), 0xFFff0000.toInt())
            //每个颜色的位置
            val PICKCOLORBAR_POSITIONS = floatArrayOf(0f, 0.16f, 0.33f, 0.51f, 0.67f, 0.85f, 1f)
        }

        private var mColorArr = PICKCOLORBAR_COLORS
        private var mColorPosition = PICKCOLORBAR_POSITIONS

        constructor()
        constructor(colorArr : IntArray){
            this.mColorArr = colorArr
        }

        /**
         * 获取某个百分比位置的颜色
         *
         * @param radio 取值[0,1]
         * @return
         */
        fun getColor(radio:Float):Int{
            var startColor = 0
            var endColor = 0
            if (radio >= 1) {
                return mColorArr[mColorArr.size - 1]
            }
            for(i in 0 until mColorPosition.size){
                if (radio <= mColorPosition[i]) {
                    if (i == 0) {
                        return mColorArr[0]
                    }
                    startColor = mColorArr[i - 1]
                    endColor = mColorArr[i]
                    val areaRadio : Float = getAreaRadio(radio, mColorPosition[i - 1], mColorPosition[i])
                    return getColorFrom(startColor, endColor, areaRadio)
                }
            }
            return -1;
        }


    fun getAreaRadio(radio : Float ,startPosition : Float , endPosition:Float ):Float{
        return (radio - startPosition) / (endPosition - startPosition)
    }

    /**
     * 取两个颜色间的渐变区间 中的某一点的颜色
     *
     * @param startColor
     * @param endColor
     * @param radio
     * @return
     */
    fun getColorFrom( startColor : Int,  endColor : Int,  radio : Float) : Int {
        val redStart = Color.red(startColor);
        val blueStart = Color.blue(startColor);
        val greenStart = Color.green(startColor);
        val redEnd = Color.red(endColor);
        val blueEnd = Color.blue(endColor);
        val greenEnd = Color.green(endColor);

        val red =  (redStart + ((redEnd - redStart) * radio + 0.5)).toInt()
        val greed =  (greenStart + ((greenEnd - greenStart) * radio + 0.5)).toInt()
        val blue =  (blueStart + ((blueEnd - blueStart) * radio + 0.5)).toInt()
        return Color.argb(255, red, greed, blue)
    }

}
}

//在weex sdk0.19.0中取消了WXDomObject对象。如使用0.19以下版本的使用该构造函数

class WeexSeekBar(instance: WXSDKInstance, dom: WXDomObject, parent: WXVContainer<*>) : WXComponent<AppCompatSeekBar>(instance, dom, parent), SeekBar.OnSeekBarChangeListener 

注册WXComponent 

//key值便是vue中使用的标签此处为key为seekbar
WXSDKEngine.registerComponent(  WeexConstance.COMPONENT_SEEK_BAR, WeexSeekBar.class);

vue中使用

其中type值会传至原生种对应type处 @slide 为原生发送数据时调用到vue种的方法其他类似

<seekbar class="content-seekbar" type="normal" rel="seekBarBrightness" ref="seekBarBrightness" @slide="onBrightnessSlide" @stopSlide="onBrightnessSlideStop" @progress="progressBrightness"/>

附带给出一个方法

 onBrightnessSlide(seekBar){

this.progressBrightness = seekBar.progress;

const colorObj = ColorUtil.hsvToRgb(this.progressColor/100,this.progressShade/100,this.progressBrightness/100);

this.blockColorR = colorObj.r;

this.blockColorG = colorObj.g;

this.blockColorB = colorObj.b;

},

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值