web-dev-qa-db-ja.com

レイアウトがライブラリモジュールにある場合の合成ビューの未解決の参照

kotlin 1.20.20を使用します(重要ではありません。古いバージョンも同じように動作します)

レイアウトが別のライブラリモジュールにある場合Android Studioでのビューの検索と参照に問題はありません

import kotlinx.Android.synthetic.main.view_user_input.*

しかし、アプリをコンパイルしようとすると、Unresolved reference: view_user_input オン :app:compileDebugKotlin

ライブラリモジュールでビューが参照されている場合、すべて正常に機能します。

ここに何かが足りませんか?

プロジェクト構造の追加。すべてのモジュールはkotlinおよびkotlin-extensionsを使用しています。

build.gradle
app/
  build.gradle //main application
library-module-a/
  build.gradle //library application
library-module-b/
  build.gradle //library application

以下にアプリの例を示します https://github.com/mjurkus/KotlinxTest

KTトラッカー でその問題を登録

20
Martynas Jurkus

これを解決する1つの方法は、他のモジュールから使用できる「エイリアス」プロパティを作成することです。

// SyntheticExports.kt
package com.example.synthetic.exported

import kotlinx.Android.synthetic.main.layout_in_library.*

inline val Activity.exported_text_view get() = text_view

次に、他のモジュールで:

// MainActivity.kt
import com.example.synthetic.exported.exported_text_view

exported_text_view.text = "example"

それは私たちにとってうまくいきます。 viewfragmentなどのさまざまな拡張機能を作成する必要があります。それらを手動で行うのは少し面倒ですが、これが最も簡単な回避策です。

Extra:これは、内部モジュールだけでなく、パブリックライブラリの一部として合成拡張機能をエクスポートするための適切な方法でもあります。

3
pablisco

私もこの問題を抱えており、私の解決策は次のとおりです。

  • Import kotlinx.Android.synthetic.main .... *を使用しないでください。

  • FindViewById()を使用します

例:textview_id.text = "abc"。 findViewById(R.id.textview_id).text = "abc"に変更します

3
Anh Duy

前提条件

次のライブラリをインポートしないでくださいimport kotlinx.Android.synthetic.main.my_view.view.*

app/MainActivity.kt

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val view: View = MyView(this)
        view.findViewById<TextView>(R.id.textViewPocLib).text = "I can edit the library components"
        setContentView(view)
}

my_library/MyView.kt

class MyView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
    LinearLayout(context, attrs, defStyleAttr) {

    init {
        LayoutInflater.from(context)
            .inflate(R.layout.my_view, this, true)
    }
}

GL

出典:

1
CORONEL Braian

1.2.30-eap-16に切り替えて追加してみてください

androidExtensions { experimental = true }

build.gradleに。

1
Ivan Morgillo

@ cesards 上記のコメントで述べたように、これは 進行中の問題 Kotlin Android Extentionsを使用しています。今日の。


良い:カスタムビューを使用する

私の主な提案は、ビューと関連する動作をカスタムビューとしてカプセル化し、<include>タグを介して含める代わりに、<com.example.app.YourCustomView>としてレイアウトで直接使用することです。

これは、ビュークラスが別のモジュールにあるかどうかに関係なく機能します。


悪いとUい:ID衝突回避策

ただし、含まれているビューからone referenceのみを取得したい場合は、ハッキーな回避策が見つかりました。

他のモジュールから含まれるレイアウトにkotlin合成インポートを使用するには、次の手順に従います。

  1. 含まれているxmlファイルで参照を取得するビューにidを与えます。
  2. インクルードxmlファイルのincludeタグに同じIDを与えます。
  3. これで、インクルードレイアウトから(インクルードからではなく)ビュー(id)を合成インポートします。

これがどのように、なぜ機能するのかはよくわかりませんが、レイアウトを再利用する非常に壊れやすく汚い方法です。

例:

レイアウト(fragment_example.xml)を含む

<include
    Android:id="@+id/exampleView"
    layout="@layout/example_layout" />

含まれるレイアウト(example_layout.xml)

<merge xmlns:Android="http://schemas.Android.com/apk/res/Android">

    <TextView
        Android:id="@+id/exampleView"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content" />

</merge>

フラグメントクラス(ExampleFragment.kt)

import kotlinx.Android.synthetic.main.fragment_example.exampleView

// Do not import the exampleView through example_layout.exampleView

class ExampleFragment : Fragment() {
    // Do something with imported exampleView
}
1
SafaOrhan