首页 > 解决方案 > 为什么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)
        }
    }

标签: androidkotlin

解决方案


您可以在活动中创建进度条而不是片段,然后从两个片段访问进度条。通过这样做,您将不会面临错误。


推荐阅读