web-dev-qa-db-ja.com

アダプターまたはViewHolderのKotlin合成

私はコトリンの初心者です。 findViewByIdクラスで迷惑なメソッドActivityの代わりに合成メソッドを見つけて使用しようとしましたが、「Viewで合成プロパティを呼び出したい場合(アダプタークラスで有用)、 kotlinx.Android.synthetic.main.view。*もインポートする必要があります。」しかし、私はそれが正確にどのように機能するのか理解できませんか?例はありますか?

64
busylee

https://github.com/antoniolg/Kotlin-for-Android-Developers の簡単な例

import kotlinx.Android.synthetic.item_forecast.view.*

class ForecastListAdapter() : RecyclerView.Adapter<ForecastListAdapter.ViewHolder>() {

    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {

        fun bindForecast(forecast: Forecast) {
            itemView.date.text = forecast.date.toDateString()
        }
    }
}

書く必要はありません

val view = itemView.findViewById(R.id.date) as TextView
view.text = forecast.date.toDateString()

ただ

itemView.date.text = forecast.date.toDateString()

シンプルで効果的!

77
Peter Zhao

Kotling 1.1.4アウト

詳細: https://antonioleiva.com/kotlin-Android-extensions/

そのため、これを追加できるようにする必要がありますbuild.gradle:

apply plugin: 'org.jetbrains.kotlin.Android.extensions'
androidExtensions {
    experimental = true
}

この新しいバージョンのKotlin以来、Android Extensionsにはいくつかの新しい興味深い機能が組み込まれています。任意のクラスのキャッシュ(興味深いことにViewHolderが含まれます)

ViewHolder(または任意のカスタムクラス)で使用する

class ViewHolder(override val containerView: View) : RecyclerView.ViewHolder(containerView), 
        LayoutContainer {

    fun bind(title: String) {
        itemTitle.text = "Hello Kotlin!"
    }
}
25
Dhaval Jivani

あなたが必要

import kotlinx.Android.synthetic.row_wall.view.*

その後、次の行に沿って何か:

convertView.titleText.text = item.title

要点は、view。*がViewクラスに拡張機能を導入することです。

7
Zsolt Szatmari

試して

class CustomViewModel(val baseView: View) { val firstName = baseView.firstName val lastName = baseView.lastName }

ビューオブジェクトはビューを公開しますref: https://discuss.kotlinlang.org/t/unable-to-use-kotlin-Android-extension-in-adapter-class/289

6
hyena

最新バージョンl ;.を使用している場合、experimental = trueを追加する必要はありません。

プロジェクトレベルGradle

classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.21'

アプリレベルのGradle

apply plugin: 'kotlin-Android'
apply plugin: 'kotlin-Android-extensions' //These should be on the top of file.

および依存関係で..

implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21'

以下としてインポート

import kotlinx.Android.synthetic.main.your_layout_file_name.view.*

そして例

import kotlinx.Android.synthetic.main.item_animal.view.*

class AnimalVH(parent: ViewGroup, layoutID: Int) : BaseViewHolder<Animal>(parent, layoutID) {

    override fun bindData(animal: Animal) {
        itemView.tv_animal.text = animal.title
    }
}

baseViewHolderは

abstract class BaseViewHolder<T>(parent: ViewGroup, layoutID: Int) : RecyclerView.ViewHolder(
    LayoutInflater.from(parent.context).inflate(layoutID, parent, false)
) {
    abstract fun bindData(model: T)
}
3
Xar E Ahmer

つまり、この行をソースファイルの先頭に配置する必要があります。

import kotlinx.Android.synthetic.main.view.*

そのため、たとえばfindView(R.id.textView) as TextViewの代わりにtextViewとだけ書くことになります。後者はパッケージkotlinx.Android.synthetic.main.viewにある合成拡張プロパティです。そのため、そこからすべてをインポートする必要があります。

公式サイトのチュートリアル があります。ご覧ください。

1

FYI:ビュールックアップでは、合成よりもデータバインディングをお勧めします。

GoogleからのAndroidのDAからのコメント Redditで

おい! GoogleのAndroidの開発者支援者はこちら!

ここに背景を少し加えたいと思いました。合成ビューを使用したKotlin Extensionsは、意図的に「推奨」されることはありませんでしたが、それらを使用しないことを推奨と見なすべきではありません。彼らがあなたのために働いているなら、あなたのアプリでそれらを使い続けてください。

それらは、無効なルックアップに対するチェックなしで実際に膨らまされ、Kotlinのみであり、donビューが一部の構成にのみ存在する場合、null可能性を公開しません。総合すると、これらの問題により、APIはAndroidアプリのクラッシュ数を増加させます。

一方、ビューの検索を簡素化するのに役立つ軽量APIを提供します。このスペースでは、自動ビュールックアップを実行するデータバインディングもご覧ください。また、LiveDataと統合して、データが変更されるとビューを自動的に更新します。

現在、このスペースには機能するいくつかのオプションがあります。

データバインディングは、ビューのルックアップとバインディングの推奨で​​すが、Android Kotlin Extensionsと比較すると、多少のオーバーヘッドが追加されます。これがアプリに適しているかどうかを確認する価値があります。データバインディングでは、LiveDataを観察して、データが変更されたときにビューを自動的にバインドすることもできます。 Kotlin Extensionsと比較して、ビューのルックアップとタイプセーフのコンパイル時チェックを追加します。 Android Kotlin Extensionsは公式には推奨されていません(推奨されているものとは異なります)。上記の問題が発生するため、コードでは使用していません。バターナイフは、KotlinとJavaプログラミング言語の両方で非常に人気のある別のソリューションです。ここのコメントを読むと、Kotlin Extensionsで大きな成功を収めている多くの開発者がいます。これはすばらしいことです。APIを改善し続ける方法を検討する際に留意することです。データバインディングをまだ見ていない場合は、ぜひ試してみてください。

余談ですが、内部コードスタイルガイドは、コードベースの外部に直接適用することを目的としていません。たとえば、mPrefixVariablesを使用しますが、すべてのアプリがそのスタイルに従う必要がある理由はありません。

0
user158