ผู้ที่หลงเข้ามาอ่านหลายๆคนคงจะรู้จักกับ AppCompatActivity กันบ้างแล้ว เพราะว่าในตอนนี้มันถูกประกาศไว้ให้อัตโนมัติในเวลาที่สร้างโปรเจคแอนดรอยด์ขึ้นมาใหม่ ซึ่งเจ้า AppCompat นี้เข้ามาเสริมการทำงานของ Material Design Theme, Action Bar, Dialog และ ShareActionProvider ที่จะช่วยให้ลูกเล่นใหม่ๆเหล่านี้รองรับบนแอนดรอยด์เวอร์ชันเก่าๆด้วย เพียงแค่ Activity นั้นๆจะต้องประกาศใช้งาน AppCompatActivity ด้วย ถึงจะรองรับ

แต่ถ้าโปรเจคของผู้ที่หลงเข้ามาอ่านใช้งานจาก Activity ของ Library ตัวหนึ่ง แต่ว่า Activity ตัวนั้นๆไม่ได้รองรับ AppCompat (ไม่ได้ Extend จาก AppCompatActivity) แล้วจะเรียกใช้ AppCompat ได้อย่างไรล่ะ? นั่นล่ะ

เพื่อแก้ปัญหาดังกล่าว จึงต้องใช้ AppCompatDelegate เข้าช่วยให้ Activity นั้นๆรองรับ AppCompat

ทำยังไงล่ะ?

หลักการง่ายๆก็คือสร้าง Activity มา แล้วใส่คำสั่งของ AppCompatDelegate ในนั้น แล้วเอา Activity ตัวนั้นๆไปใช้งานแทน

ต้องทำยังไงนะ?

ยกตัวอย่างว่าเจ้าของบล็อกมี SlidingActivity ที่อยากจะให้มันรองรับ AppCompat นะ ดังนั้นเจ้าของบล็อกก็จะต้องสร้าง Activity ขึ้นมาก่อน เพื่อทำให้ SlidingActivity รองรับ AppCompat โดยสร้างขึ้นมาใหม่ในชื่อว่า AppCompatSlidingActivity (ตั้งชื่อแบบบ้านๆ)

open class AppCompatSlidingActivity : SlidingActivity() { ... }

จากนั้นก็เพิ่มคำสั่งของ AppCompatDelegate เข้าไปดังนี้

open class AppCompatSlidingActivity : SlidingActivity() {
    private val delegate: AppCompatDelegate by lazy { AppCompatDelegate.create(this, null) }

    override fun onCreate(savedInstanceState: Bundle?) {
        delegate.installViewFactory()
        delegate.onCreate(savedInstanceState)
        super.onCreate(savedInstanceState)
    }

    override fun onPostCreate(savedInstanceState: Bundle?) {
        super.onPostCreate(savedInstanceState)
        delegate.onPostCreate(savedInstanceState)
    }

    override fun getSupportActionBar(): ActionBar? {
        return delegate.supportActionBar
    }

    override fun setSupportActionBar(toolbar: Toolbar?) {
        delegate.setSupportActionBar(toolbar)
    }

    override fun getMenuInflater(): MenuInflater {
        return delegate.menuInflater
    }

    override fun setContentView(@LayoutRes layoutResID: Int) {
        delegate.setContentView(layoutResID)
    }

    override fun setContentView(view: View) {
        delegate.setContentView(view)
    }

    override fun setContentView(view: View, params: ViewGroup.LayoutParams) {
        delegate.setContentView(view, params)
    }

    override fun addContentView(view: View, params: ViewGroup.LayoutParams) {
        delegate.addContentView(view, params)
    }

    override fun onPostResume() {
        super.onPostResume()
        delegate.onPostResume()
    }

    override fun onTitleChanged(title: CharSequence, color: Int) {
        super.onTitleChanged(title, color)
        delegate.setTitle(title)
    }

    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        delegate.onConfigurationChanged(newConfig)
    }

    override fun onStop() {
        super.onStop()
        delegate.onStop()
    }

    override fun onDestroy() {
        super.onDestroy()
        delegate.onDestroy()
    }

    override fun invalidateOptionsMenu() {
        delegate.invalidateOptionsMenu()
    }
}

เท่านี้ก็เป็นอันเสร็จเรียบร้อย~

เอาไปใช้งานได้เลย

เมื่อทำเสร็จแล้วก็เอา Activity ที่สร้างขึ้นเมื่อครู่นี้ไปใช้งานแทนตัวเก่า

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

จากนั้นก็สามารถเรียกคำสั่งต่างๆของ AppCompat ได้เลย

สรุป

วิธีนี้ใช้ Delegate Pattern จ้ะ