最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Dialog 按照順序彈窗的優(yōu)雅寫法

 更新時間:2021年09月19日 12:24:25   作者:讓開,我要吃人了  
這篇文章主要介紹了Dialog 按照順序彈窗的寫法及示例,給大家介紹了DrawType的使用方式,需要的朋友可以參考下

我為 Compose 寫了一個波浪效果的進(jìn)度加載庫,API 的設(shè)計上符合 Compose 的開發(fā)規(guī)范,使用非常簡便。

1. 使用方式

在 root 的 build.gradle 中引入 jitpack,

allprojects {
	repositories {
		...
		maven { url 'https://jitpack.io' }
	}
}

在 module 的 build.gradle 中引入 ComposeWaveLoading 的最新版本

dependencies {
    implementation 'com.github.vitaviva:ComposeWaveLoading:$latest_version'
}

2. API 設(shè)計思想

Box {
    WaveLoading (
        progress = 0.5f // 0f ~ 1f
    ) {
        Image(
          painter = painterResource(id = R.drawable.logo_tiktok),
          contentDescription = ""
        )
    }
}

傳統(tǒng)的 UI 開發(fā)方式中,設(shè)計這樣一個波浪控件,一般會使用自定義 View 并將 Image 等作為屬性傳入。 而在 Compose 中,我們讓 WaveLoadingImage 以組合的方式使用,這樣的 API 更加靈活,WaveLoding 的內(nèi)部可以是 Image,也可以是 Text 亦或是其他 Composable。波浪動畫不拘泥于某一特定 Composable, 任何 Composable 都可以以波浪動畫的形式展現(xiàn), 通過 Composable 的組合使用,擴(kuò)大了 “能力” 的覆蓋范圍。

3. API 參數(shù)介紹

@Composable
fun WaveLoading(
    modifier: Modifier = Modifier,
    foreDrawType: DrawType = DrawType.DrawImage,
    backDrawType: DrawType = rememberDrawColor(color = Color.LightGray),
    @FloatRange(from = 0.0, to = 1.0) progress: Float = 0f,
    @FloatRange(from = 0.0, to = 1.0) amplitude: Float = defaultAmlitude,
    @FloatRange(from = 0.0, to = 1.0) velocity: Float = defaultVelocity,
    content: @Composable BoxScope.() -> Unit
) { ... }

參數(shù)說明如下:

參數(shù) 說明
progress 加載進(jìn)度
foreDrawType 波浪圖的繪制類型: DrawColor 或者 DrawImage
backDrawType 波浪圖的背景繪制
amplitude 波浪的振幅, 0f ~ 1f 表示振幅在整個繪制區(qū)域的占比
velocity 波浪移動的速度
content 子Composalble

接下來重點(diǎn)介紹一下 DrawType。

DrawType

波浪的進(jìn)度體現(xiàn)在前景(foreDrawType)和后景(backDrawType)的視覺差,我們可以為前景后景分別指定不同的 DrawType 改變波浪的樣式。

sealed interface DrawType {
    object None : DrawType
    object DrawImage : DrawType
    data class DrawColor(val color: Color) : DrawType
}

如上,DrawType 有三種類型:

  • None: 不進(jìn)行繪制
  • DrawColor:使用單一顏色繪制
  • DrawImage:按照原樣繪制

以下面這個 Image 為例, 體會一下不同 DrawType 的組合效果

index backDrawType foreDrawType 說明
1 DrawImage DrawImage 背景灰度,前景原圖
2 DrawColor(Color.LightGray) DrawImage 背景單色,前景原圖
3 DrawColor(Color.LightGray) DrawColor(Color.Cyan) 背景單色,前景單色
4 None DrawColor(Color.Cyan) 無背景,前景單色

注意 backDrawType 設(shè)置為 DrawImage 時,會顯示為灰度圖。

4. 原理淺析

簡單介紹一下實(shí)現(xiàn)原理。為了便于理解,代碼經(jīng)過簡化處理,完整代碼可以在 github 查看

這個庫的關(guān)鍵是可以將 WaveLoading {...} 內(nèi)容取出,加以波浪動畫的形式顯示。所以需要將子 Composalbe 轉(zhuǎn)成 Bitmap 進(jìn)行后續(xù)處理。

4.1 獲取 Bitmap

我在 Compose 中沒找到獲取位圖的辦法,所以用了一個 trick 的方式, 通過 Compose 與 Android 原生視圖良好的互操作性,先將子 Composalbe 顯示在 AndroidView 中,然后通過 native 的方式獲取 Bitmap:

