android - 为什么aFragment中的属性在显示Dialog后位于ViewPager中不再初始化?
问题描述
正如您在图像中看到的那样,我有一个TabLayout和一个Viewpager。
我有一个产品片段和一个类别片段。在我的onViewCreated方法中,我将 progressBar 设置为可见。在访问 ProgressBar 之前,在onViewCreated方法中初始化了progressBar 属性。
正如您在图像中看到的,ProgressBar 已成功设置为可见。产品已加载,然后 ProgressBar 再次设置为不可见。
当我点击浮动操作按钮时,我正在打开一个Dialog,它扩展了DialogFragment类。
包含 TabView 和 ViewPager 的主类正在实现ProductDialog.ProductDialogEventListener。这意味着,当我点击保存按钮时,在主类中调用方法 onProductAdded。
但是,此方法调用 productFragment 类中的方法以将新产品添加到片段内的列表中。当 ProgressBar 现在设置为可见时,我收到 UninitializedPropertyAccessException 因为 progressBar 属性未初始化。
没看懂,因为之前已经初始化并使用过。
这是一些代码:
产品对话框:
class ProductDialog : DialogFragment() {
lateinit var editTextTitle: EditText
lateinit var editTextSpecialText: EditText
lateinit var editTextDescription: EditText
lateinit var radioButtonMen: RadioButton
lateinit var radioButtonWomen: RadioButton
lateinit var radioButtonUnisex: RadioButton
lateinit var productDialog: AlertDialog
lateinit var productDialogEventListener: ProductDialogEventListener
lateinit var apiOperations: ApiOperations
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val builder = AlertDialog.Builder(activity)
val inflater = requireActivity().layoutInflater
val view = inflater.inflate(R.layout.layout_product_dialog,null)
builder.setView(view)
.setTitle("Produkt erstellen")
.setPositiveButton("Speichern") { _, _ -> saveProductRequest()}
.setNegativeButton(R.string.cancel) { _, _ ->
dialog.cancel()
}
setViews(view)
setValues(view)
productDialog = builder.create()
return productDialog
}
interface ProductDialogEventListener{
val onProductAdded: (variant:Product)->Unit
}
override fun onAttach(context: Context?) {
super.onAttach(context)
try {
productDialogEventListener = context as ProductDialogEventListener
}catch (exception: ClassCastException){
throw exception
}
}
private fun onProductSaved(id:String){
productDialogEventListener.onProductAdded(Product(id.toInt(),editTextTitle.text.toString(),editTextSpecialText.text.toString(),editTextDescription.text.toString(),getCheckedGender()))
}
主要活动(OverviewActivity)
import android.content.Intent
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.design.widget.FloatingActionButton
import android.support.design.widget.TabLayout
import android.support.design.widget.TabLayout.OnTabSelectedListener
import android.support.v4.app.Fragment
import android.support.v4.view.ViewPager
import android.view.View
import android.widget.ListView
import android.widget.ProgressBar
import android.widget.TableLayout
import android.widget.Toast
class OverviewActivity : AppCompatActivity(), ProductDialog.ProductDialogEventListener, CategoryDialog.CategoryDialogListener {
private lateinit var listViewCategories: ListView
private lateinit var apiOperations: ApiOperations
private lateinit var progressBarCategories: ProgressBar
private lateinit var addCategoryButton: FloatingActionButton
private lateinit var tabLayout: TabLayout
private lateinit var viewPager : ViewPager
private var categories = ArrayList<Category>()
private val productsFragment = ProductsFragment()
private val categoriesFragment = CategoriesFragment()
override fun onResume() {
super.onResume()
setCategories()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_overview)
setViews()
setViewPager()
setValues()
}
private fun setViews(){
listViewCategories = findViewById(R.id.listViewCategories)
addCategoryButton = findViewById(R.id.add_category_button)
progressBarCategories = findViewById(R.id.progressCategories)
viewPager = findViewById(R.id.viewPager)
tabLayout = findViewById(R.id.tabLayout)
}
private fun setViewPager(){
val fragmentList = listOf(productsFragment,categoriesFragment)
val overViewPageViewAdapter = OverViewPageViewAdapter(supportFragmentManager,tabLayout.tabCount)
viewPager.adapter = overViewPageViewAdapter
viewPager.addOnPageChangeListener(TabLayout.TabLayoutOnPageChangeListener(tabLayout))
tabLayout.addOnTabSelectedListener(object : OnTabSelectedListener{
override fun onTabReselected(p0: TabLayout.Tab?) {
}
override fun onTabUnselected(p0: TabLayout.Tab?) {
}
override fun onTabSelected(tab: TabLayout.Tab) {
viewPager.currentItem = tab.position
}
})
}
private fun setValues(){
apiOperations = ApiOperations(applicationContext)
}
private fun setProgressBarVisible(visible: Boolean, progressBar: ProgressBar){
when(visible){
true -> progressBar.visibility = View.VISIBLE
else -> progressBar.visibility = View.GONE
}
}
fun addNewProductButtonClicked(view:View){
val dialog = ProductDialog()
dialog.show(supportFragmentManager,"New Product")
}
override val onProductAdded: (product: Product) -> Unit
get() = {product ->
productsFragment.onProductAdded(product)
}
}
最后是 productFragment 类
import android.content.Intent
import android.os.Bundle
import android.support.design.widget.FloatingActionButton
import android.support.v4.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ListView
import android.widget.ProgressBar
import android.widget.Toast
class ProductsFragment :Fragment(){
lateinit var apiOperations: ApiOperations
lateinit var listViewProducts: ListView
lateinit var addProductButton: FloatingActionButton
lateinit var progressBar: ProgressBar
private var products = ArrayList<Product>()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.products_fragment_layout,container,false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
apiOperations = ApiOperations(view.context)
setViews(view)
setProducts(view)
}
private fun setViews(view: View){
listViewProducts = view.findViewById(R.id.listViewProducts)
addProductButton = view.findViewById(R.id.add_product_button)
progressBar = view.findViewById(R.id.progress_circular)
}
private fun updateProductList(view: View,newList:ArrayList<Product>){
Toast.makeText(context,"settingProgressbar visible",Toast.LENGTH_SHORT).show()
setProgressBarVisible(true)
products = newList
listViewProducts.adapter = ProductListViewAdapter(view,
products,::deleteProduct)
listViewProducts.setOnItemClickListener{ _, _, position, _ ->
val product: Product = listViewProducts.adapter.getItem(position) as Product
openProductActivity(product)
}
setProgressBarVisible(false)
}
private fun setProducts(view: View){
setProgressBarVisible(true)
apiOperations.getProducts(
{ newList -> updateProductList(view,newList)},
{
setProgressBarVisible(false)
Toast.makeText(context,"Produkte konnten nicht geladen werden!",Toast.LENGTH_SHORT).show()
}
)
}
fun addNewProductButtonClicked(view:View){
val dialog = ProductDialog()
dialog.show(fragmentManager,"New Product")
}
private fun deleteProduct(view: View,productId: Int){
setProgressBarVisible(true)
apiOperations.deleteProduct(productId,{
products.removeAll { product -> product.id == productId }
updateProductList(view,products)
setProgressBarVisible(false)
Toast.makeText(view.context,"Produkt wurde gelöscht!", Toast.LENGTH_SHORT).show()
},
{
Toast.makeText(view.context, "Es ist ein Fehler aufgetreten!" , Toast.LENGTH_LONG).show()
setProgressBarVisible(false)
}
)
}
private fun openProductActivity(product: Product){
val intent = Intent(view?.context, ProductActivity::class.java)
intent.putExtra("product",product)
startActivity(intent)
}
private fun setProgressBarVisible(visible: Boolean){
if(progressBar==null){
progressBar = view!!.findViewById(R.id.progress_bar)
}
Toast.makeText(context,"setProgressbar called",Toast.LENGTH_SHORT).show()
when(visible){
true -> progressBar.visibility = View.VISIBLE
else -> progressBar.visibility = View.GONE
}
}
fun onProductAdded(product: Product) {
setProgressBarVisible(true)
products.add(product)
Toast.makeText(context,products.size.toString(),Toast.LENGTH_SHORT).show()
Toast.makeText(context,"Neues Produkt " + product.title + " hinzugefügt!",Toast.LENGTH_SHORT).show()
setProgressBarVisible(false)
}
}
我还在另一个片段中添加了以下代码。我有同样的问题。似乎 getView() (仅在 Kotlin 中view)导致 null 并且因此不起作用。为什么会这样。我还尝试按照评论中的建议重置 onResume 中的值,但关闭 DialogFragment 后既不调用 onPause 也不调用 onResume。
我无法想象我是唯一有这个问题的人。
fun onCategoryAdded(category: Category){
Log.i("fragment","onCategoryAdded called")
if(categories === null){
Log.i("fragment", "categories is null")
}
if(view == null){
Log.i("fragment", "view is null")
}
if(categories!=null && view!= null){
categories.add(category)
updateCategoriesList(view!!.context,categories)
}
}
解决方案
您可以在活动中创建进度条而不是片段,然后从两个片段访问进度条。通过这样做,您将不会面临错误。
推荐阅读
- corda - corda 4 - 一个国家可以属于多个合同类别
- ios - Zoom iOS 客户端 SDK - Swift - 群组通话流视图
- google-data-studio - Google 数据工作室仪表板中的图像适用于编辑器,但不适用于查看器
- python - Matplotlib 绘图 y_axis 值不正确
- numpy - Numpy 和 MATLAB 中的索引
- docker - 运行 Node 的 Docker 立即退出,我怎样才能获得访问权限?
- pgmpy - Pgmpy:贝叶斯推理
- seo - seo 组件 gatsby - 影响布局
- powershell - 无法通过 powershell 远程传输超过 278K 的文件
- authentication - 为什么此编码不加载管理仪表板?中间件或身份验证问题?拉拉维尔 8