Quantcast
Channel: Yudiz Solutions Ltd.
Viewing all articles
Browse latest Browse all 595

Kotlin : Android’s future is here – Part 7

$
0
0

Overview

Tab Layout

This blog is about implementing tab layout in Android using Kotlin.

Tab Layout with view pager

Including tab layout & view pager in xml

<LinearLayout 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/activity_main"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:orientation="vertical"
   tools:context="com.MainActivity">

   <android.support.v7.widget.Toolbar
       android:id="@+id/toolBar"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:background="@color/colorPrimary" />

   <android.support.design.widget.TabLayout
       android:id="@+id/tabLayout"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       app:tabMode="fixed" />

   <android.support.v4.view.ViewPager
       android:id="@+id/viewPager"
       android:layout_width="match_parent"
       android:layout_height="match_parent" />

</LinearLayout>

Create the fragments that you want to display inside the view pager when tab is selected

Here, we will display different colored background for each fragment in view pager.
I’ll show one fragment here, for instance.

XML file:-

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:background="@color/colorAccent"
   android:orientation="vertical">

   <FrameLayout
       android:id="@+id/frag1_frame"
       android:layout_width="match_parent"
       android:layout_height="match_parent" />
</LinearLayout>

Kotlin file:-

class Frag1 : android.support.v4.app.Fragment() {

   override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
       val view = inflater!!.inflate(R.layout.frag1_layout, container, false)
       return view
   }
}

Implementing FragmentStatePager Adapter

class ViewPagerAdapter(fm: FragmentManager) : FragmentPagerAdapter(fm) {

   private val fragments = ArrayList<Fragment>()
   private val tabNames = ArrayList<String>()

   fun addFragmentTabName(fragment: Fragment, tabName: String) {

       fragments.add(fragment)
       tabNames.add(tabName)

   }

   override fun getItem(position: Int): Fragment {
       return fragments[position]
   }

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

   override fun getPageTitle(position: Int): CharSequence {            
       return tabNames[position]
   }
}

Here, I have used 2 arrayLists; one for storing fragments and 1 for storing names of tabs.

To display names of tabs on tab selection, getPageTitle( ) method is overridden in adapter and it returns name of the tab at selected position.

To display fragment on tab selection, getItem( ) method is overridden in adapter which returns the fragment at selected position.

Code in MainActivity.kt

class MainActivity : AppCompatActivity() {

   private var viewPagerAdapter: ViewPagerAdapter? = null

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

       init()

       viewPager!!.offscreenPageLimit = 3         //upto 3 off screen pages will not get destroyed. default is 1
       setSupportActionBar(toolBar)
       passFragmentsIntoAdapter()
       setAdapter()
       setIconsInTabLayout()
   }

   internal fun init() {
       viewPagerAdapter = ViewPagerAdapter(supportFragmentManager)

   }

   internal fun passFragmentsIntoAdapter() {            
       viewPagerAdapter!!.addFragmentTabName(Frag1(), "Frag1")
       viewPagerAdapter!!.addFragmentTabName(Frag2(), "Frag2")
       viewPagerAdapter!!.addFragmentTabName(Frag3(), "Frag3")
   }

   internal fun setAdapter() {
       viewPager!!.adapter = viewPagerAdapter
       tabLayout!!.setupWithViewPager(viewPager)
   }

   internal fun setIconsInTabLayout() {         //should be called after setting adapter and tab layout
       //tab titles can also be set here using setText
       tabLayout!!.getTabAt(0)!!.setIcon(R.mipmap.ic_launcher)
       tabLayout!!.getTabAt(1)!!.setIcon(R.mipmap.ic_launcher)
       tabLayout!!.getTabAt(2)!!.setIcon(R.mipmap.ic_launcher)
   }

}

Tab Layout without view pager

Including tab layout & a frame layout in xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:id="@+id/activity_main"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:orientation="vertical"
   tools:context="com.MainActivity">

   <android.support.design.widget.TabLayout
       android:id="@+id/actMain_tabLayout"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:background="#336699" />

   <FrameLayout
       android:id="@+id/actMain_frame"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:layout_weight="1" />
</LinearLayout>

Create the fragments that you want to display when tab is selected

Here, we will display different colored background for each fragment.
I’ll show one fragment here, for instance.

XML file:-

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:background="@color/colorAccent"
   android:orientation="vertical">

   <FrameLayout
       android:id="@+id/frag1_frame"
       android:layout_width="match_parent"
       android:layout_height="match_parent" />
</LinearLayout>

Kotlin file:-

class Frag1 : android.support.v4.app.Fragment() {

   override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
       val view = inflater!!.inflate(R.layout.frag1_layout, container, false)
       return view
   }
}

Code in MainActivity.kt

class MainActivity : AppCompatActivity() {
   private var fragmentTransaction: FragmentTransaction? = null

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

       addFirstFrag()
       designTabLayout()

       actMain_tabLayout!!.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {

override fun onTabSelected(tab: TabLayout.Tab?) {            setCurrentTabFragment(actMain_tabLayout!!.getSelectedTabPosition())
}
           override fun onTabUnselected(tab:TabLayout.Tab?){            
}
      override fun onTabReselected(tab:TabLayout.Tab?) {
}
})

}

   internal fun addFirstFrag() {
       fragmentTransaction = fragmentManager!!.beginTransaction()

       fragmentTransaction!!.replace(R.id.actMain_frame, Frag1())
       fragmentTransaction!!.addToBackStack("")
       fragmentTransaction!!.commit()
   }

   internal fun designTabLayout() {
      actMain_tabLayout!!.addTab(actMain_tabLayout!!.newTab().setIcon(R.mipmap.ic_launcher).setText("1"))
       actMain_tabLayout!!.addTab(actMain_tabLayout!!.newTab().setIcon(R.mipmap.ic_launcher).setText("2"))
       actMain_tabLayout!!.addTab(actMain_tabLayout!!.newTab().setIcon(R.mipmap.ic_launcher).setText("3"))

   }

   internal fun addFrag(fragment: Fragment) {
       fragmentTransaction = fragmentManager!!.beginTransaction()

       fragmentTransaction!!.replace(R.id.actMain_frame, fragment)
       fragmentTransaction!!.addToBackStack("")
       fragmentTransaction!!.commit()
   }

   internal fun setCurrentTabFragment(pos: Int) {
       when (pos) {
           0 ->
               addFrag(Frag1())
           1 ->
               addFrag(Frag2())
           2 ->
               addFrag(Frag3())
       }
   }
}

First, we have to design the tab layout before loading fragments in frame layout i.e. setting icon and text for each tab.

Then, I have loaded 1st fragment in the frame layout.

Finally, I have used addOnTabSelectedListener( ) to detect the selected tab and then on selection of the tab, I have loaded the respective fragment in the frame.

Conclusion

Tab layouts are in fashion now-a-days. We see them in facebook, whatsapp and other such giant apps. Hence, it is a good idea to learn to code tab layouts in Kotlin because it will be a must requirement in future projects.


Viewing all articles
Browse latest Browse all 595

Trending Articles