Android Studio 的设计视图中不呈现自定义视图?
Custom View does not render in Design View in Android Studio?
我已经为底部的信息创建了一个自定义视图,屏幕顶部有分隔线。
我无法在 Android Studio (V4.1) 的设计视图中呈现它,尽管它在应用程序中运行良好。
class InfoDivider @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0,
defStyleRes: Int = 0
) : LinearLayout(context, attrs, defStyle, defStyleRes) {
var text: String? by Delegates.observable<String?>("") { _, old, new ->
if (old != new)
update()
}
init {
LayoutInflater.from(context)
.inflate(R.layout.info_divider, this, true)
orientation = VERTICAL
if (attrs != null) {
val math = context.obtainStyledAttributes(attrs, R.styleable.InfoDivider)
if (math.hasValue(R.styleable.InfoDivider_text)) {
this.text = math.getString(R.styleable.InfoDivider_text)
}
math.recycle()
}
}
private fun update() {
txt_message.text = text
}
}
它仅在设计视图中抛出一些问题
java.lang.NoSuchMethodError: kotlin.jvm.internal.MutablePropertyReference1Impl.<init>(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;I)V
at com.test.custom_views.info_dividers.InfoDivider.<clinit>(InfoDivider.kt)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.jetbrains.android.uipreview.ViewLoader.createNewInstance(ViewLoader.java:413)
at org.jetbrains.android.uipreview.ViewLoader.loadClass(ViewLoader.java:203)
at org.jetbrains.android.uipreview.ViewLoader.loadView(ViewLoader.java:161)
at com.android.tools.idea.rendering.LayoutlibCallbackImpl.loadView(LayoutlibCallbackImpl.java:309)
at android.view.BridgeInflater.loadCustomView(BridgeInflater.java:416)
at android.view.BridgeInflater.loadCustomView(BridgeInflater.java:427)
at android.view.BridgeInflater.createViewFromTag(BridgeInflater.java:331)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:961)
at android.view.LayoutInflater.inflate(LayoutInflater.java:659)
at android.view.LayoutInflater.inflate(LayoutInflater.java:501)
at com.android.layoutlib.bridge.impl.RenderSessionImpl.inflate(RenderSessionImpl.java:353)
at com.android.layoutlib.bridge.Bridge.createSession(Bridge.java:404)
at com.android.tools.idea.layoutlib.LayoutLibrary.createSession(LayoutLibrary.java:141)
at com.android.tools.idea.rendering.RenderTask.createRenderSession(RenderTask.java:713)
at com.android.tools.idea.rendering.RenderTask.lambda$inflate(RenderTask.java:844)
at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1604)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
看起来像这样
它应该是这样的
class InfoDivider @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0,
defStyleRes: Int = 0
) : LinearLayout(context, attrs, defStyle, defStyleRes) {
init {
LayoutInflater.from(context)
.inflate(R.layout.info_divider, this, true)
orientation = VERTICAL
if (attrs != null) {
val math = context.obtainStyledAttributes(attrs, R.styleable.InfoDivider)
if (math.hasValue(R.styleable.InfoDivider_text)) {
txt_message.text = math.getString(R.styleable.InfoDivider_text)
}
math.recycle()
}
}
fun setText(str: String) {
txt_message.text = str
}
}
对于可能陷入同一问题的任何人。
根本原因是 Kotlin 委托属性。
解决方案可能是以下 3 种中的一种:
删除使用委托属性的代码
保持委托属性逻辑并将您的 Kotlin 版本降低到 1.3 - 由我自己测试,它有效但您必须放弃一些只有 Kotlin 1.4 才能提供的 Kotlin 功能,例如尾随逗号,自动智能投射...
保留委托属性,Kotlin 版本高于 1.4,并将您的 Android Studio 升级到 4.2 beta - 撰写此答案时的最新版本。
这是我找到上述答案的地方
我已经为底部的信息创建了一个自定义视图,屏幕顶部有分隔线。 我无法在 Android Studio (V4.1) 的设计视图中呈现它,尽管它在应用程序中运行良好。
class InfoDivider @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0,
defStyleRes: Int = 0
) : LinearLayout(context, attrs, defStyle, defStyleRes) {
var text: String? by Delegates.observable<String?>("") { _, old, new ->
if (old != new)
update()
}
init {
LayoutInflater.from(context)
.inflate(R.layout.info_divider, this, true)
orientation = VERTICAL
if (attrs != null) {
val math = context.obtainStyledAttributes(attrs, R.styleable.InfoDivider)
if (math.hasValue(R.styleable.InfoDivider_text)) {
this.text = math.getString(R.styleable.InfoDivider_text)
}
math.recycle()
}
}
private fun update() {
txt_message.text = text
}
}
它仅在设计视图中抛出一些问题
java.lang.NoSuchMethodError: kotlin.jvm.internal.MutablePropertyReference1Impl.<init>(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;I)V
at com.test.custom_views.info_dividers.InfoDivider.<clinit>(InfoDivider.kt)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.jetbrains.android.uipreview.ViewLoader.createNewInstance(ViewLoader.java:413)
at org.jetbrains.android.uipreview.ViewLoader.loadClass(ViewLoader.java:203)
at org.jetbrains.android.uipreview.ViewLoader.loadView(ViewLoader.java:161)
at com.android.tools.idea.rendering.LayoutlibCallbackImpl.loadView(LayoutlibCallbackImpl.java:309)
at android.view.BridgeInflater.loadCustomView(BridgeInflater.java:416)
at android.view.BridgeInflater.loadCustomView(BridgeInflater.java:427)
at android.view.BridgeInflater.createViewFromTag(BridgeInflater.java:331)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:961)
at android.view.LayoutInflater.inflate(LayoutInflater.java:659)
at android.view.LayoutInflater.inflate(LayoutInflater.java:501)
at com.android.layoutlib.bridge.impl.RenderSessionImpl.inflate(RenderSessionImpl.java:353)
at com.android.layoutlib.bridge.Bridge.createSession(Bridge.java:404)
at com.android.tools.idea.layoutlib.LayoutLibrary.createSession(LayoutLibrary.java:141)
at com.android.tools.idea.rendering.RenderTask.createRenderSession(RenderTask.java:713)
at com.android.tools.idea.rendering.RenderTask.lambda$inflate(RenderTask.java:844)
at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1604)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
看起来像这样
它应该是这样的
class InfoDivider @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0,
defStyleRes: Int = 0
) : LinearLayout(context, attrs, defStyle, defStyleRes) {
init {
LayoutInflater.from(context)
.inflate(R.layout.info_divider, this, true)
orientation = VERTICAL
if (attrs != null) {
val math = context.obtainStyledAttributes(attrs, R.styleable.InfoDivider)
if (math.hasValue(R.styleable.InfoDivider_text)) {
txt_message.text = math.getString(R.styleable.InfoDivider_text)
}
math.recycle()
}
}
fun setText(str: String) {
txt_message.text = str
}
}
对于可能陷入同一问题的任何人。
根本原因是 Kotlin 委托属性。
解决方案可能是以下 3 种中的一种:
删除使用委托属性的代码
保持委托属性逻辑并将您的 Kotlin 版本降低到 1.3 - 由我自己测试,它有效但您必须放弃一些只有 Kotlin 1.4 才能提供的 Kotlin 功能,例如尾随逗号,自动智能投射...
保留委托属性,Kotlin 版本高于 1.4,并将您的 Android Studio 升级到 4.2 beta - 撰写此答案时的最新版本。
这是我找到上述答案的地方