Git Product home page Git Product logo

androidcustomfragmentmanager's Introduction

API Android-Studio Language

Android Custom Fragment Manager

It is an architectural infrastructure that establishes a relationship between activity and fragment in android, and also provides transitions and management between fragments.

  • Existing fragment initialization according to fragment type
  • Switching between fragments by command type
  • Base class that runs and organizes the whole process: MyFragmentManager.kt
  • Custom backstack management
  • Interface for fragment interaction

Introduction

First of all, view binding, which is recommended by Google, was used in the project.

In the build.gradle file, it is stated that we will use view binding.

buildFeatures {
    viewBinding true
}

Binding is done in Activity and Fragment files

private lateinit var binding: ActivityMainBinding

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityMainBinding.inflate(layoutInflater)
    val view = binding.root
    setContentView(view)
}

Usage

The application starts with MainActivity. It is used to hold frame layout fragments in activity_main.xml.
All fragments must implement the MyFragment class.
Types of all fragments are specified with enum class.
OnFragmentInteractionListener interface is used to switch between fragments.

When the application is first opened, it starts with MainActivity. The first fragment is displayed by calling the initFragment method under OnCreate. The initFragment method sets the current fragment using the myFragmentManager base class.

private lateinit var binding: ActivityMainBinding

private val myFragmentManager = MyFragmentManager(this, supportFragmentManager)

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityMainBinding.inflate(layoutInflater)
    val view = binding.root
    setContentView(view)

    initFragment()
}

private fun initFragment(){
    myFragmentManager.setCurrentFragmentType(MyFragmentType.HOME_FRAGMENT, null, false)
}

The fragment manager determines the current fragment with the setCurrentFragmentType method.

fun setCurrentFragmentType(fragmentType: MyFragmentType, arguments: Bundle?, addToBackStack: Boolean) {

  if (currentFragment?.fragmentType === fragmentType) return

  if (!addToBackStack) clearBackStack()

  currentFragment = when (fragmentType) {
      MyFragmentType.MY_FRAGMENT_TYPE_A -> FragmentA()
      MyFragmentType.MY_FRAGMENT_TYPE_B -> FragmentB()
      MyFragmentType.HOME_FRAGMENT -> HomeFragment()
  }

  currentFragment?.arguments = arguments

  if (addToBackStack){
      myFragmentStack.add(currentFragment)
  }else{
      baseFragment = currentFragment
  }

  val fragmentTransaction = fragmentManager.beginTransaction()
  if (addToBackStack){
      fragmentTransaction.replace(R.id.activity_main_fragment_container, currentFragment as Fragment)
          .addToBackStack(fragmentType.toString())
  }else{
      fragmentTransaction.replace(R.id.activity_main_fragment_container, currentFragment as Fragment)
  }


  try {
      fragmentTransaction.commit()
  }catch (e: Exception){
      e.printStackTrace()
  }

}

The setCurrentFragmentType method takes an argument of type MyFragmentType in order to traverse the fragment. In addition, if we want to send an argument (Bundle) while switching between fragments, we accept it as a parameter and if we want to add the relevant fragment to bacstack, we need to send the addToBackStack parameter as true.

currentFragment and baseFragment are objects of type MyFragment. myFragmentStack is a Stack structure containing MyFragment.

private var currentFragment: MyFragment? = null
private var baseFragment: MyFragment? = null

private val myFragmentStack = Stack<MyFragment>()

myFragment is the class that determines the structure of all fragments.

abstract class MyFragment : Fragment() {

  abstract val fragmentType: MyFragmentType

}

Every fragment must have a type. The setCurrentFragmentType method determines the current fragment according to this type. The type here is specified with the enum class. There should be as many types as the number of fragments.

enum class MyFragmentType {
  HOME_FRAGMENT,
  MY_FRAGMENT_TYPE_A,
  MY_FRAGMENT_TYPE_B
}

The scenario for displaying homeFragment is as above. Since the addToBackStack parameter is false in the initFragment, the homeFragment is not added to the backstack and the application exits when the back button is pressed.

Thanks to the buttons in homeFragment, transitions can be made between fragments. The OnFragmentInteraction interface runs the setCurrentFragmentType method in the fragment manager according to the command type.

private var mListener: OnFragmentInteractionListener? = null

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    val isUserPushed = arguments?.get("isUserPushedScreen")
    Log.e("TEST", "Fragment Home isUserPushed: ${isUserPushed}")

    binding.homeFragmentGotoFragmentA.setOnClickListener {
        mListener?.onFragmentInteraction(MyFragmentCommand.GO_TO_FRAGMENT_A, null, true)
    }

    binding.homeFragmentGotoFragmentB.setOnClickListener {
        mListener?.onFragmentInteraction(MyFragmentCommand.GO_TO_FRAGMENT_B, null, true)
    }
}

When the listener is triggered, the onFragmentInteraction method in MainActivity is called and fragment passage is provided.

override fun onFragmentInteraction(command: MyFragmentCommand, argumentData: Bundle?, addToBackStack: Boolean) {
  var argBundle: Bundle? = argumentData
  if (argBundle == null){
      argBundle = Bundle()
  }

  //default arguments
  argBundle.putBoolean("isUserPushedScreen", true)

  when(command){
      MyFragmentCommand.GO_TO_FRAGMENT_A -> {
          myFragmentManager.setCurrentFragmentType(MyFragmentType.MY_FRAGMENT_TYPE_A, argBundle, addToBackStack)
      }
      MyFragmentCommand.GO_TO_FRAGMENT_B -> {
          myFragmentManager.setCurrentFragmentType(MyFragmentType.MY_FRAGMENT_TYPE_B, argBundle, addToBackStack)
      }
  }
}

androidcustomfragmentmanager's People

Contributors

ayhanunal avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.