主頁 > 移動端開發 > Compose | 控制元件篇(一) -- Text、TextField、Button

Compose | 控制元件篇(一) -- Text、TextField、Button

2021-08-21 08:31:42 移動端開發

這一篇,我們一起學習 Jetpack Compose 中的部分控制元件 – Text、TextField、Button,掌握其使用方式和特性,

文中代碼均基于 1.0.1版本

如無特殊說明,下文中的 Compose 均指代 Jetpack compose

小互動

上一篇文章:Compose | 一文理解神奇的Modifier 在郭嬸的號上有讀者評論到不知道Compose從何學起,
無從下手,這里簡單的談一談我的看法:

  • Compose 以及 Jetpack Compose 對于Android從業人員而言確實是一門 全新的技術
  • 目前才興起,還沒有達到一個輝煌的階段

在此背景下,開始學習研究Compose 都可以算的上 先行者,而且這門技識訓做不到諸如:“一年內全面替代老技術”、“不掌握就找不到作業” 這種程度,

那么按部就班的學習它就行了,沒有時間上的緊迫感,而學習一樣東西,有這樣幾個階段:

  • 掌握如何使用
  • 掌握實作細節,逐漸理解其本質
  • 從其本質出發,利用對程式的理解,優化使用方式甚至優化這門技術

顯然,我們現在要做的就是:

  • 先結合官方資料以及原始碼,先掌握如何使用:它解決哪些問題,怎么使用它解決問題
  • 鑒于部分讀者已經有一定的基礎,對類似技術有了一定的理解,在此程序中就可以提前閱讀該技術的實作細節,嘗試理解其本質,或者再掌握了使用方式后再開始,
  • 再之后的道路就很清晰了

下面我們進入今天的正文,

Text

在Android中,有 TextView 這一控制元件,用于展示文本,Compose中對應的是 Text

先看原始碼:

fun Text(
    text: String,
    modifier: Modifier = Modifier,
    color: Color = Color.Unspecified,
    fontSize: TextUnit = TextUnit.Unspecified,
    fontStyle: FontStyle? = null,
    fontWeight: FontWeight? = null,
    fontFamily: FontFamily? = null,
    letterSpacing: TextUnit = TextUnit.Unspecified,
    textDecoration: TextDecoration? = null,
    textAlign: TextAlign? = null,
    lineHeight: TextUnit = TextUnit.Unspecified,
    overflow: TextOverflow = TextOverflow.Clip,
    softWrap: Boolean = true,
    maxLines: Int = Int.MAX_VALUE,
    onTextLayout: (TextLayoutResult) -> Unit = {},
    style: TextStyle = LocalTextStyle.current
)
fun Text(
    text: AnnotatedString,
    modifier: Modifier = Modifier,
    color: Color = Color.Unspecified,
    fontSize: TextUnit = TextUnit.Unspecified,
    fontStyle: FontStyle? = null,
    fontWeight: FontWeight? = null,
    fontFamily: FontFamily? = null,
    letterSpacing: TextUnit = TextUnit.Unspecified,
    textDecoration: TextDecoration? = null,
    textAlign: TextAlign? = null,
    lineHeight: TextUnit = TextUnit.Unspecified,
    overflow: TextOverflow = TextOverflow.Clip,
    softWrap: Boolean = true,
    maxLines: Int = Int.MAX_VALUE,
    inlineContent: Map<String, InlineTextContent> = mapOf(),
    onTextLayout: (TextLayoutResult) -> Unit = {},
    style: TextStyle = LocalTextStyle.current
)

這兩個方法原型的唯一差別就是形參 text 的型別,AnnotatedString 類似于Android中的 SpannableString, 可以標記各類效果,

其實閱讀原始碼后可以發現,Text 基于 BasicText 實作,應用了樣式

val textColor = color.takeOrElse {
    style.color.takeOrElse {
        LocalContentColor.current.copy(alpha = LocalContentAlpha.current)
    }
}
val mergedStyle = style.merge(
    TextStyle(
        color = textColor,
        fontSize = fontSize,
        fontWeight = fontWeight,
        textAlign = textAlign,
        lineHeight = lineHeight,
        fontFamily = fontFamily,
        textDecoration = textDecoration,
        fontStyle = fontStyle,
        letterSpacing = letterSpacing
    )
)
BasicText(
    text,
    modifier,
    mergedStyle,
    onTextLayout,
    overflow,
    softWrap,
    maxLines,
    inlineContent
)

