RxJava-RxAndroid

Tại sao lại là RxJava?

Như hầu hết các bài viết trên Internet, có một ví dụ đơn giản về sử dụng AsyncTask.

Khi sử cài đặt AsyncTask handle một tác vụ ngầm, method doInBackground sẽ chạy trên một thread khác UI thread(main thread), sau khi đó sẽ trả kết quả về onPostExcute(), method này chạy trên UI thread. Vấn dề là khi chạy hàm onPostExcute gắn liền với context, khi app bị kill thì AsyncTask vẫn còn gắn reference với context, dễ xảy ra tình trọng memory leak hoặc null pointer(ez hiểu =))).

Nó khá là giống observer pattern, nhưng có sự khác biệt với Observables.

Thành phần chủ yếu của RJ là Observable và Observer(Subscriber). Observable phát ra item, còn Observer sử dụng những item đó. Với mỗi Observer sẽ có 3 phương thức cài đặt sẵn tương ứng:

+ onNext(): gọi mỗi khi Observable phát ra item

+ onComplete(): khi Observable hoàn thành việc phát ra mọi item.

+ onError(): khi Observable gặp lỗi.

Một Observable có thể tạo ra một hoặc nhiều item. Subscriber là một implement của Observer. Observer là một object có thể lấy data từ data source( một Observable) thông qua onNext(). Subscriber là một Observer mà có thể unsubscribe thông qua implement một interface khác đó là Subscription(khác với Observer ở chỗ này).

RxJava cung cấp cho 10 phương thức dể tạo ra Observable:

+ Observable.from(): nếu truyền vào một array thì nó tổng số lần nó phát ra item trong onNext() bằng size của array đó. VD: param là array có size bằng 3 thì Observable sẽ phát ra onNext 3 lần

+ Observable.just(): nếu truyền vào một array thí Observable sẽ phát ra array trong duy nhất một onNext, nó khác với from(). VD: param là array thì phát ra item là array onNext().

+Observable.defer(): Observable chỉ khởi tạo khi có ÍT NHẤT một Subscriber đăng kí với nó. Nó sẽ tạo 1 Observable cho mỗi Subscriber của nó.

+Observable.interval(): phát ra một item trong onNext() kiểu Long sau mỗi n thời gian.

+Observable.create(): cách này làm thủ công

 

 

 

N0te 2016/27/01

  • Edittext need clicking twice to do something => need to set “focusableInTouchMode” = false to resolved this issue
  • Không được hoàn toàn tin tưởng library hoặc code có sẵn, phải kiểm tra lại luồng

Note 2016/01/04

  • Gặp vấn đề về hàm vẽ layout, cẩn thận nó là listener gọi liên tục => giảm performance
  • VD:  getViewTreeObserver().addOnGlobalLayoutListener
  • Gặp vấn đề fade in của dialog khi bị click khi dialog chưa kịp show lên
  • => làm thêm handler cho dialog đang fade in
  • Gặp vấn đề về multi dialog khi bị stress test
  • =>
    @Override
      public void show(FragmentManager manager, String tag) {
        if (manager.findFragmentByTag(tag) == null) {
          super.show(manager, tag);
        }
      }

Google Cloud Message(GCM)


