Kotlin 的大小事 - t104360088/AndroidNote GitHub Wiki

作用區域函數

參考 : https://juejin.im/post/5b0048ed518825428a2619ed

坑 : 使用Array.let 的時候要注意,null及empty的情況,不會進入作用區域 所以進入的唯一情況為有值的Array

字串處理與正規表達式

在維護學校專案的時候,遇到這個問題,所以記錄下來。 專案中有貼文功能,需要加入#字號標記,讓使用者可以標記這個貼文的類型 但是這個該怎麼做呢? 就是使用正規表達式來完成,運用它我們可以判斷字串是否符合格式 判斷出來後,我們要加入點擊事件,讓#的標記可以點擊,並找出所有相關的文章 而這個就需要使用到Spannable,其中的子類別SpannableString或SpannableStringBuilder 這裡我們使用SpannableStringBuilder來做,因為它可以使用append加入字串,不像SpannableString會把文字訂死

var content = getItem(position).content  //取得item的content字串
val sb = StringBuilder(content)  //StringBuilder方便對字串做修改
val ssb = SpannableStringBuilder("")
val regex = Regex("""(#+\S*\s)""")  //正則表達式,遇到#字號後無論多少字串,最後一定要是\s(空白或換行)

content = content.replace('#', '#')  //將全形全部換成半形
Linkify.addLinks(holder.tv_content, Linkify.EMAIL_ADDRESSES or Linkify.WEB_URLS)  //將textView加入超連結

//content字串符合規則的數量大於0,即文章中有使用#標記
if (regex.findAll(content).count()>0) {
    var counter = 0  //計算處理次數,用於判斷文字更正後的位置
    var prefix = 0  //儲存下一次的開頭從哪開始

    //把#標記全部取出,可獲得符合的字串及其範圍
    regex.findAll(content).forEach {
        
        //需要在#標記的最後一個字前插入空白,預防整段都可被點擊
        content = sb.insert(it.range.endInclusive+counter, " ").toString()
        //把從開頭到#標記末端的所有文字加入SpannableStringBuilder,這樣才可以對每個#標記設置點擊事件
        ssb.append(content.substring(prefix, it.range.endInclusive+counter+1))
        //點擊事件設定
        ssb.setSpan(object : ClickableSpan(){
            override fun onClick(widget: View) {
                val b = Bundle()
                b.putString("TagType", it.value.dropLast(1))
                Method.switchTo(context as AppCompatActivity, CueListFragment(), b, true)
            }
        }, it.range.start+counter, it.range.endInclusive+counter, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)

        //設定下次的開頭位置、處理過的次數,因為我們有增加文字,所以範圍的位置需要更新
        prefix = it.range.endInclusive+counter+1
        counter =+ 1
    }
    ssb.append(sb.substring(prefix, sb.length))  //若#標記後還有文字,把他們全部加入
} else
    ssb.append(sb)  //文章中無#標記,則把StringBuilder全部丟給SpannableStringBuilder

holder.tv_content.text = ssb  //textView設置
holder.tv_content.movementMethod = LinkMovementMethod.getInstance()  //最後需加入此段,才有點擊事件
            

TextView 跑馬燈

在xml設置

android:singleLine="true"  //必須設定為單行
android:ellipsize="marquee"  //若有超出textView的文字則變跑馬燈
android:marqueeRepeatLimit="-1"  //跑馬燈循環次數,-1為無限次

最後要讓這個textView獲取焦點(任何獲取方式都可以,但需確定有獲取) 直接使用textView.isSelected = true 強制它被選中即可

LinearLayout動態生成View的問題

當要使用linearlayout動態生成item時,會遇到item無法均分的現象 只要是因為在addView()時會把之前設定的weight取消 解決方式就是在addView的同時,加入位置設定

//child為要加入的item元件,第二參數為此元件的位置設定(寬、高、權重)
addView(child, LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT, 1));

參考:http://nobodycare.me/2015/01/09/android-linear-layout-weight-setting-when-adding-child-dynamically/

屏蔽 ListView 點擊效果

有時候我們希望清單是沒有點擊效果的,那我們可以怎麼做呢?

  • 在xml中,將清單點擊效果變成透明 android:listSelector="@android:color/transparent"
  • 重寫Adapter將item變成不可點擊(最直接且有效)
override fun areAllItemsEnabled() { return false }
override fun isEnabled(position: Int) { return false }

參考: https://blog.csdn.net/pvpheroszw/article/details/51385789 https://blog.csdn.net/maxwell_nc/article/details/49444887