Kotlin:来自 AppCompatActivity 的片段
Kotlin: Fragment from AppCompatActivity
已将 AppCompatActivity()
转换为 Fragment()
并根据主题进行了一些更改:
并更新了 Gradle .
carouselView
在我制作片段视图之前工作。它编译:
Executing tasks: [:app:assembleDebug] in project /Users/jaskier/Documents/Android/GoodTogether
Configure project :app
Warning: The 'kotlin-android-extensions' Gradle plugin is deprecated. Please use this migration guide (https://goo.gle/kotlin-android-extensions-deprecation) to start working with View Binding (https://developer.android.com/topic/libraries/view-binding) and the 'kotlin-parcelize' plugin.
Configure project :tabview
Warning: The 'kotlin-android-extensions' Gradle plugin is deprecated. Please use this migration guide (https://goo.gle/kotlin-android-extensions-deprecation) to start working with View Binding (https://developer.android.com/topic/libraries/view-binding) and the 'kotlin-parcelize' plugin.
Task :app:preBuild UP-TO-DATE
Task :app:preDebugBuild UP-TO-DATE
Task :tabview:preBuild UP-TO-DATE
Task :tabview:preDebugBuild UP-TO-DATE
Task :tabview:packageDebugRenderscript NO-SOURCE
Task :app:generateDebugBuildConfig UP-TO-DATE
Task :app:compileDebugRenderscript NO-SOURCE
Task :tabview:compileDebugAidl NO-SOURCE
Task :app:compileDebugAidl NO-SOURCE
Task :app:generateDebugResValues UP-TO-DATE
Task :app:generateDebugResources UP-TO-DATE
Task :tabview:generateDebugResValues UP-TO-DATE
Task :tabview:compileDebugRenderscript NO-SOURCE
Task :tabview:generateDebugResources UP-TO-DATE
Task :tabview:packageDebugResources UP-TO-DATE
Task :app:mergeDebugResources UP-TO-DATE
Task :app:createDebugCompatibleScreenManifests UP-TO-DATE
Task :app:extractDeepLinksDebug UP-TO-DATE
Task :tabview:extractDeepLinksDebug UP-TO-DATE
Task :tabview:processDebugManifest UP-TO-DATE
Task :app:processDebugManifest UP-TO-DATE
Task :tabview:compileDebugLibraryResources UP-TO-DATE
Task :tabview:parseDebugLocalResources UP-TO-DATE
Task :tabview:generateDebugRFile UP-TO-DATE
Task :app:processDebugResources UP-TO-DATE
Task :tabview:generateDebugBuildConfig UP-TO-DATE
Task :tabview:javaPreCompileDebug UP-TO-DATE
Task :tabview:compileDebugKotlin UP-TO-DATE
Task :tabview:compileDebugJavaWithJavac UP-TO-DATE
Task :tabview:bundleLibCompileToJarDebug UP-TO-DATE
Task :app:compileDebugKotlin UP-TO-DATE
Task :app:javaPreCompileDebug UP-TO-DATE
Task :app:compileDebugJavaWithJavac UP-TO-DATE
Task :app:compileDebugSources UP-TO-DATE
Task :app:mergeDebugShaders UP-TO-DATE
Task :app:compileDebugShaders NO-SOURCE
Task :app:generateDebugAssets UP-TO-DATE
Task :tabview:mergeDebugShaders UP-TO-DATE
Task :tabview:compileDebugShaders NO-SOURCE
Task :tabview:generateDebugAssets UP-TO-DATE
Task :tabview:packageDebugAssets UP-TO-DATE
Task :app:mergeDebugAssets UP-TO-DATE
Task :app:processDebugJavaRes NO-SOURCE
Task :tabview:processDebugJavaRes NO-SOURCE
Task :tabview:bundleLibResDebug UP-TO-DATE
Task :app:mergeDebugJavaResource UP-TO-DATE
Task :tabview:bundleLibRuntimeToJarDebug UP-TO-DATE
Task :app:dexBuilderDebug UP-TO-DATE
Task :app:checkDebugDuplicateClasses UP-TO-DATE
Task :app:mergeExtDexDebug UP-TO-DATE
Task :app:mergeDexDebug UP-TO-DATE
Task :app:mergeDebugJniLibFolders UP-TO-DATE
Task :tabview:mergeDebugJniLibFolders UP-TO-DATE
Task :tabview:mergeDebugNativeLibs UP-TO-DATE
Task :tabview:stripDebugDebugSymbols NO-SOURCE
Task :tabview:copyDebugJniLibsProjectOnly UP-TO-DATE
Task :app:mergeDebugNativeLibs UP-TO-DATE
Task :app:stripDebugDebugSymbols NO-SOURCE
Task :app:validateSigningDebug UP-TO-DATE
Task :app:packageDebug UP-TO-DATE
Task :app:assembleDebug UP-TO-DATE
BUILD SUCCESSFUL in 829ms 40 actionable tasks: 40 up-to-date Build
Analyzer results available
但是当我将此片段切换为活动状态(带有片段的 tabView)时,它给出:
Unfortunately, Application has stopped
从 AppCompatActivity()
转换时我会遗漏什么?
之前:
package com.myPackage.application
import android.annotation.SuppressLint
import android.app.PendingIntent.getActivity
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.ImageView
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat
import kotlinx.android.synthetic.main.activity_start_carousel.*
class StartCarouselActivity : AppCompatActivity() {
private val movies = arrayListOf(R.drawable.ic_action_tab1, R.drawable.ic_action_tab2, R.drawable.ic_action_tab3)
private val moviesTitles = arrayListOf("Harry Potter", "Konosuba", "I Am Legend")
private val trending = arrayListOf(R.drawable.ic_action_tab1, R.drawable.ic_action_tab2, R.drawable.ic_action_tab3)
private val trendingTitles = arrayListOf("Lord of the Rings", "The Last Naruto the Movie", "Spirited Away")
@SuppressLint("UseCompatLoadingForDrawables")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_start_carousel)
carouselView1.apply {
size = movies.size
resource = R.layout.start_carousel_movies_item
scaleOnScroll = true
spacing = 50
hideIndicator(true)
setCarouselViewListener { view, position ->
val imageView = view.findViewById<ImageView>(R.id.imageView)
imageView.setImageDrawable(ResourcesCompat.getDrawable(resources, movies[position], null))
val textView = view.findViewById<TextView>(R.id.textViewTitle)
textView.text = moviesTitles[position]
}
show()
}
carouselView2.apply {
val trendingMovies = trending + movies
val trendingTitle = trendingTitles + moviesTitles
size = trendingMovies.size
resource = R.layout.start_carousel_trending_item
spacing = 50
hideIndicator(true)
setCarouselViewListener { view, position ->
val imageView = view.findViewById<ImageView>(R.id.imageView)
imageView.setImageDrawable(ResourcesCompat.getDrawable(resources, trendingMovies[position], null))
val textView = view.findViewById<TextView>(R.id.textViewTitle)
textView.text = trendingTitle[position]
}
show()
}
}
}
之后:
package com.myPackage.application
import android.annotation.SuppressLint
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.core.content.res.ResourcesCompat
import androidx.fragment.app.Fragment
import kotlinx.android.synthetic.main.activity_start_carousel.*
import kotlinx.android.synthetic.main.fragment_tab2.view.*
class TabFragment2 : Fragment() {
private val movies = arrayListOf(
R.drawable.ic_action_tab1,
R.drawable.ic_action_tab2,
R.drawable.ic_action_tab3
)
private val moviesTitles = arrayListOf("Harry Potter", "Konosuba", "I Am Legend")
private val trending = arrayListOf(
R.drawable.ic_action_tab1,
R.drawable.ic_action_tab2,
R.drawable.ic_action_tab3
)
private val trendingTitles = arrayListOf(
"Lord of the Rings",
"The Last Naruto the Movie",
"Spirited Away"
)
@SuppressLint("UseCompatLoadingForDrawables")
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
super.onCreate(savedInstanceState)
val v: View = inflater.inflate(R.layout.activity_start_carousel, container, false)
carouselView1.apply {
size = movies.size
resource = R.layout.start_carousel_movies_item
scaleOnScroll = true
spacing = 50
hideIndicator(true)
setCarouselViewListener { view, position ->
val imageView = view.findViewById<ImageView>(R.id.imageView)
imageView.setImageDrawable(
ResourcesCompat.getDrawable(
resources,
movies[position],
null
)
)
val textView = view.findViewById<TextView>(R.id.textViewTitle)
textView.text = moviesTitles[position]
}
show()
}
carouselView2.apply {
val trendingMovies = trending + movies
val trendingTitle = trendingTitles + moviesTitles
size = trendingMovies.size
resource = R.layout.start_carousel_trending_item
spacing = 50
hideIndicator(true)
setCarouselViewListener { view, position ->
val imageView = view.findViewById<ImageView>(R.id.imageView)
imageView.setImageDrawable(
ResourcesCompat.getDrawable(
resources,
trendingMovies[position],
null
)
)
val textView = view.findViewById<TextView>(R.id.textViewTitle)
textView.text = trendingTitle[position]
}
show()
}
return v
}
}
假设您的轮播视图 ID 是 carouselView1 和 carouselView2,您应该使用
v.findViewById<CarouselView>(R.id.carouselView1).apply { ... }
和
v.findViewById<CarouselView>(R.id.carouselView2).apply { ... }
在 onCreateView
中实例化轮播视图。
kotlin中的apply函数是一个作用域函数,引用上下文对象(本例中是你的两个CarouselView
)
和 returns 它。
所以在你的情况下 v.findViewById<CarouselView>(R.id.carouselView1).apply { ... }
和 v.findViewById<CarouselView>(R.id.carouselView2).apply { ... }
returns一个CarouselView
.
如果您需要在 Fragment
:
中全局使用视图,此行为可能很有用
private var carouselView1: CarouselView? = null
@SuppressLint("UseCompatLoadingForDrawables")
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
super.onCreate(savedInstanceState)
val v: View = inflater.inflate(R.layout.activity_start_carousel, container, false)
carouselView1 = v.findViewById<CarouselView>(R.id.carouselView1).apply { ... }
}
fun exampleFunction() {
// Example operation to explain the global use of this variable
carouselView1?.spacing = 10
}
有关 Kotlin 范围函数的更多信息,请参阅 here。
您的片段代码的主要问题是您没有在膨胀视图 (v
) 中搜索您的 CarouselView
。
事实上,在你的 AppCompactActivity
中你不需要参考 findViewById
之前的特定视图,因为 onCreate
中的 setContentView
方法,
自动膨胀布局。
这些是代码语法 v.findViewById<ViewType>(<view-id>)
的原因。
已将 AppCompatActivity()
转换为 Fragment()
并根据主题进行了一些更改:
carouselView
在我制作片段视图之前工作。它编译:
Executing tasks: [:app:assembleDebug] in project /Users/jaskier/Documents/Android/GoodTogether
Configure project :app Warning: The 'kotlin-android-extensions' Gradle plugin is deprecated. Please use this migration guide (https://goo.gle/kotlin-android-extensions-deprecation) to start working with View Binding (https://developer.android.com/topic/libraries/view-binding) and the 'kotlin-parcelize' plugin.
Configure project :tabview Warning: The 'kotlin-android-extensions' Gradle plugin is deprecated. Please use this migration guide (https://goo.gle/kotlin-android-extensions-deprecation) to start working with View Binding (https://developer.android.com/topic/libraries/view-binding) and the 'kotlin-parcelize' plugin.
Task :app:preBuild UP-TO-DATE Task :app:preDebugBuild UP-TO-DATE Task :tabview:preBuild UP-TO-DATE Task :tabview:preDebugBuild UP-TO-DATE Task :tabview:packageDebugRenderscript NO-SOURCE Task :app:generateDebugBuildConfig UP-TO-DATE Task :app:compileDebugRenderscript NO-SOURCE Task :tabview:compileDebugAidl NO-SOURCE Task :app:compileDebugAidl NO-SOURCE Task :app:generateDebugResValues UP-TO-DATE Task :app:generateDebugResources UP-TO-DATE Task :tabview:generateDebugResValues UP-TO-DATE Task :tabview:compileDebugRenderscript NO-SOURCE Task :tabview:generateDebugResources UP-TO-DATE Task :tabview:packageDebugResources UP-TO-DATE Task :app:mergeDebugResources UP-TO-DATE Task :app:createDebugCompatibleScreenManifests UP-TO-DATE Task :app:extractDeepLinksDebug UP-TO-DATE Task :tabview:extractDeepLinksDebug UP-TO-DATE Task :tabview:processDebugManifest UP-TO-DATE Task :app:processDebugManifest UP-TO-DATE Task :tabview:compileDebugLibraryResources UP-TO-DATE Task :tabview:parseDebugLocalResources UP-TO-DATE Task :tabview:generateDebugRFile UP-TO-DATE Task :app:processDebugResources UP-TO-DATE Task :tabview:generateDebugBuildConfig UP-TO-DATE Task :tabview:javaPreCompileDebug UP-TO-DATE Task :tabview:compileDebugKotlin UP-TO-DATE Task :tabview:compileDebugJavaWithJavac UP-TO-DATE Task :tabview:bundleLibCompileToJarDebug UP-TO-DATE Task :app:compileDebugKotlin UP-TO-DATE Task :app:javaPreCompileDebug UP-TO-DATE Task :app:compileDebugJavaWithJavac UP-TO-DATE Task :app:compileDebugSources UP-TO-DATE Task :app:mergeDebugShaders UP-TO-DATE Task :app:compileDebugShaders NO-SOURCE Task :app:generateDebugAssets UP-TO-DATE Task :tabview:mergeDebugShaders UP-TO-DATE Task :tabview:compileDebugShaders NO-SOURCE Task :tabview:generateDebugAssets UP-TO-DATE Task :tabview:packageDebugAssets UP-TO-DATE Task :app:mergeDebugAssets UP-TO-DATE Task :app:processDebugJavaRes NO-SOURCE Task :tabview:processDebugJavaRes NO-SOURCE Task :tabview:bundleLibResDebug UP-TO-DATE Task :app:mergeDebugJavaResource UP-TO-DATE Task :tabview:bundleLibRuntimeToJarDebug UP-TO-DATE Task :app:dexBuilderDebug UP-TO-DATE Task :app:checkDebugDuplicateClasses UP-TO-DATE Task :app:mergeExtDexDebug UP-TO-DATE Task :app:mergeDexDebug UP-TO-DATE Task :app:mergeDebugJniLibFolders UP-TO-DATE Task :tabview:mergeDebugJniLibFolders UP-TO-DATE Task :tabview:mergeDebugNativeLibs UP-TO-DATE Task :tabview:stripDebugDebugSymbols NO-SOURCE Task :tabview:copyDebugJniLibsProjectOnly UP-TO-DATE Task :app:mergeDebugNativeLibs UP-TO-DATE Task :app:stripDebugDebugSymbols NO-SOURCE Task :app:validateSigningDebug UP-TO-DATE Task :app:packageDebug UP-TO-DATE Task :app:assembleDebug UP-TO-DATE
BUILD SUCCESSFUL in 829ms 40 actionable tasks: 40 up-to-date Build Analyzer results available
但是当我将此片段切换为活动状态(带有片段的 tabView)时,它给出:
Unfortunately, Application has stopped
从 AppCompatActivity()
转换时我会遗漏什么?
之前:
package com.myPackage.application
import android.annotation.SuppressLint
import android.app.PendingIntent.getActivity
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.ImageView
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat
import kotlinx.android.synthetic.main.activity_start_carousel.*
class StartCarouselActivity : AppCompatActivity() {
private val movies = arrayListOf(R.drawable.ic_action_tab1, R.drawable.ic_action_tab2, R.drawable.ic_action_tab3)
private val moviesTitles = arrayListOf("Harry Potter", "Konosuba", "I Am Legend")
private val trending = arrayListOf(R.drawable.ic_action_tab1, R.drawable.ic_action_tab2, R.drawable.ic_action_tab3)
private val trendingTitles = arrayListOf("Lord of the Rings", "The Last Naruto the Movie", "Spirited Away")
@SuppressLint("UseCompatLoadingForDrawables")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_start_carousel)
carouselView1.apply {
size = movies.size
resource = R.layout.start_carousel_movies_item
scaleOnScroll = true
spacing = 50
hideIndicator(true)
setCarouselViewListener { view, position ->
val imageView = view.findViewById<ImageView>(R.id.imageView)
imageView.setImageDrawable(ResourcesCompat.getDrawable(resources, movies[position], null))
val textView = view.findViewById<TextView>(R.id.textViewTitle)
textView.text = moviesTitles[position]
}
show()
}
carouselView2.apply {
val trendingMovies = trending + movies
val trendingTitle = trendingTitles + moviesTitles
size = trendingMovies.size
resource = R.layout.start_carousel_trending_item
spacing = 50
hideIndicator(true)
setCarouselViewListener { view, position ->
val imageView = view.findViewById<ImageView>(R.id.imageView)
imageView.setImageDrawable(ResourcesCompat.getDrawable(resources, trendingMovies[position], null))
val textView = view.findViewById<TextView>(R.id.textViewTitle)
textView.text = trendingTitle[position]
}
show()
}
}
}
之后:
package com.myPackage.application
import android.annotation.SuppressLint
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.core.content.res.ResourcesCompat
import androidx.fragment.app.Fragment
import kotlinx.android.synthetic.main.activity_start_carousel.*
import kotlinx.android.synthetic.main.fragment_tab2.view.*
class TabFragment2 : Fragment() {
private val movies = arrayListOf(
R.drawable.ic_action_tab1,
R.drawable.ic_action_tab2,
R.drawable.ic_action_tab3
)
private val moviesTitles = arrayListOf("Harry Potter", "Konosuba", "I Am Legend")
private val trending = arrayListOf(
R.drawable.ic_action_tab1,
R.drawable.ic_action_tab2,
R.drawable.ic_action_tab3
)
private val trendingTitles = arrayListOf(
"Lord of the Rings",
"The Last Naruto the Movie",
"Spirited Away"
)
@SuppressLint("UseCompatLoadingForDrawables")
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
super.onCreate(savedInstanceState)
val v: View = inflater.inflate(R.layout.activity_start_carousel, container, false)
carouselView1.apply {
size = movies.size
resource = R.layout.start_carousel_movies_item
scaleOnScroll = true
spacing = 50
hideIndicator(true)
setCarouselViewListener { view, position ->
val imageView = view.findViewById<ImageView>(R.id.imageView)
imageView.setImageDrawable(
ResourcesCompat.getDrawable(
resources,
movies[position],
null
)
)
val textView = view.findViewById<TextView>(R.id.textViewTitle)
textView.text = moviesTitles[position]
}
show()
}
carouselView2.apply {
val trendingMovies = trending + movies
val trendingTitle = trendingTitles + moviesTitles
size = trendingMovies.size
resource = R.layout.start_carousel_trending_item
spacing = 50
hideIndicator(true)
setCarouselViewListener { view, position ->
val imageView = view.findViewById<ImageView>(R.id.imageView)
imageView.setImageDrawable(
ResourcesCompat.getDrawable(
resources,
trendingMovies[position],
null
)
)
val textView = view.findViewById<TextView>(R.id.textViewTitle)
textView.text = trendingTitle[position]
}
show()
}
return v
}
}
假设您的轮播视图 ID 是 carouselView1 和 carouselView2,您应该使用
v.findViewById<CarouselView>(R.id.carouselView1).apply { ... }
和
v.findViewById<CarouselView>(R.id.carouselView2).apply { ... }
在 onCreateView
中实例化轮播视图。
kotlin中的apply函数是一个作用域函数,引用上下文对象(本例中是你的两个CarouselView
)
和 returns 它。
所以在你的情况下 v.findViewById<CarouselView>(R.id.carouselView1).apply { ... }
和 v.findViewById<CarouselView>(R.id.carouselView2).apply { ... }
returns一个CarouselView
.
如果您需要在 Fragment
:
private var carouselView1: CarouselView? = null
@SuppressLint("UseCompatLoadingForDrawables")
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
super.onCreate(savedInstanceState)
val v: View = inflater.inflate(R.layout.activity_start_carousel, container, false)
carouselView1 = v.findViewById<CarouselView>(R.id.carouselView1).apply { ... }
}
fun exampleFunction() {
// Example operation to explain the global use of this variable
carouselView1?.spacing = 10
}
有关 Kotlin 范围函数的更多信息,请参阅 here。
您的片段代码的主要问题是您没有在膨胀视图 (v
) 中搜索您的 CarouselView
。
事实上,在你的 AppCompactActivity
中你不需要参考 findViewById
之前的特定视图,因为 onCreate
中的 setContentView
方法,
自动膨胀布局。
这些是代码语法 v.findViewById<ViewType>(<view-id>)
的原因。