引數含義:(翻譯自API檔案)

  • text - 要顯示的內容
  • modifier - 需要應用的修飾器.
  • color - 文字色. 如果是 Color.Unspecified, 同時 style 沒有配飾顏色, 將會使用 LocalContentColor.
  • fontSize - 字號. See TextStyle.fontSize.
  • fontStyle - 文字樣式,例如斜體,See TextStyle.fontStyle.
  • fontWeight - 字重,例如加粗.
  • fontFamily - 字體系列. See TextStyle.fontFamily.
  • letterSpacing - 字間距. See TextStyle.letterSpacing.
  • textDecoration - 文字裝飾效果,例如下劃線. See TextStyle.textDecoration.
  • textAlign - 文欄位落對齊方式. See TextStyle.textAlign.
  • lineHeight - 行高. See TextStyle.lineHeight.
  • overflow - 溢位時的處理方案,所謂溢位即文本框顯示不下這么多文字.
  • softWrap - 是否應用換行符. 如果不應用,則一行寫完,overflowTextAlign 無效.
  • maxLines - 最大行數,必須大于0.
  • inlineContent - 占位的替代資訊匹配
  • onTextLayout - 繪制文字計算布局時的回呼
  • style - 樣式,例如: color, font, line height 等.

WorkShop 中按照這些引數撰寫了一些樣例代碼,效果如下,因過度圖片壓縮導致有鋸齒感,非Compose問題

text_demo.webp

考慮到閱讀體驗,代碼請移步WorkShop

TextField

Android中有 EditText 控制元件,用于接收 用戶的文本輸入,Compose中為 TextField

TextField 類似的還有 OutlinedTextField,使用上和 TextField 一致,多一個描邊外框效果

方法原型:

fun TextField(
    value: String,
    onValueChange: (String) -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    readOnly: Boolean = false,
    textStyle: TextStyle = LocalTextStyle.current,
    label: @Composable (() -> Unit)? = null,
    placeholder: @Composable (() -> Unit)? = null,
    leadingIcon: @Composable (() -> Unit)? = null,
    trailingIcon: @Composable (() -> Unit)? = null,
    isError: Boolean = false,
    visualTransformation: VisualTransformation = VisualTransformation.None,
    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
    keyboardActions: KeyboardActions = KeyboardActions(),
    singleLine: Boolean = false,
    maxLines: Int = Int.MAX_VALUE,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    shape: Shape =
        MaterialTheme.shapes.small.copy(bottomEnd = ZeroCornerSize, bottomStart = ZeroCornerSize),
    colors: TextFieldColors = TextFieldDefaults.textFieldColors()
)
fun TextField(
    value: TextFieldValue,
    onValueChange: (TextFieldValue) -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    readOnly: Boolean = false,
    textStyle: TextStyle = LocalTextStyle.current,
    label: @Composable (() -> Unit)? = null,
    placeholder: @Composable (() -> Unit)? = null,
    leadingIcon: @Composable (() -> Unit)? = null,
    trailingIcon: @Composable (() -> Unit)? = null,
    isError: Boolean = false,
    visualTransformation: VisualTransformation = VisualTransformation.None,
    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
    keyboardActions: KeyboardActions = KeyboardActions(),
    singleLine: Boolean = false,
    maxLines: Int = Int.MAX_VALUE,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    shape: Shape =
        MaterialTheme.shapes.small.copy(bottomEnd = ZeroCornerSize, bottomStart = ZeroCornerSize),
    colors: TextFieldColors = TextFieldDefaults.textFieldColors()
)

很巧,和Text類似,除了value 和 onValueChange 的型別不一致,其他均一致,

簡單追溯代碼后可以發現:

  • 和Android不一致,它并沒有依賴Text的實作,而Android中 Edittext 繼承自 TextView
  • TextField 同樣是結合 較為通用的設計 組合而成的一個控制元件,并不僅僅只有文字相關部分

本篇注重于學習如何使用,故而略去原始碼部分

引數含義:

