23 August 2015

AppCompatDelegate สำหรับการทำ Activity ใดๆให้รองรับ AppCompat

Updated on


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

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


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

ทำยังไงล่ะ?

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



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

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

public class AppCompatSlidingActivity extends SlidingActivity {
    
}

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

public class AppCompatSlidingActivity extends SlidingActivity {
    private AppCompatDelegate mDelegate;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        getDelegate().installViewFactory();
        getDelegate().onCreate(savedInstanceState);
        super.onCreate(savedInstanceState);
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        getDelegate().onPostCreate(savedInstanceState);
    }

    public ActionBar getSupportActionBar() {
        return getDelegate().getSupportActionBar();
    }

    public void setSupportActionBar(@Nullable Toolbar toolbar) {
        getDelegate().setSupportActionBar(toolbar);
    }

    @Override
    public MenuInflater getMenuInflater() {
        return getDelegate().getMenuInflater();
    }

    @Override
    public void setContentView(@LayoutRes int layoutResID) {
        getDelegate().setContentView(layoutResID);
    }

    @Override
    public void setContentView(View view) {
        getDelegate().setContentView(view);
    }

    @Override
    public void setContentView(View view, ViewGroup.LayoutParams params) {
        getDelegate().setContentView(view, params);
    }

    @Override
    public void addContentView(View view, ViewGroup.LayoutParams params) {
        getDelegate().addContentView(view, params);
    }

    @Override
    protected void onPostResume() {
        super.onPostResume();
        getDelegate().onPostResume();
    }

    @Override
    protected void onTitleChanged(CharSequence title, int color) {
        super.onTitleChanged(title, color);
        getDelegate().setTitle(title);
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        getDelegate().onConfigurationChanged(newConfig);
    }

    @Override
    protected void onStop() {
        super.onStop();
        getDelegate().onStop();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        getDelegate().onDestroy();
    }

    public void invalidateOptionsMenu() {
        getDelegate().invalidateOptionsMenu();
    }

    private AppCompatDelegate getDelegate() {
        if (mDelegate == null) {
            mDelegate = AppCompatDelegate.create(this, null);
        }
        return mDelegate;
    }
}

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

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

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

public class MainActivity extends AppCompatSlidingActivity {
    private Button btnConfirm;
    private ToggleButton tbAvailable;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnConfirm = (Button) findViewById(R.id.btn_confirm);
        tbAvailable = (ToggleButton) findViewById(R.id.tb_available);
    }
}

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



สรุป

        วิธีนี้ใช้แนวคิดของการ Implement Delegate จ๊ะ