kotlinのenumをIntに

enumをintentで使いたくて、Intに相互変換できないか調べた。結果は、以下のようにしたらできた(これが正解かはわからない)。

    enum class ListHeight {
        SMALL,
        MID,
        LARGE
    }

    var listHeight1 = ListHeight.LARGE
    var i = listHeight1.ordinal                 //i==2
    var listHeight2 = ListHeight.values()[i]     //listHeight2 == ListHeight.LARGE

ordinalで順番(?)で、values()でenum値の配列が取れる。

跳んで埼玉

跳んで埼玉を観てきました。魔夜峰央先生が最初に出てきました。自分のイメージではタモリなんだけど、いまは違う感じでした。

キャラクターが魔夜峰央の漫画は独特な感じなんだけど、それを再現しつつ全然違和感がないのがすごいと思いました。楽しかったです

ListViewの中に編集可能なTextView(EditText)

編集可能なTextViewがListViewの中にある場合が今回の問題です。

class GroupListAdapter(context: Context, var groups: MutableList<MemoGroup>) :
    ArrayAdapter<MemoGroup> (context, 0, groups) {
data class ViewHolder(val textView: TextView)
    private val layoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater

    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
        var view = convertView
        var holder: ViewHolder
        if (view == null) {
            view = layoutInflater.inflate(R.layout.view_group_setting, null)
            holder = ViewHolder(
                view.findViewById(R.id.textView)
            )
            view.tag = holder
            holder.textView.addTextChangedListener(object: TextWatcher {
                override fun afterTextChanged(p0: Editable?) {
                    if(p0 != null) {
                        groups[position].title = p0.toString()
                    }
                }

                override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}

                override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}

            })
        } else {
            holder = view.tag as ViewHolder
        }
        holder.textView.text = groups[position].title
        return view!!
    }
}

本当はもうちょっとごちゃごちゃしているのですが、多少見やすいように修正しました。

さて、これだと何度もafterTextChangedが呼ばれて、しかもpositionもp0.toString()も思った値が取れない。

ここを参考にして解決しました。

class GroupListAdapter(context: Context, var groups: MutableList<MemoGroup>) :
    ArrayAdapter<MemoGroup> (context, 0, groups) {
    inner class MutableWatcher : TextWatcher {
        var position: Int = 0
        var active: Boolean = false
        override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
        override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
        override fun afterTextChanged(s: Editable) {
            if (active) {
                groups[position].title =  s.toString()
            }
        }
    }
    data class ViewHolder(val textView: TextView, val watcher:MutableWatcher)
    private val layoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
        var view = convertView
        var holder: ViewHolder
        if (view == null) {
            view = layoutInflater.inflate(R.layout.view_group_setting, null)
            holder = ViewHolder(
                view.findViewById(R.id.textView),
                MutableWatcher()
            )
            view.tag = holder
            holder.textView.addTextChangedListener(holder.watcher)
        } else {
            holder = view.tag as ViewHolder
        }
        holder.watcher.active = false
        holder.textView.text = groups[position].title
        holder.watcher.position = position
        holder.watcher.active = true
        return view!!
    }
}

textView.textに代入してもafterTextChangedが呼ばれるので、その時は無視するようにして、TextWatcher をそれぞれに持たせる感じなのか?まだ勉強が足りません。

onActivityResultでintentから返るデータがnull

恥ずかしいミスだけど、書いておく。

呼び出したActivityからputExtraでデータをもらって、

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == 100 && intent !=null && resultCode == RESULT_OK) {
var a = intent.getParcelableArrayListExtra<MyGroup>("groups")
}
}

これでaはnullが返る。単純すぎるんだけど、

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == 100 && data !=null && resultCode == RESULT_OK) {
var a = data.getParcelableArrayListExtra<MyGroup>("groups")
}
}

intentじゃなくてdataでしたという落ち。オーバーライドしたonActivityResultは自動生成したもので、intent部分はコピペ。単純だけど、なかなかわからなかった。

toolbar表示でエラー

アプリの設定画面を作ろうと思った。機能は単純なので、適当に空のActivityを作ったら、ツールバーがMainActivityのまま。それで独自のツールバーを表示しようと思った。慣れてきたので、適当にコピペでレイアウトコピー、コードもコピーで簡単と思いきや、例外で落ちる。

調べたら、AndroidManifest.xmlの新規に作ったActivity部分に、

android:theme="@style/AppTheme.NoActionBar"

を付けなければいけなかった。いままでは、空のActivityじゃなくて、なにがしかの中身のあるテンプレートから作ってたから自動で付いていた。

あわせてタイトルも設定した。勉強にはなったが、最初から中身のあるテンプレート使えば楽だったかも。

ListViewのヘッダー文字

例えば、次のようなlayoutを作る。

group_list_header.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">

<TextView
android:text="group name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView2"
android:layout_weight="2"/>
<TextView
android:text="show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView3"
android:layout_weight="1"
android:gravity="right"/>
</LinearLayout>

次に、ActivityのonCreateで次のように設定

val headerView = layoutInflater.inflate(R.layout.group_list_header, groupListView, false) as ViewGroup
groupListView.addHeaderView(headerView)

これでできるけど、groupListViewの中にswitchがあったため、ヘッダーの文字の位置がうまく合わなくていまいちだった。 groupListView の中身が文字だけならまぁまぁうまくいきそう。
ということで、今回は使わなかった。せっかく調べたので、記録として残す。

Fragmentの中のListViewで文字色が白くなった

Activityの中身をFragmentに移したら、ListViewの文字色が白くなって見えなくなった。

val adapter = SummaryListAdapter(activity!!.applicationContext)
summaryListView.adapter = adapter


val adapter = SummaryListAdapter(activity!!)
summaryListView.adapter = adapter

にしたら直った。アプリケーションのcontextでの色と、Activityの色が違う(?)らしい。今回、なぜわざわざapplicationContextを使ったかは謎。

failed linking file resources

androidのプログラミングしていて “failed linking file resources. “というエラーが出た。

エラー前の変更箇所を思い出して、layoutリソースのactivityのConstraintLayoutのなかで

app:layout_constraintRight_toLeftOf="@+id/choice"

としなければいけないところを、

app:layout_constraintRight_toLeftOf="choice"

としていた。そういえば、デザイナーのプレビューで正常に表示されていなかったことを後から思い出した。

近況?

junkbulkと言います。

10年くらい前までは某所の日記で独り言を書いていたのですが、なんとなく飽きてしまってやめてしまいました。

趣味で電子工作とロボット作りとプログラミングしています。 近頃、 android 携帯向けのプログラミングを勉強中です。