value: TextFieldValue
輸入框中要顯示的文本,包含了輸入框編輯狀態的資訊,這個功能很強大,可以用來更新文本,游標等,然后還可以從其他位置直接觀察到這些值的變化,也就是相當于雙向系結的意思;

  • value: 顯示的文本
  • onValueChange: 更新后的回呼
  • modifier:修飾器
  • enabled:是否可用,如果為false,將不可選中,不可輸入,呈現出禁用狀態
  • readOnly:是否只讀,如果是true,則不可編輯,但是可以選中,可以觸發復制
  • textStyle: 文字樣式,前文中Text的諸多引數亦用于構建TextStyle
  • label: 顯示在文本欄位內的可選標簽,未獲得焦點時呈現
  • placeholder: 獲得焦點時的默認呈現 類似Tint的效果
  • leadingIcon: 輸入框前部的圖示;
  • trailingIcon: 輸入框后部的圖示;
  • isError: 輸入內容是否錯誤,如果為true,則label,Icon等會相應的展示錯誤的顯示狀態;
  • visualTransformation: 內容顯示轉變,例如輸入密碼時可以變成特定效果
  • keyboardOptions: 軟體鍵盤選項
  • keyboardActions: ImeAction
  • singleLine: 是否單行輸入
  • maxLines:最大行數,需要≥1,如果將singleLine設定為true,則將忽略此引數,
  • interactionSource: 目前的知識體系暫不深入
  • shape: 輸入框的形狀
  • colors: 各種狀態下的顏色 類似Android的ColorStateList

效果演示

TextField(
    value = "文字",
    onValueChange = {
        
    }
)

如果我們測驗這樣一段代碼,會發現無論輸入什么,顯示內容都不會改變,Compose 需要我們在外部維護狀態

一個有效的輸入框代碼示例:

var text by rememberSaveable { mutableStateOf("文字") }
TextField(
    value = text,
    onValueChange = {
        text = it
    }
)

如果讀者仔細的觀察一下,會發現這里的value 依舊對應 String 型別!這里充分利用了Delegate的特性!!

接下來,我們嘗試一下幾個有趣的屬性,

而下述的一些簡單屬性,相信讀者已經心中有數,就不在WorkShop中演示了:

  • modifier
  • enabled
  • readOnly
  • textStyle
  • visualTransformation
  • singleLine
  • maxLines
  • shape
  • colors

label & placeholder

var text by rememberSaveable { mutableStateOf("") }
TextField(
    value = text,
    onValueChange = { text = it },
    label = { Text("Label") },
    placeholder = { Text("PlaceHolder") }
)

未獲得焦點時,顯示label:這里輸入的是啥,獲取焦點后,label縮小,如果沒有初始值,則顯示PlaceHolder,否則初始文字
PlaceHolder:輸入示例

效果在章節末呈現

leadingIcon&trailingIcon

var text by rememberSaveable { mutableStateOf("") }

TextField(
    value = text,
    onValueChange = { text = it },
    placeholder = { Text("PlaceHolder") },
    leadingIcon = { Icon(Icons.Filled.Favorite, contentDescription = "Favorite") },
    trailingIcon = { Icon(Icons.Filled.Clear, contentDescription = "Clear",modifier = Modifier.clickable {
        text = ""
    }) }
)

如果在Android原生SDK下,做法可以是:

  • 完全自定義View – 完全通過繼承
  • 繼承ViewGroup或者特定ViewGroup,內部通過組合控制元件方式 反射xml布局或者代碼構建 實作邏輯 – 繼承 + 組合
  • 定義類,內部通過組合控制元件方式 反射xml布局或者代碼構建 實作邏輯 – 組合

每種做法都有自身的優勢和劣勢,但代碼量都會很多

這個例子下我們還無法去討論 組合與繼承的優劣對比 ,但代碼量的感性對比非常明顯

isError & keyboardActions & 輸入校驗

var text by rememberSaveable { mutableStateOf("") }
var isError by rememberSaveable { mutableStateOf(false) }

fun validate(text: String) {
    isError = text.count() < 5
}

TextField(
    value = text,
    onValueChange = {
        text = it
        isError = false
    },
    singleLine = true,
    label = { Text(if (isError) "Email*" else "Email") },
    isError = isError,
    keyboardActions = KeyboardActions { validate(text) },
    modifier = Modifier.semantics {
        // Provide localized description of the error
        if (isError) {
            Toast.makeText(this@P26TextFieldSample,"輸入錯誤",Toast.LENGTH_SHORT).show()
        }
    }
)

代碼含義清晰明了

上述例子的效果

text_field_demo.webp

讀者可以clone專案后自行體驗

相信有讀者已經在思考Compose是如何實作 雙向系結 的了,按照我們的學習計劃,這將在后續的文章中展開,

Button

相信看到這里,有讀者已經在思考一個問題了:

Modifier 中有點擊相關的內容,為什么還需要有Button呢?它真的是一個視圖控制元件嗎?還是一個特定的、帶有點擊效果的樣式組合?

