Search code examples
androidandroid-studioandroid-fragmentskotlinandroid-viewpager

how can i add button Fragments,ViewPager using kotlin


I want to add a button (id='Home') which take me to the main activity i use those codes but it is not reacting, this is a sample of my project in GITHUB please check it from HERE ( the problem has been fixed by @advice-dog , it has been added to the this project)

in layout of the ViewPager I have :

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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/bg2"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:theme="@style/AppFullScreenTheme"
    tools:context=".License">


    <android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="visible"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

in there class I have:

package com.medanis.fneclis


import android.content.Intent
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.v4.view.ViewPager
import kotlinx.android.synthetic.main.activity_license.*


class License : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_license)
        val viewPager = findViewById<ViewPager>(R.id.view_pager)
        viewPager.adapter = CustomPagerAdapter(this)

    }
}

in the first PAGE of the ViewPager where I have the button Home:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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/l1_bg"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/fneclis_l1_bg"
    tools:context=".AllButtons">


    <Button
        android:id="@+id/Home"
        android:layout_width="56dp"
        android:layout_height="53dp"
        android:layout_marginBottom="523dp"
        android:layout_marginEnd="312dp"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="312dp"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:background="@drawable/ic_home_black_24dp"
        android:contentDescription="@string/todo"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

which is related to the class AllButtons (I want to use it in the most pages of the ViewPage but not all of them):

package com.medanis.fneclis

import android.content.Intent 
import android.os.Bundle 
import android.support.v7.app.AppCompatActivity 
import kotlinx.android.synthetic.main.activity_l1_page.*

class AllButtons: AppCompatActivity() {

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

// those are some other pages which contains the same button and they are inside the ViewPager
           /* setContentView(R.layout.activity_l2_page)
            setContentView(R.layout.activity_l3_page)
            setContentView(R.layout.activity_m1page)
            setContentView(R.layout.activity_m2page)*/

        Home.setOnClickListener{
            val intent = Intent(this, MainActivity::class.java)
            startActivity(intent)
        }
    } }

THe ADAPTER :

package com.medanis.fneclis

import android.app.Activity
import android.content.Context
import android.support.v4.view.PagerAdapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup

class CustomPagerAdapter(private val mContext: Context) : PagerAdapter() {

    override fun instantiateItem(collection: ViewGroup, position: Int): Any {
        val modelObject = ModelObject.values()[position]
        val inflater = LayoutInflater.from(mContext)
        val viewGroup = inflater.inflate(modelObject.titleResId, collection, false) as ViewGroup
        collection.addView(viewGroup)
        return viewGroup
    }

    override fun destroyItem(collection: ViewGroup, position: Int, view: Any) {
        collection.removeView(view as View)
    }

    override fun getCount(): Int {
        return ModelObject.values().size
    }

    override fun isViewFromObject(view: View, `object`: Any): Boolean {

        return view === `object`
    }

    override fun getPageTitle(position: Int): CharSequence {
        val customPagerEnum = ModelObject.values()[position]
        return mContext.getString(customPagerEnum.titleResId)
    }

    override fun getItemPosition(`object`: Any): Int {
        return super.getItemPosition(`object`)
    }
}

ModelObject :

package com.medanis.fneclis

enum class ModelObject private constructor(val titleResId: Int ) {

    LICENSEONE(R.layout.activity_l1_page),
    PAGEONE(R.layout.activity_l1s1page),
    PAGETWO(R.layout.activity_l1s2page),

    LICENSETWO(R.layout.activity_l2_page),
    PAGETHREE(R.layout.activity_l2_s3page),
    PAGEFOUR(R.layout.activity_l2_s4page),

    LICENSETHREE(R.layout.activity_l3_page),
    PAGEFIVE(R.layout.activity_l3_s5page),
    PAGESIX(R.layout.activity_l3_s6page),

}

Solution

  • I rewrote your code a bit, I'll explain some tips and suggestions on how to improve.

    First, always add Actvitiy or Fragment to the end of your Activities or Fragments, this will help make things a lot easier to understand.

    class LicenseActivity : AppCompatActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_license)
    
            // You can simply use the id of the View here.
            view_pager.adapter = CustomPagerAdapter(supportFragmentManager)
        }
    }
    

    Next, I changed your AllButtons Activity into a Fragment.

    This code is a bit more complex, but it's using a very common pattern, the newInstance pattern. To create a new Fragment, you want to make a static method that will return a Fragment with your values passed into the arguments.

    So, to explain it a bit more. You make a function called newInstance that takes the information this Fragment should be aware of, in this case, the layout we want it to show.

    Next, you create a Bundle, and put the layout into it.

    And then lastly you assign your Fragment's arguments to the Bundle.

    This is the safest way to create Fragments.

    class AllButtonsFragment : Fragment() {
    
        companion object {
            private const val EXTRA_COLOR = "EXTRA_COLOR"
            private const val EXTRA_LAYOUT = "EXTRA_LAYOUT"
    
            fun newInstance(modelObject: ModelObject): Fragment {
                val fragment = AllButtonsFragment()
    
                // Creating a Bundle with the various values we want to pass, such as the color and layout.
                val bundle = Bundle()
                bundle.putInt(EXTRA_COLOR, modelObject.titleResId)
                bundle.putInt(EXTRA_LAYOUT, modelObject.layoutResId)
                fragment.arguments = bundle
    
                return fragment
            }
        }
    
        // Getting the layout from the arguments to inflate the View.
        override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
            val layout = arguments?.getInt(EXTRA_LAYOUT)
                    ?: throw IllegalStateException("arguments does not contain a layout.")
            return inflater.inflate(layout, container, false)
        }
    
        override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
    
            val color = arguments?.getInt(EXTRA_COLOR)
            // TODO: Do whatever with your colour.
    
            // Using findViewById since this isn't on every layout.
            view?.findViewById<View>(R.id.Home)?.setOnClickListener {
                val intent = Intent(context, MainActivity::class.java)
                startActivity(intent)
            }
        }
    }
    

    Next, I rewrote your Adapter to work with Fragments. This will just get the position of the page, pass it to our newInstance function, and get a Fragment for you.

    class CustomPagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) {
    
        override fun getItem(position: Int): Fragment {
            val modelObject = ModelObject.values()[position]
            // Creating a new instance of our Fragment with this Model Object.
            return AllButtonsFragment.newInstance(modelObject)
        }
    
        override fun getCount() = ModelObject.values().size
    }