@Composable
fun WaveLoading (...)
{
    Box {
 
        var _bitmap by remember {
            mutableStateOf(Bitmap.createBitmap(1, 1, Bitmap.Config.RGB_565))
        }
        
        AndroidView(
            factory = { context ->
                // Creates custom view
                object : AbstractComposeView(context) {
 
                    @Composable
                    override fun Content() {
                        Box(Modifier.wrapContentSize(){
                            content()
                        }
                    }
 
 
                    override fun dispatchDraw(canvas: Canvas?) {
                        val bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
                        val canvas2 = Canvas(source)
                        super.dispatchDraw(canvas2)
                        _bitmap = bmp
                        
                    }
 
                }
            }
 
        )
 
 
        WaveLoadingInternal(bitmap = _bitmap)
 
    }
}

AndroidView 是一個可以繪制 Composable 的原生控件,我們將 WaveLoading 的子 Composable 放在其 Content 中,然后在 dispatchDraw 中繪制時,將內(nèi)容繪制到我們準(zhǔn)備好的 Bitmap 中。

4.2 繪制波浪線

我們基于 Compose 的 Canvas 繪制波浪線,波浪線通過 Path 承載 定義 WaveAnim 用來進(jìn)行波浪線的繪制

internal data class WaveAnim(
    val duration: Int,
    val offsetX: Float,
    val offsetY: Float,
    val scaleX: Float,
    val scaleY: Float,
) {
 
    private val _path = Path()
 
    //繪制波浪線
    internal fun buildWavePath(
        dp: Float,
        width: Float,
        height: Float,
        amplitude: Float,
        progress: Float
    ): Path {
 
        var wave = (scaleY * amplitude).roundToInt() //計算拉伸之后的波幅
 
        _path.reset()
        _path.moveTo(0f, height)
        _path.lineTo(0f, height * (1 - progress))
 
        // 通過正弦曲線繪制波浪
        if (wave > 0) {
                var x = dp
                while (x < width) {
                    _path.lineTo(
                        x,
                        height * (1 - progress) - wave / 2f * Math.sin(4.0 * Math.PI * x / width)
                            .toFloat()
                    )
                    x += dp
                }
        }
            
        _path.lineTo(width, height * (1 - progress))
        _path.lineTo(width, height)
        _path.close()
        return _path
    }
 
}

如上,波浪線 Path 通過正弦函數(shù)繪制。

4.3 波浪填充

有了 Path ,我們還需要填充內(nèi)容。填充的內(nèi)容前文已經(jīng)介紹過,或者是 DrawColor 或者 DrawImage。 繪制 Path 需要定義 Paint

 val forePaint = remember(foreDrawType, bitmap) {
        Paint().apply {
            shader = BitmapShader(
                when (foreDrawType) {
                    is DrawType.DrawColor -> bitmap.toColor(foreDrawType.color)
                    is DrawType.DrawImage -> bitmap
                    else -> alphaBitmap
                },
                Shader.TileMode.CLAMP,
                Shader.TileMode.CLAMP
            )
        }
    } 

Paint 使用 Shader 著色器繪制 Bitmap, 當(dāng) DrawType 只繪制單色時, 對位圖做單值處理:

/**
 * 位圖單色化
 */
fun Bitmap.toColor(color: androidx.compose.ui.graphics.Color): Bitmap {
    val bmp = Bitmap.createBitmap(
        width, height, Bitmap.Config.ARGB_8888
    )
    val oldPx = IntArray(width * height) //用來存儲原圖每個像素點(diǎn)的顏色信息
    getPixels(oldPx, 0, width, 0, 0, width, height) //獲取原圖中的像素信息
 
    val newPx = oldPx.map {
        color.copy(Color.alpha(it) / 255f).toArgb()
    }.toTypedArray().toIntArray()
    bmp.setPixels(newPx, 0, width, 0, 0, width, height) //將處理后的像素信息賦給新圖
    return bmp
}

4.4 波浪動畫

最后通過 Compose 動畫讓波浪動起來

val transition = rememberInfiniteTransition()
 
    val waves = remember(Unit) {
        listOf(
            WaveAnim(waveDuration, 0f, 0f, scaleX, scaleY),
            WaveAnim((waveDuration * 0.75f).roundToInt(), 0f, 0f, scaleX, scaleY),
            WaveAnim((waveDuration * 0.5f).roundToInt(), 0f, 0f, scaleX, scaleY)
        )
    }
 
    val animates :  List<State<Float>> = waves.map { transition.animateOf(duration = it.duration) }

為了讓波浪更有層次感,我們定義三個 WaveAnim 以 Set 的形式做動畫

最后,配合 WaveAnim 將波浪的 Path 繪制到 Canvas 即可

Canvas{
 
        drawIntoCanvas { canvas ->
 
            //繪制后景
            canvas.drawRect(0f, 0f, size.width, size.height, backPaint)
 
 
            //繪制前景
            waves.forEachIndexed { index, wave ->
 
                canvas.withSave {
 
                    val maxWidth = 2 * scaleX * size.width / velocity.coerceAtLeast(0.1f)
                    val maxHeight = scaleY * size.height
                  
                    canvas.drawPath (
                        wave.buildWavePath(
                            width = maxWidth,
                            height = maxHeight,
                            amplitude = size.height * amplitude,
                            progress = progress
                        ), forePaint
                    )
                }
 
            }
        }
    }

需要源碼可以私信我,當(dāng)天回復(fù)

到此這篇關(guān)于Dialog 按照順序彈窗的文章就介紹到這了,更多相關(guān)Dialog 按照順序彈窗內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • conda創(chuàng)建環(huán)境、安裝包、刪除環(huán)境步驟詳細(xì)記錄

    conda創(chuàng)建環(huán)境、安裝包、刪除環(huán)境步驟詳細(xì)記錄

    對于生信工作者,有一個方便可用的環(huán)境可以極大地方便我們開展分析,conda可以讓我們在非root的情況下較為方便地切換不同的工作環(huán)境,下面這篇文章主要給大家介紹了關(guān)于conda創(chuàng)建環(huán)境、安裝包、刪除環(huán)境步驟的相關(guān)資料,需要的朋友可以參考下
    2022-08-08
  • OpenCV形狀檢測的示例詳解

    OpenCV形狀檢測的示例詳解

    本文主要介紹了OpenCV中的形狀檢測,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • Python處理mysql特殊字符的問題

    Python處理mysql特殊字符的問題

    今天小編就為大家分享一篇Python處理mysql特殊字符的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-03-03
  • 淺談Python]程序的分支結(jié)構(gòu)

    淺談Python]程序的分支結(jié)構(gòu)

    這篇文章主要介紹了淺談Python]程序的分支結(jié)構(gòu),語句塊是 if 條件滿足后執(zhí)行的一個或多個語句序列,語句塊中語句通過與 if 所在行形成縮進(jìn)表達(dá)包含關(guān)系,需要的朋友可以參考下
    2023-04-04
  • Python編程使用NLTK進(jìn)行自然語言處理詳解

    Python編程使用NLTK進(jìn)行自然語言處理詳解

    這篇文章主要介紹了Python編程使用NLTK進(jìn)行自然語言處理詳解,涉及了nltk和開發(fā)環(huán)境的簡單介紹,以及SentencesSegment,SentencesSegment等內(nèi)容,具有一定參考價值,需要的朋友可以了解下。
    2017-11-11
  • pandas如何修改某一列的數(shù)據(jù)

    pandas如何修改某一列的數(shù)據(jù)

    這篇文章主要介紹了pandas如何修改某一列的數(shù)據(jù)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-02-02
  • Python使用MyQR制作專屬動態(tài)彩色二維碼功能

    Python使用MyQR制作專屬動態(tài)彩色二維碼功能

    MyQR是一個能夠生成自定義二維碼的第三方庫,你可以根據(jù)需要生成普通二維碼、帶圖片的藝術(shù)二維碼,也可以生成動態(tài)二維碼。這篇文章主要介紹了Python使用MyQR制作專屬動態(tài)彩色二維碼,需要的朋友可以參考下
    2019-06-06
  • 用smtplib和email封裝python發(fā)送郵件模塊類分享

    用smtplib和email封裝python發(fā)送郵件模塊類分享

    本文針對發(fā)郵件相關(guān)的操作進(jìn)行了封裝,包括發(fā)送文本、HTML、帶附件的郵件,使用Python發(fā)郵件,主要用到smtplib和email兩個模塊,需要的朋友可以參考下
    2014-02-02
  • Python實(shí)戰(zhàn)案例之可增刪改查的員工管理系統(tǒng)

    Python實(shí)戰(zhàn)案例之可增刪改查的員工管理系統(tǒng)

    本實(shí)戰(zhàn)案例主要對MySQL進(jìn)行一些基本操作,通過完成本實(shí)驗(yàn)任務(wù),要求學(xué)生熟練掌握MySQL的增刪改查,并對MySQL的增刪改查基本操作進(jìn)行管理員工的信息,需要的朋友跟著小編往下看吧
    2021-10-10
  • 如何在Python中導(dǎo)入EXCEL數(shù)據(jù)

    如何在Python中導(dǎo)入EXCEL數(shù)據(jù)

    這篇文章主要介紹了使用Python處理EXCEL基礎(chǔ)操作篇1,如何在Python中導(dǎo)入EXCEL數(shù)據(jù),文中提供了解決思路和部分實(shí)現(xiàn)代碼,一起來看看吧
    2023-03-03

最新評論

阳春市| 乐陵市| 阿拉善左旗| 全椒县| 宣威市| 平山县| 雷波县| 尼玛县| 彩票| 红河县| 大兴区| 兴隆县| 高淳县| 九龙城区| 长岭县| 宕昌县| 蒲城县| 浪卡子县| 肃北| 车致| 南丹县| 晋江市| 日照市| 仙居县| 翼城县| 陇川县| 拜城县| 湖州市| 普兰店市| 永寿县| 杭州市| 上杭县| 邢台县| 南康市| 庄浪县| 荆门市| 泽普县| 塘沽区| 伊春市| 合川市| 库车县|