其實 Button 在人機互動中,是一個類似 隱喻 的存在,指代點擊可觸發特定行為的互動區,在設計發展中,
逐漸形成了一些約定:

  • 可觸發和不可觸發的狀態要可識別
  • 從其所在環境中可以被輕易地識別出來
  • 點擊或者按壓要有視覺反饋效果

所以樣式上是一個不可忽略的側重點,但是也要客觀的承認一點:中式UI和歐美UI確實不是一個風格,所以多數情況下我們會修改掉默認效果,

看一下方法原型:

fun Button(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    elevation: ButtonElevation? = ButtonDefaults.elevation(),
    shape: Shape = MaterialTheme.shapes.small,
    border: BorderStroke? = null,
    colors: ButtonColors = ButtonDefaults.buttonColors(),
    contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
    content: RowScope.() -> Unit
): @Composable Unit
  • onClick: 點擊事件回呼
  • modifier: 修飾器
  • enabled:是否可點擊觸發
  • interactionSource:
  • elevation: z軸投影效果
  • shape: button和投影的形狀
  • border: 描邊
  • colors: 背景色、內容色、各個狀態配色
  • contentPadding: 容器和內容的間距
  • content: 內容

代碼示例

一個最簡單的文字按鈕:

Button(
    onClick = {
        toast("onClick")
    },
    modifier = Modifier.clickable {
        toast("Modifier.onClick")
    }
) {
    Text(
        text = "Button",
    )
}

顯然,點擊生效的是 onClick 的回呼函式,

后面的效果圖 或者 運行WorkShop后 可發現,這個文字Button已經運用了許多樣式

Button的樣式部分,讀者可自行編碼探索實踐一二,可以很輕易的和Android原生內容對應上,不再展開,

前文的方法原型中,content: RowScope.() -> Unit 顯然可以包含更多的東西,Row 的布局特性會在后續文章展開

例如:

Button(
    onClick = {
        toast("onClick")
    }
) {
    Icon(
        Icons.Filled.Favorite,
        contentDescription = "Favorite"
    )
    Text(
        text = "Button",
    )
}

可以在文字左邊放置一個 Favorite 圖示

結合樣式的衍生物

而Compose中,還有一些內容,代表著Button的操作含義,但有更特殊的樣式含義,例如:

  • OutlinedButton:有邊線的Button, 但非實質的,借用Android原生的內容比喻:有Stroke效果,無Solid效果
  • IconButton:顯示一個Icon的button 但編碼上未強制約束
  • IconToggleButton:兩個狀態圖示的icon,相互切換,例如:收藏、取消收藏,表現含義上有別于 Switch,表現類似無文字的 CheckBox

OutlinedButton

fun OutlinedButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    elevation: ButtonElevation? = null,
    shape: Shape = MaterialTheme.shapes.small,
    border: BorderStroke? = ButtonDefaults.outlinedBorder,
    colors: ButtonColors = ButtonDefaults.outlinedButtonColors(),
    contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
    content: @Composable RowScope.() -> Unit
)

和Button引數含義一致

IconButton

fun IconButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    content: @Composable () -> Unit
)

引數含義參考Button

適用場景如回傳鍵、關閉按鈕等

示例:

IconButton(
    onClick = {
        toast("onClick")
    },
) {
    Icon(
        imageVector = Icons.Filled.Favorite,
        contentDescription = "Favorite"
    )
}

IconToggleButton

fun IconToggleButton(
    checked: Boolean,
    onCheckedChange: (Boolean) -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    content: @Composable () -> Unit
) 
  • checked:默認狀態
  • onCheckedChange:狀態變化后的回呼

適用場景如:收藏、取消收藏等

示例:

val checkedState = remember { mutableStateOf(true) }

IconToggleButton(
    checked = checkedState.value,
    onCheckedChange = {
        checkedState.value = it
    },
) {
    Icon(
        imageVector = Icons.Filled.Favorite,
        contentDescription = "Favorite",
        tint = if (checkedState.value) {
            Color.Red
        } else {
            Color.Gray
        }
    )
}

上述所有內容的效果:
button_demo.webp

結語

在本篇文章中,我們一起學習了Compose的部分基礎內容,這些內容學起來也比較枯燥,但適應了Compose之后,學習這些基礎內容就會越來越快,

讀者可以結合 WorkShop 實踐一波,加深印象!

我們下一篇見,

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/295206.html

標籤:其他

上一篇:Android Audio知識梳理 看完這一篇就夠了!

下一篇:appium入坑必備--APP元素定位+基本工具介紹

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more