K
K
Kogoth2018-05-12 18:51:25
Android
Kogoth, 2018-05-12 18:51:25

How to access ViewPager from dynamically assigned Fragment?

There is fragment_shop.xml:

spoiler
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".FunBoxStore">

    <android.support.v4.view.ViewPager
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

</android.support.design.widget.CoordinatorLayout>

The Shop_fragment.kt class has been created for it:
spoiler
class Shop_fragment : Fragment() {
    val TAG = "Shop"
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_shop, null)
    }
}

There is also the main window activity_fun_box_store.xml where the buttons should change fragments:
spoiler
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".FunBoxStore">

    <LinearLayout
        android:id="@+id/active_fragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:layout_above="@id/switch_for_fragment" />

    <LinearLayout
        android:id="@+id/switch_for_fragment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_alignParentBottom="true">

        <Button
            android:id="@+id/shop_btn"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@string/shop_btn" />

        <Button
            android:id="@+id/store_btn"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@string/store_btn" />

    </LinearLayout>
</RelativeLayout>

And finally the source code:
spoiler
class FunBoxStore : AppCompatActivity() {

    private val shop_fragment: Shop_fragment = Shop_fragment()
    private val store_fragment: Store_fragment = Store_fragment()
    private var manager: FragmentManager? = null
    private var transaction: FragmentTransaction? = null
    private var mSectionsPagerAdapter: SectionsPagerAdapter? = null
    private val products = ArrayList<Product>()
    private val products_showed = ArrayList<Product>()
    private val blank_product = Product("Товаров больше нет",0f,0)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_fun_box_store)

        manager=supportFragmentManager
        transaction = manager?.beginTransaction()
        transaction?.add(R.id.active_fragment,shop_fragment,shop_fragment.TAG)
        transaction?.commit()

        shop_btn.setOnClickListener{
            transaction = manager?.beginTransaction()
            transaction?.replace(R.id.active_fragment,shop_fragment,shop_fragment.TAG)
            transaction?.commit()
        }

        mSectionsPagerAdapter = SectionsPagerAdapter(supportFragmentManager)

        //Попытка установить adapter через findViewById

        //val viewPager = findViewById<ViewPager>(R.id.container)
        //viewPager.adapter = mSectionsPagerAdapter

        //Попытка установить adapter через findFragmentByTag (в if не входит без него виснет)

        /*if(manager?.findFragmentByTag(shop_fragment.TAG) is Shop_fragment){
            (manager?.findFragmentByTag(shop_fragment.TAG) as Shop_fragment).container.adapter = mSectionsPagerAdapter
            Log.d("myLogs", "нашелся")
        }*/

        //Попытка установить adapter через прямое обращение к экземпляру класса

        //shop_fragment.container.adapter = mSectionsPagerAdapter

        //Способ напрямую без фрагментов работает если ViewPager разместить на activity_fun_box_store.xml

        //container.adapter = mSectionsPagerAdapter

        products.add(Product("Apple iPod touch 5 32Gb", 8888f, 5))
        products.add(Product("Samsung Galaxy S Duos S7562", 7230f, 5))
        products.add(Product("Canon EOS 600D Kit", 15659f, 0))

        for (product in products) {
            if (product.merch_amt>0) {
                products_showed.add(product)
            }
        }

        //Попытка обратиться к adapter через findViewById

        //viewPager.adapter?.notifyDataSetChanged()

        //Попытка обратиться к adapter через findFragmentByTag (в if не входит без него виснет)

        /*if(manager?.findFragmentByTag(shop_fragment.TAG) is Shop_fragment){
            (manager?.findFragmentByTag(shop_fragment.TAG) as Shop_fragment).container.adapter?.notifyDataSetChanged()
            Log.d("myLogs", "нашелся")
        }*/

        //Попытка обратиться к adapter через прямое обращение к экземпляру класса

        //shop_fragment.container.adapter?.notifyDataSetChanged()

        //Способ напрямую без фрагментов работает если ViewPager разместить на activity_fun_box_store.xml

        //container.adapter = mSectionsPagerAdapter
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        // Inflate the menu; this adds items to the action bar if it is present.
        menuInflater.inflate(R.menu.menu_fun_box_store, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        val id = item.itemId
        if (id == R.id.action_settings) {
            return true
        }
        return super.onOptionsItemSelected(item)
    }

    inner class SectionsPagerAdapter(fm: FragmentManager) : FragmentPagerAdapter(fm) {

        override fun getItem(position: Int): Fragment {
            return if (products_showed.size > 0) {
                PlaceholderFragment.newInstance(position + 1, products_showed[position])
            }else{
                PlaceholderFragment.newInstance(position+1,blank_product)
            }
        }

        override fun getCount(): Int {
            Log.d("myLogs", "fuck"+products_showed.size.toString())
            return if (products_showed.size > 0) {
                products_showed.size
            }else{
                1
            }
        }
    }

    class PlaceholderFragment : Fragment() {

        override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                                  savedInstanceState: Bundle?): View? {
            val rootView = inflater.inflate(R.layout.fragment_fun_box_store, container, false)
            rootView.name.text =  arguments?.getString("MERCH_NAME")
            rootView.price.text =  arguments?.getFloat("MERCH_PRICE").toString()
            rootView.amt.text =  arguments?.getInt("MERCH_AMT").toString()
                    //getString(R.string.section_format, arguments?.getInt(ARG_SECTION_NUMBER))
            return rootView
        }

        companion object {

            private val ARG_SECTION_NUMBER = "section_number"

            fun newInstance(sectionNumber: Int, product:Product): PlaceholderFragment {
                val fragment = PlaceholderFragment()
                val args = Bundle()
                args.putInt(ARG_SECTION_NUMBER, sectionNumber)
                args.putString("MERCH_NAME",product.merch_name)
                args.putFloat("MERCH_PRICE",product.merch_price)
                args.putInt("MERCH_AMT",product.merch_amt)
                fragment.arguments = args
                return fragment
            }
        }
    }
}

Well, the actual question is how to access the ViewPager with android:id="@+id/container" which was created in the private val shop_fragment: Shop_fragment = Shop_fragment() from inflater.inflate(R.layout.fragment_shop, null) and assigned to active_fragment using transaction?.add(R.id.active_fragment,shop_fragment,shop_fragment.TAG)???

Answer the question

In order to leave comments, you need to log in

2 answer(s)
K
Kogoth, 2018-05-12
@Kogoth

BOOO MY!! GIVE ME THE HAMMER AND THE HEAD OF THE ONE WHO DID THIS!!!!!!!
It turns out transaction?.commit() is not executed immediately!!!! this creature can work quickly, or maybe xs how long to wait! As a result, in order to guarantee access to the elements of the fragment, you must first execute manager?.executePendingTransactions() to forcefully commit the transaction! It just goes against the very meaning of transactions!!! AAA
------------------------------------------------- -------------------------------------------------- ----------------------------------------
A million years have passed... I realized that the transaction is in progress in a separate thread, and all access to the elements of the fragment must be done in its own onCreate () method. ))))

D
Denis Zagaevsky, 2018-05-12
@zagayevskiy

Firstly, the fragment must be a thing in itself, no one should know what views it has inside, it encapsulates them in itself.
Secondly, when the fragment is created, it doesn't mean anything yet. Its entire life cycle begins only after being added to the fragment manager. Accordingly, views can only be accessed after onCreateView has been executed. And to do this, as I said above, follows only from the fragment itself.
I can't say anything about this. Correct the comments above, read Android developers about fragments and their usage, and the problem will most likely disappear.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question