Chapter 5 Explore Fragment

  1. Add a Fragment

    1. XML to add

      
                
      <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:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="horizontal"
          tools:context=".chapter5.FragmentActivity">
      
          <fragment
              android:id="@+id/leftFragment"
              android:name="com.youngly.firstlineofcode.chapter5.LeftFragment"
              android:layout_width="0dp"
              android:layout_height="match_parent"
              android:layout_weight="1" />
      
          <FrameLayout
              android:id="@+id/right_layout"
              android:layout_width="0dp"
              android:layout_height="match_parent"
              android:layout_weight="2" />
      
      </LinearLayout>
      Copy the code
    2. Dynamically add

      class FragmentActivity : AppCompatActivity() {
          override fun onCreate(savedInstanceState: Bundle?). {
              super.onCreate(savedInstanceState)
              setContentView(R.layout.activity_fragment)
      
              replaceFragment(RightFragment.newInstance())
          }
      
          fun changeFragment(view: View) {
              replaceFragment(AnotherRightFragment.newInstance())
          }
      
          private fun replaceFragment(newInstance: Fragment) {
              val beginTransaction = supportFragmentManager.beginTransaction()
              beginTransaction.replace(R.id.right_layout, newInstance)
              beginTransaction.commit()
          }
      }
      Copy the code
    3. Implementing the return stack

      beginTransaction.addToBackStack(null)
      Copy the code
  2. The life cycle

    1. The callback method

      • onAttach(context: Context): called when a Fragment is associated with an Activity
      • onCreateView(): called when creating a view for the Fragment (loading the layout)
      • onActivityCreated(): is called when the Activity associated with the Fragment has been created
      • onDestoryView(): Called when the view associated with the Fragment is removed
      • onDetach(): called when the Fragment and Activity are disassociated
  3. Dynamic loading layout techniques

    1. Use qualifiers

      The layout-large folder holds the tablet resources

    2. Use the minimum width qualifier

      The shell-width qualifier corresponds to the smallest width in the developer’s options

      The min-width qualifier allows us to specify a minimum (in dp) for the width of the screen, at which point the screen width greater than this will load the layout under this directory.

  4. Best practices

    To achieve an APP, the fruit list page on the mobile phone shows the fruit, and click a fruit to jump to the fruit details page. The fruit list is displayed on the left side of the pad, and details about the selected fruit are displayed on the right side.

    1. Implement two fragments: fruit list Fragment and fruit detail Fragment

      
                
      <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          tools:context=".chapter5.FruitListFragment">
      
          <ListView
              android:id="@+id/fruit_listview"
              android:layout_width="match_parent"
              android:layout_height="match_parent"/>
      
      </FrameLayout>
      Copy the code
      class FruitListFragment : Fragment() {
          private var fruitList = ArrayList<FruitListActivity.Fruit>()
      
          override fun onCreate(savedInstanceState: Bundle?). {
              super.onCreate(savedInstanceState)
              initFruits()
          }
      
          private fun initFruits(a) {
              repeat(20) {
                  fruitList.add(FruitListActivity.Fruit(R.drawable.apple_pic, "Apple"))
                  fruitList.add(FruitListActivity.Fruit(R.drawable.banana_pic, "Banana"))
                  fruitList.add(FruitListActivity.Fruit(R.drawable.orange_pic, "Orange"))
                  fruitList.add(FruitListActivity.Fruit(R.drawable.watermelon_pic, "Watermelon"))
                  fruitList.add(FruitListActivity.Fruit(R.drawable.pear_pic, "Pear"))
                  fruitList.add(FruitListActivity.Fruit(R.drawable.grape_pic, "Grape"))
                  fruitList.add(FruitListActivity.Fruit(R.drawable.pineapple_pic, "PineApple"))
                  fruitList.add(FruitListActivity.Fruit(R.drawable.strawberry_pic, "Strawberry"))
                  fruitList.add(FruitListActivity.Fruit(R.drawable.cherry_pic, "Cherry"))
                  fruitList.add(FruitListActivity.Fruit(R.drawable.mango_pic, "Mango"))}}override fun onCreateView(
              inflater: LayoutInflater, container: ViewGroup? , savedInstanceState:Bundle?).: View? {
              return inflater.inflate(R.layout.fragment_fruit_list, container, false)}override fun onActivityCreated(savedInstanceState: Bundle?). {
              super.onActivityCreated(savedInstanceState) view? .let {val fruitListView = it.findViewById<ListView>(R.id.fruit_listview)
                  fruitListView.adapter =
                      context?.let { it1 -> FruitAdapter(it1, R.layout.fruit_item, fruitList) }
                  fruitListView.setOnItemClickListener { _, _, position, _ ->
                      (context as FruitActivity).showFruit(
                          fruitList[position].imgId,
                          fruitList[position].name
                      )
                  }
              }
          }
      }
      Copy the code
      
                
      <androidx.constraintlayout.widget.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/constraint_layout"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          tools:context=".chapter5.FruitFragment">
      
      
          <ImageView
              android:id="@+id/fruit_img"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_marginTop="268dp"
              android:src="@drawable/apple_pic"
              app:layout_constraintEnd_toEndOf="parent"
              app:layout_constraintHorizontal_bias="0.498"
              app:layout_constraintStart_toStartOf="parent"
              app:layout_constraintTop_toTopOf="parent" />
      
          <TextView
              android:id="@+id/fruit_name"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="TextView"
              app:layout_constraintBottom_toBottomOf="parent"
              app:layout_constraintEnd_toEndOf="parent"
              app:layout_constraintHorizontal_bias="0.498"
              app:layout_constraintStart_toStartOf="parent"
              app:layout_constraintTop_toBottomOf="@+id/fruit_img"
              app:layout_constraintVertical_bias="0.118" />
      </androidx.constraintlayout.widget.ConstraintLayout>
      Copy the code
      class FruitFragment : Fragment() {
      
          override fun onCreateView(
              inflater: LayoutInflater, container: ViewGroup? , savedInstanceState:Bundle?).: View? {
              return inflater.inflate(R.layout.fragment_fruit, container, false)}fun refreshView(resourceId: Int, name: String){ view? .apply { findViewById<ImageView>(R.id.fruit_img).setImageResource(resourceId) findViewById<TextView>(R.id.fruit_name).text = name } } }Copy the code
    2. To implement the Activity

      1. Mobile phone layout

        <androidx.constraintlayout.widget.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:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".chapter5.FruitActivity">
        
            <fragment
                android:id="@+id/chat_history"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:name="com.youngly.firstlineofcode.chapter5.FruitListFragment"/>
        
        </androidx.constraintlayout.widget.ConstraintLayout>
        Copy the code
      2. Flat layout

        
                    
        <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:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="horizontal"
            tools:context=".chapter5.FruitActivity">
        
            <fragment
                android:id="@+id/fruit_list_fragment"
                android:name="com.youngly.firstlineofcode.chapter5.FruitListFragment"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1" />
        
            <fragment
                android:id="@+id/fruit_fragment"
                android:name="com.youngly.firstlineofcode.chapter5.FruitFragment"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="2" />
        
        </LinearLayout>
        Copy the code
      3. The Activity code

        class FruitActivity : AppCompatActivity() {
            private var mIsLarge: Boolean = false
            override fun onCreate(savedInstanceState: Bundle?). {
                super.onCreate(savedInstanceState)
                setContentView(R.layout.activity_fruit)
        
              	// Check whether the tablet exists by checking whether the Fragment exists on the right sidemIsLarge = supportFragmentManager.findFragmentById(R.id.fruit_fragment) ! =null
            }
        
            fun showFruit(resourceId: Int, name: String) {
                if (mIsLarge) {
                    (supportFragmentManager.findFragmentById(R.id.fruit_fragment) as FruitFragment).refreshView(resourceId, name)
                } else {
                    val intent = Intent(this, FruitDetailActivity::class.java)
                    intent.putExtra("resourceId", resourceId)
                    intent.putExtra("name", name)
                    startActivity(intent)
                }
            }
        }
        Copy the code
  5. Kotlin classroom

    1. Extension function

      Requirement: Count the number of letters in the string

      1. Util class in Java, define the function to get the number of letters

      2. Extension functions in Kotlin

        Because you want to add an extension function to the String class, create a string.kt file

        fun String.letterCount(a): Int {
            var count = 0
            for (char in this) {
                if (char.isLetter())
                    count++
            }
            return count
        }
        Copy the code
    2. Operator overloading

      Operator overloading uses the operator keyword

      The + operator corresponds to the plus() function

      The following example is the sum of different currencies to get the same currency

      1. Define the parent class

        /** * Creater: yanglei * Date: 2021/7/2 PM 11:59 * Desc: * rate: exchange rate */
        open class Money(var value: Float.var rate: Float) {
        
            var symbol: String = ""
        
            operator fun plus(money: Money): Money {
                val newMoney = this: :class.java.newInstance()
                this: :class.java.superclass.getDeclaredField("value").set(newMoney, this.value + money.value * (money.rate / this.rate))
                this: :class.java.superclass.getDeclaredField("rate").set(newMoney, this.rate)
                newMoney.symbol = this.symbol
                return newMoney
            }
        
            override fun toString(a): String {
                return "${this::class.java.simpleName}($symbol $value)"}}Copy the code
      2. Definition of personal currency (exchange rate based on RMB)

        class RMB(value: Float, rate: Float) : Money(value, rate) {
        
            constructor() : this(0f.0f)
        
            init {
                symbol = "Selections"}}Copy the code
      3. Define the dollar

        class Dollar(value: Float, rate: Float) : Money(value, rate) {
            constructor() : this(0f.0f)
        
            init {
                symbol = "$"}}Copy the code
      4. test

        fun main(a) {
            val fl = RMB(7f.1f) + Dollar(1f.7f)
            println(fl)
        
            val money = Dollar(1f.7f) + RMB(7f.1f)
            println(money)
        }
        Copy the code
      5. The output

        RMB (14.0) selections Dollar ($2.0)