Nguồn

  • : https://duythanhcse.wordpress.com/2014/10/30/bai-50-cach-su-dung-google-cloud-message-trong-android

    Quy trình hoạt động như sau (số thứ tự là bước):

    Bước 0:

    – Phải tạo một Project trên https://console.developers.google.com trước để có được Sender Id và Application Id

    – Xây dựng Server và WebService của ta với CSDL phù hợp để lưu trữ Registration Id.

    Bước 1:

    – Các thiết bị Mobile Android sẽ gửi Sender Id và Application Id lên GCM server để đăng ký (chú ý là Sender Id được cung cấp từ Google Developers).

    Bước 2:

    – Nếu đăng ký thành công thì GCM Server sẽ tạo ra một mã đăng ký gọi là Registration Id và gửi ngược về cho thiết bị Android.

    Bước 3:

    – Sau khi nhận được Registration Id mà GCM Server gửi về, mỗi thiết bị Android này sẽ gửi Registration Id lên Server thông qua Web Service (chú ý là Server này do ta xây dựng, tức nó là độc lập với GCM Server của Google).

    Bước 4:

    – Sau khi Server của ta nhận được Registration Id (mỗi Android device sẽ được cung cấp Id riêng, theo từng session do GCM Server tạo ra) sẽ tiến hành lưu vào CSDL (do ta xây dựng) để sử dụng cho các lần sau này (gửi tin nhắn hàng loạt).

    Bước 5:

    – Xây dựng ứng dụng trên Server để cho phép gửi Tin nhắn hàng loạt (có thể gửi tới 1000 Android device mà không tốn phí), ở bước này cũng phải lấy Sender Id và Application Id do bước 0 tạo ra. Định dạng gửi tin sẽ theo JSON format, có thể gửi cả dấu Tiếng Việt.

    – Tin nhắn ở bước này sẽ được gửi lên GCM Server.

    Bước 6:

    – Sau khi GCM Server nhận được tin nhắn theo định dạng JSON ở bước 5, nó sẽ tiến hành gửi tơi tất cả các máy trạm được đăng ký trong gói JSON này và gần như ngay lập tức các Client đều nhận được.

    Bài này rất hay và có thể áp dụng được thực tế để giúp giảm thiểu chi phí nhắn tin SMS, vì về sau nhân viên sử dụng Smart Phone rất nhiều và dường như WIFI có trong mọi ngóc nghách hẻm hóc….. nên có thể triển khai để nhắn tin cho nhân viên thông báo họp hay đi ăn nhậu…. Đối với Trường học cũng vậy có thể áp dụng để nhắn tin cho học sinh , sinh viên lên tới 1000 người mà không tốn phí (Vì theo Tui càng về sau giới trẻ sẽ ưa chuộng Smart Phone hơn là cục gạch Nồi Đồng Cối Đá được sản xuất từ kiếp trước).

    Bước 0, 5, 6 là xây dựng cho Server Side (CSDL, Webserver, WebService, Webform…)

    Bước 1,2,3,4 là xây dựng cho Client Side (Android Application).

  • By leetron007 Posted in iOS

    Multi-Threading: Handler vs AsyncTask vs Thread

    Chủ đề này nói về lập trình đa tiến trình trong Android.
    Slide tham khảo thêm
    https://www.dropbox.com/s/eci8s6qlhx4dycz/8._Xu_ly_bat_dong_bo_academia.edu.ppt?dl=0

    Thread
    Android thay đổi UI và handler Input từ một Thread, Thread này được gọi là Main Thread.
    Android collect mọi event trong một queue và xử lí trong một Looper class.

    Nếu không xử lí đa luồng, mọi code trong Android sẽ chạy trong Main Thread và mỗi action sẽ thực thi sau một action khác. Nếu gặp phải xử lí trong thời gian lâu, ví dụ tải data từ Internet, ứng dụng Android sẽ block cho đến khi xử lí hoàn thành.

    Android hỗ trợ Java Thread. Bạn có thể sử dụng Threads từ trong package “java.util.concurrent” để put action vào trong background. Điểm giới hạn duy nhất là bạn không thể trực tiếp cập nhật UI từ trong background process, tức là Threads không thể tương tác với UI. Nếu bạn cần update UI từ một background task bạn cần sử dụng một số class riêng của Android. Bạn có thể sử dụng Handler hoặc AsyncTask. Thread được dùng để kết nối socket chạy trong một service.

    Thread là cha của cả cả 2, AsyncTask and Handler. AsyncTask and Handler are written in Java (internally they use a Thread), so everything you can do with Handler or AsyncTask, you can achieve using a Thread too.
    Handler
    Class Handler có thể tương tác, update UI. Một handler cung cấp phương thức nhận message và runnable. Để sử dụng Handler bạn override handlerMessage() để xử lí message ở trong subclass. Để xử lí runnable bạn có thể sử dụng method post(). Bạn có thể post message thông qua method sendMessage(Message msg) hoặc sendEmptyMessage.
    Ưu điểm lớn nhất khi sử dụng Handler là ưu điểm của MessagesQueues, vì vậy bạn muốn sắp xếp các message hoặc cập nhật multiple UI hoặc lặp task.
    Một Handler cho phép gửi và xử lý Message và đối tượng Runnable. Mỗi instance Handler được liên kết với một thread duy nhất và hàng đợi message của thread. Nếu tạo một Handler mới thì nó được giới hạn đến thead/message queue của thread tạo ra nó. Có 2 cách sử dụng của Handler: (1) thiết lập message và runnable sẽ được thực thi ở một thời điểm trong tương lai, (2) xếp vào hàng đợi một hành động được thực hiện ở một thread khác.

    Handler có 2 cách dùng: sử dụng sentMessage và post.
    AsyncTask
    Nếu bạn có một Activity cần dowwnload content thực hiện operation. Đặc biệt khi xử lý đa tiến trình mà lại muốn kiểm tra kết quả trả về của tiến trình thì ta phải dùng AsyncTask.
    AsyncTasks are similar, infact they make use of Handlers, but doesn’t run in the UI thread, so its good for fetching data, for instance fetching webservices. Later you can interact with the UI.

    AsyncTask was written to provide a convenient, easy-to-use way to achieve background processing in Android apps, without worrying too much about the low-level details(threads, message loops etc). It provides callback methods that help to schedule tasks and also to easily update the UI whenever required.
    My rule of thumb would be:

    If you are doing something isolated related to UI, for example downloading data to present in a list, go ahead and use AsyncTask.

    If you are doing multiple repeated tasks, for example downloading multiple images which are to be displayed in ImageViews (like downloading thumbnails) upon download, use a task queue with Handler.

    Service in Android

    Service là một trong 4 thành phần chính của android (Activity, Service, BroadcastReceiver, ContentProvider). Service không có giao diện chuyên dùng để thực hiện một nhiệm vụ nào đó được thực hiện ngầm dưới background mà không cần tương tác đến giao diện ví dụ như: chơi nhạc nền, download file, xử lý tính toán…
    Vòng đời của Service
    Một serivce là một thành phần chạy dưới nền mà không trực tiếp tương tác với người dùng. Service không có giao diện người dùng, nó không có bao quanh bởi lifecycle của một activity.
    Service dùng cho các tác vụ chạy lâu dài, ví dụ download, checking new data, data processing, update content…
    Service chạy với độ ưu tiên cao hơn so với activiy invisible vì vậy nó ít bị khả năng hệ thống Android kết thúc. Service có thể được cấu hình để khởi động lại nếu nó bị kết thúc bởi hệ thống android môt khi các tài nguyên lại có sẵn lần nữa.
    Có khả năng chỉ định service có ngang độ ưu tiên với activity đang active. Trong trường hợp này nó được yêu cầu để có một hành động notification nhìn thấy được cho các dịch vụ liên quan. Nó được thường xuyên sử dụng để chơi nhạc hoặc video.
    Lưu ý: Khi một context nào đó gọi startService() để start service mong muốn. Nếu service đó chưa được khởi tạo sẽ gọi onCreate() rồi gọi tiếp onStart().
    Nếu sau đó lại có context gọi service này mà service đang chạy thì chi mỗi phương thức onStart() được gọi lại, không gọi lại onCreate().
    Như vậy cho dù bạn có start bao nhiều lần thì chỉ có duy nhất mất một instance của service và chỉ cần gọi stopService() một lần để kết thúc service.

    Có 2 loại service tương ứng với 2 kiểu start Service:
    1. Unbound Service sử dụng phương thức startService(), thường được sử dụng để thực thi một hành động đơn và có thể không trả về kết quả (ví dụ chơi nhac). Để kết thúc Service sẽ phải gọi hàm stopService().
    Ví dụ:Khi chơi nhạc thì gọi startService, muốn nhạc dừng chơi thì stopService.

    2. Bound Service sử dụng phương thức blindService() cung cấp một interface dạng client-server cho phép app có thể tương tác với service.

    Bound Service đóng vai trò như môt server trong mô hình client-server. Bound service cho phép các thành phần của app (Activity) có thể liên kết với service để gửi các request- nhận response.
    Bound Service chỉ tồn tại khi nó phục vụ một thành phần của app mà nó không tồn tại vô hạn dưới background.
    Có 3 cách để blindService từ các thành phần của app:
    – IBlinder
    – Messenger
    – AIDL

    Activity vs Fragment vs FragmentActivity, what is difference point?

    Activity như đã biết một trong những thành phần chính của Android, Activity chính là xương sống, giao diện người dùng được xây dựng trên nền của Activity. – Giới thiệu Fragment: Fragment được đưa vào Android từ API 11, là một phần của activity, đóng góp vào xây dựng giao diện cho Activity. Fragment cũng được coi là sub-activity. Fragment life-cycle phụ thuộc vào Activity chứa nó, có nghĩa là Activity destroy thì fragment cũng không còn. – Giới thiệu về FragmentActivity: Thực chất là Activity Plus, bạn có thể gọi mọi function của Activity và có khả năng sử dụng Fragment, hữu dụng trong nhiều trường hợp. Bạn sử dụng FragmentActivity để dễ dàng xây dựng tab và swap. Chú ý: Nếu bạn sử dụng Activity thì phải đi với android.app.Fragment, còn nếu sử dụng FragmentActivity thì phải đi với android.support.v4.app.Fragment. Nếu làm ngược lại thì sẽ xảy ra exception. Bonus thêm Fragment Fragment Manager xử lý “Back” không giống Activity. Theo Activity thì trở về Activity trước đó, còn trong Fragment là trở về trạng thái trước đó. – fragmentTransaction.add(int containerViewId, Fragment fragment, String tag): add fragment mới vào container. – fragmentTransaction.remove( Fragment fragment): remove old fragment ra khỏi container. – fragmentTransaction.replace(int containerViewId, Fragment fragment, String tag): có nghĩa là nó gọi remove fragment cũ-> sau đó sẽ gọi add mới. Nó gộp quá trình remove và add. – fragmentTransaction.addToBackStack(str): Có nghĩa là quá trình transaction được lưu vào stack, option là name hoặc null. Khi replace nhiều fragment vào một stack thì nó sẽ xử lí nút Back. Function này thường sử dụng với Replace – fragmentManager.popBackStack(TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE): pop fragment có TAG, ngoài ra có xóa stack như sau transaction.popBackStack(null,FragmentManager.POP_BACK_STACK_INCLUSIVE);

    getBackStackEntryAt(int index): get at index

    getBackStackEntryCount(): get count in the back stack

    Handling Runtime Change

    Một số cấu hình có thể thay đổi trong khi runtime (ví dụ xoay màn hình, có cuộc gọi đến…). Khi đó Android restart Activity đang chạy (liên tiếp gọi onDestroy()-> onRestart).
    Vấn đề xảy ra là sẽ làm mất các thiết lập và trạng thái đang có của Avtivity, ví dụ form đang nhập sau khi restar thì các dữ liệu trên form bị mất hoàn toàn, do đó tùy một số trường hợp cần phải lưu các thông số này trước khi Activity bị destroy. Một bài trước đã giới thiệu việc lưu trữ trong Bundle trong function onSaveInstanceState(), để khôi phục lại dữ liệu thì có thể get Bundle trong function onCreate() hoặc onRestoreInstanceState().
    Việc gọi các function trên nhằm mục đích tránh việc restart bất kì thời điểm nào mà không mất dữ liệu người dùng hoặc trạng thái. Tuy nhiên có thể làm giảm trải nghiệm của người dùng vì tốn các chi phí lưu trữ và hồi phục đối với một số lượng lớn data. Có 2 option để giải quyết:
    – Giữ lại object trong khi cấu hình thay đổi : cho phép activity có thể restart khi cấu hình thay đôi, nhưng mang theo đối tượng đến new instance.
    – Xử lí cấu hình thay đổi: Ngăn chặn việc restart activity trong khi cấu hình thay đổi, nhưng nhận các callback khi cấu hình thay đổi, vì vậy có thể tự cập nhật nếu cần thiết.

    Giữ lại object trong khi cấu hình thay đổi
    Nếu khi restart activity cần một lượng lớn data thì có thể làm giảm chất lượng giao diện người dùng. Mặc dù bạn có thể restore trạng thái với Bundle với function onSaveInstanceState() – Tuy nhiên nó không được thiết kế để mang theo đối tượng lớn (ví dụ bitmap) và data phải được serialized và sau đó deserialized. Một giải pháp khác được đưa ra là sử dụng một Fragment. Fragment này có thế chưa các liên kết đển các objetc mà bạn có thể giữ lại.
    Vì sao fragment có thể làm được, khi hệ thống shut down activity khi cấu hình thay đổi, fragment được giữ lại mà không bị destroy. Do đó có thể lưu lại trong fragment.
    Để lưu giữ object trong một fragment có thể làm theo các bước sau:
    1. Extend Fragment và khai báo tham chiếu đến đối tượng.
    2. Gọi setRetainInstance(boolean) khi fragment được tạo ra.
    3. Add fragment vào activity.
    4. Sử dụng Fragment để lấy fragment khi activitu được restart.
    Ví dụ code đơn giản:

    public class RetainedFragment extends Fragment {

    // data object we want to retain
    private MyDataObject data;

    // this method is only called once for this fragment
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // retain this fragment
    setRetainInstance(true);
    }

    public void setData(MyDataObject data) {
    this.data = data;
    }

    public MyDataObject getData() {
    return data;
    }
    }

    Chú ý: Không thế lưu trữ bất kì đổi tượng nào như Drawable, Adapter, View hoặc bất kì object nào liền quan đến Context. Nếu bạn làm vậy thì các đối tượng trên sẽ bị ứng dụng giữ và không thể garbage-collected, có nghĩa là không thể giải phóng bộ nhớ, vì vậy có rất nhiều bộ nhớ bị mất không thể thu hồi.
    Khi sử dụng FragmentManager để thêm fragment vào activity. Bạn có thể chứa các object data từ fragment khi activity khởi động lại. Ví dụ:

    public class MyActivity extends Activity {

    private RetainedFragment dataFragment;

    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    // find the retained fragment on activity restarts
    FragmentManager fm = getFragmentManager();
    dataFragment = (DataFragment) fm.findFragmentByTag(“data”);

    // create the fragment and data the first time
    if (dataFragment == null) {
    // add the fragment
    dataFragment = new DataFragment();
    fm.beginTransaction().add(dataFragment, “data”).commit();
    // load the data from the web
    dataFragment.setData(loadMyData());
    }

    // the data is available in dataFragment.getData()
    ...
    }

    @Override
    public void onDestroy() {
    super.onDestroy();
    // store the data in the fragment
    dataFragment.setData(collectMyLoadedData());
    }
    }

    Như trên, khi gọi function onCreate() thêm tham chiếu đối tượng và lấy data từ trong fragment. Và onDestroy để lưu trữ data bên trong fragment.

    Xử lí cấu hình thay đổi
    Nếu Activity không cần thay đổi khi cấu hình thay đổi, cần ngăn chặn việc restart activity.
    Bạn cần khai báo bên trong activity để xử lí khi cấu hình thay đổi. Bên trong file manifest, bên trong các bao gồm thẻ android:configChanges. Nếu tôi khai khai báo như sau:


    Có nghĩa là Activity có tên là MyActivity ngăn chặn việc restart activity khi xoay màn hình và hiện bàn phím. Thay vì đó, MyActivity sẽ nhận được một callback đến function onConfigurationChanges(). Sự thay đối cấu hình lúc này sẽ được xử lí.

    Fragment – Connectiton with another fragment

    Muốn một Fragment giao tiếp với một Fragment khác. Mọi sự giao tiếp Fragment- Fragment được thực hiện qua Activity. Hai Fragment không bao giờ có thể liên lạc trực tiếp.
    Định nghĩa Interface
    Để cho phép một Fragment giao tiếp với Activity, bạn định nghĩa một Interface bên trong Fragment sau đó khai bao trong function onAttach(),cuối cùng implement nó bên trong Activity.
    Interface là một listener đơn giản.
    Sau đây là code một ví dụ đơn giản giao tiếp giữa 2 Fragment A&B, A sẽ truyền text cho B:

    // You Activity implements your interface
    public class YourActivity implements FragmentA.TextClicked{
    @Override
    public void sendText(String text){
    // Get Fragment B
    FraB frag = (FragB)
    getSupportFragmentManager().findFragmentById(R.id.fragment_b);
    frag.updateText(text);
    }
    }

    // Fragment A defines an Interface, and calls the method when needed
    public class FragA extends Fragment{

    TextClicked mCallback;

    public interface TextClicked{
    public void sendText(String text);
    }

    @Override
    public void onAttach(Activity activity) {
    super.onAttach(activity);

    // This makes sure that the container activity has implemented
    // the callback interface. If not, it throws an exception
    try {
    mCallback = (TextClicked) activity;
    } catch (ClassCastException e) {
    throw new ClassCastException(activity.toString()
    + " must implement TextClicked");
    }
    }

    public void someMethod(){
    mCallback.sendText("YOUR TEXT");
    }
    }

    // Fragment B has a public method to do something with the text
    public class FragB extends Fragment{

    public void updateText(String text){
    // Here you have it
    }
    }

    Fragment – Part2

    Một Fragment đại diện cho một hành vi hoặc một phần của giao diện người dùng. Bạn có thể kết hợp nhiều Fragment trong một Activity duy nhất để xây dựng một giao diện người dùng đa cửa sổ. Bạn có thể nghĩ đến một Fragment như là một phần mô-đun của một Activity, trong đó nó có vòng đời riêng, có input riêng và có thể add và remove Fragment trong khi activity đang chạy. Nó như một “sub-activity”.

    Một Fragment luôn luôn phải được nhúng vào trong một activity và vòng đời của Fragment bị ảnh hưởng trực tiếp bởi vòng đời hoạt động của activity chủ. Ví dụ, khi activity đang trạng thái paused, tất cả các fragment trong nó cũng bị paused, và khi activity bị destroyed, tất cả các fragment cũng bị destroyed. Tuy nhiên, trong khi một Activity đang chạy (đang trong giai đoạn sau khi gọi hàm onResume đến trước khi gọi hàm onPause), bạn có thể thao tác từng Fragment một cách độc lập, chẳng hạn như thêm hoặc loại bỏ chúng.

    Khi add một Fragment vào trong một Activity layout tương tự như một View bằng cách sử dụng các thẻ tuy nhiên có thể một fragment không yêu cầu trở thành một phần giao diện của activity, bạn có thể sử dụng fragment mà nó không có UI như một thành phần vô hình của activity.

    Tạo một Fragment
    Khi tao một Fragment phải tạo một subclass của Fragment, class Fragment này có code gần giống như một Activity. Nó cũng gọi một số methods tương tự activity như onCreate(), onStart(), onPause(), and onStop(). Trong thực tế, có thế convert một ứng dụng Android sang sử dụng fragment, có thế move code gọi từ activity sang gọi từ fragment.

    Sau đây là lifecycle của một Fragment.
    Fragment Lifecycle

    Thông thường phải implement ít nhất một trong ba method sau:
    – onCreate() gọi khi tạo fragment, trong method này bạn nên khởi tạo các component cần thiết của fragment mà bạn muốn giữ lại khi fragment đang paused hoặc stopped sau đó resumed.
    – onCreateView() gọi khi fragment hiển thị giao diện lần đầu. Để draw UI cho fragment bạn phải trả về một View từ chính methods này. Bạn có thể trả về null nếu fragment không cung cấp một UI.
    – onPause() gọi khi người dùng rời khỏi fragment (không có nghĩa fragment bị destroyed). Nơi bạn thực hiện bất kỳ sự thay đổi nào lên trên session hiện tại.
    Có một số subclass bạn muốn kế thừa từ Fragment class:
    – DialoFragment: Sử dụng để tạo dialog.
    – ListFragment: cung cấp các methods chung để quản lý listview.
    – PreferenceFragment tương tự như FreferenceActivity, rất hữu dụng để tạo “setting” cho ứng dụng.

    Thêm giao diện cho Fragment.

    Để thêm giao diện cho fragment, bạn phải implement method onCreateView(), nó sẽ được hệ thống gọi khi lần đầu tiên fragment draw layout, method này trả về một View.

    Để trả về layout tf onCreateView, bạn có thế inflate một layout resource định nghĩa trong XML, ví dụ:

    public static class ExampleFragment extends Fragment {
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            // Inflate the layout for this fragment
            return inflater.inflate(R.layout.example_fragment, container, false);
        }
    }

    Method inflate() cung cấp 3 argument:

    – ID resource của layout muốn inflate

    – ViewGroup là cha của layout inflate.

    – Biến boolean trong trường hợp layout inflate sẽ được gắn vào với VewGroup cha trong khi inflate. Trong trường hợp false bởi vì hệ thống đã chèn layout inflate vào trong ViewGroup.

    Add một fragment vào trong một Activity

    Có 2 cách có thể add fragment vào trong activity:

    1. Khai báo fragment bên trong layout activity

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <fragment android:name="com.example.news.ArticleListFragment"
                android:id="@+id/list"
                android:layout_weight="1"
                android:layout_width="0dp"
                android:layout_height="match_parent" />
        <fragment android:name="com.example.news.ArticleReaderFragment"
                android:id="@+id/viewer"
                android:layout_weight="2"
                android:layout_width="0dp"
                android:layout_height="match_parent" />
    </LinearLayout>

    2. Lập tình add fragment vào trong một ViewGroup

    Trong khi activity đang chạy, có thể add fragment vào activity, đơn giản là xác định một ViewGroup và add fragment.

    Sử dụng APIs FragmentTransaction để transaction fragment, có thể get instance của FragmentTransaction từ Activity:

    FragmentManager fragmentManager = getFragmentManager()
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

    Thêm fragment sử dụng method add(), chỉ định fragment  ví dụ:

    ExampleFragment fragment = new ExampleFragment();
    fragmentTransaction.add(R.id.fragment_container, fragment);
    fragmentTransaction.commit();

    Tham số thứ nhất là ViewGroup, tham số này khai báo trong layout của activity. Tham số thứ hai chính là fragment để add. Cuối cùng gọi method commit() để bắt đầu chuyển đổi.

    Trước khi gọi method commit(), bạn có thể gọi method addToBackStack(), cho phép người dùng trở về trạng thái trước của fragment thông qua button Back.

    // Create new fragment and transaction
    Fragment newFragment = new ExampleFragment();
    FragmentTransaction transaction = getFragmentManager().beginTransaction();
    
    // Replace whatever is in the fragment_container view with this fragment,
    // and add the transaction to the back stack
    transaction.replace(R.id.fragment_container, newFragment);
    transaction.addToBackStack(null);
    
    // Commit the transaction
    transaction.commit();

    Giao tiếp với Activity

    Fragment có thể giao tiếp với activity thông qua instance với method getActivity(), ví dụ

    View listView = getActivity().findViewById(R.id.list);