Android Fragment is truly completely parsed (on), androidfragment
Reprinted please indicate the source: http://blog.csdn.net/lmj623565791/article/details/37970961
Since Fragment appeared, I have been talking about Fragment for a while. I feel like you can talk about anything with Fragment. I have to ask if Fragment can be implemented ~~~ Haha, isn't it a bit ~~~
This blog aims to show you how Fragment is generated, what is Fragment, Fragment lifecycle, how to use Fragment statically and dynamically, Fragment rollback stacks, Fragment transactions, and some special uses of Fragment, for example, what is the use of Fragment without layout? How does Fragment interact with Activity? How does Fragment create a dialog box? How Fragment integrates with ActionBar and so on.
1. Generation and introduction of Fragment
Android runs on a variety of devices, including cell phones with small screens, ultra-large screen tablets, and even TVs. For the screen size gap, in many cases, a set of apps are first developed for mobile phones, then a copy is copied, and the layout is modified to adapt to the tablet Shenma super screen. Can't an App adapt to mobile phones and tablets at the same time? Of course, yes. Fragment is designed to solve this problem. You can regard Fragment as an integral part of an Activity's interface. Even the Activity's interface can have completely different Fragment components, what's more handsome is that Fragment has its own lifecycle and receives and processes user events, so that it does not have to write a bunch of control event processing code in the Activity. More importantly, you can dynamically add, replace, and remove a Fragment.
2. Fragment Lifecycle
Fragment must exist in dependency and Activity. Therefore, the lifecycle of an Activity directly affects the lifecycle of Fragment. The figure on the official website shows the relationship between the two lifecycles:
We can see that Fragment has several additional lifecycle callback methods than Activity:
OnAttach (Activity)
Called when Fragment is associated with Activity.
OnCreateView (LayoutInflater, ViewGroup, Bundle)
Create a view for this Fragment
OnActivityCreated (Bundle)
Called when the onCreate method of the Activity returns
OnDestoryView ()
Corresponds to onCreateView, called when the Fragment view is removed
OnDetach ()
Corresponds to onAttach. It is called when the association between Fragment and Activity is canceled.
Note: Except onCreateView, If you overwrite all other methods, you must call the implementation of the parent class for this method,
3. Static Fragment
Hey, it's time to use it ~~
This is the simplest way to use Fragment. You can use Fragment as a common control and directly write it in the layout file of the Activity. Steps:
1. inherit Fragment and rewrite onCreateView to determine Fragemnt Layout
2. Declare the Fragment in the Activity, just like the normal View.
The following is an example (I use 2 Fragment as the layout of the Activity, one Fragment for the title layout, and one Fragment FOR THE CONTENT layout ):
Layout file of TitleFragment:
<? Xml version = "1.0" encoding = "UTF-8"?> <RelativeLayout xmlns: android = "http://schemas.android.com/apk/res/android" android: layout_width = "match_parent" android: layout_height = "45dp" android: background = "@ drawable/title_bar"> <ImageButton android: id = "@ + id/HYPERLINK" android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: layout_centerVertical = "true" android: layout_marginLeft = "3dp" android: background = "@ drawable/showleft_selector"/> <TextView android: layout_width = "fill_parent" android: layout_height = "fill_parent" android: gravity = "center" android: text = "I'm not" android: textColor = "# fff" android: textSize = "20sp" android: textStyle = "bold"/> </RelativeLayout>
TitleFragment
package com.zhy.zhy_fragments;import android.app.Fragment;import android.os.Bundle;import android.view.LayoutInflater;import android.view.View;import android.view.View.OnClickListener;import android.view.ViewGroup;import android.widget.ImageButton;import android.widget.Toast;public class TitleFragment extends Fragment{private ImageButton mLeftMenu;@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState){View view = inflater.inflate(R.layout.fragment_title, container, false);mLeftMenu = (ImageButton) view.findViewById(R.id.id_title_left_btn);mLeftMenu.setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View v){Toast.makeText(getActivity(),"i am an ImageButton in TitleFragment ! ",Toast.LENGTH_SHORT).show();}});return view;}}
Similarly, the layout file of ContentFragment is as follows:
<? Xml version = "1.0" encoding = "UTF-8"?> <LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android" android: layout_width = "match_parent" android: layout_height = "match_parent" android: orientation = "vertical"> <TextView android: layout_width = "fill_parent" android: layout_height = "fill_parent" android: gravity = "center" android: text = "Use the Fragment console" android: textSize = "20sp" android: textStyle = "bold"/> </LinearLayout>
package com.zhy.zhy_fragments;import android.app.Fragment;import android.os.Bundle;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;public class ContentFragment extends Fragment{@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState){return inflater.inflate(R.layout.fragment_content, container, false);}}
MainActivity
package com.zhy.zhy_fragments;import android.app.Activity;import android.os.Bundle;import android.view.Window;public class MainActivity extends Activity{@Overrideprotected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);setContentView(R.layout.activity_main);}}
Activity layout file:
<RelativeLayout 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" > <fragment android:id="@+id/id_fragment_title" android:name="com.zhy.zhy_fragments.TitleFragment" android:layout_width="fill_parent" android:layout_height="45dp" /> <fragment android:layout_below="@id/id_fragment_title" android:id="@+id/id_fragment_content" android:name="com.zhy.zhy_fragments.ContentFragment" android:layout_width="fill_parent" android:layout_height="fill_parent" /></RelativeLayout>
Does Fragment be declared in the layout file of the Activity just like a normal View, and all the control's event processing and other code are processed by their respective Fragment? In an instant, I think the Activity is clean and well-known ~~ Is code readability, reusability, and maintainability instantly improved ~~~ See the following:
4. Dynamic use of Fragment
As demonstrated above, the easiest way to use Fragment is ~ The following describes how to dynamically add, update, and delete Fragment.
To dynamically use Fragment, modify the layout file of Actvity and use a FrameLayout in the middle. Add the following four buttons ~~~ Hey ~~ No button --!
<RelativeLayout 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" > <fragment android:id="@+id/id_fragment_title" android:name="com.zhy.zhy_fragments.TitleFragment" android:layout_width="fill_parent" android:layout_height="45dp" /> <include android:id="@+id/id_ly_bottombar" android:layout_width="fill_parent" android:layout_height="55dp" android:layout_alignParentBottom="true" layout="@layout/bottombar" /> <FrameLayout android:id="@+id/id_content" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_above="@id/id_ly_bottombar" android:layout_below="@id/id_fragment_title" /></RelativeLayout>
The layout of the four buttons at the bottom will not be pasted, and you will understand it later ~~
Main Activity below
Package com. zhy. zhy_fragments; import android. app. activity; import android. app. fragmentManager; import android. app. fragmentTransaction; import android. OS. bundle; import android. view. view; import android. view. view. onClickListener; import android. view. window; import android. widget. linearLayout; public class MainActivity extends Activity implements OnClickListener {private LinearLayout listener; private LinearLayout mTabFriend; private ContentFragment mWeixin; private extends mFriend; @ define void onCreate (Bundle listener) {super. onCreate (savedInstanceState); requestWindowFeature (Window. FEATURE_NO_TITLE); setContentView (R. layout. activity_main); // initialize the control and declare the event mTabWeixin = (LinearLayout) findViewById (R. id. tab_bottom_weixin); mTabFriend = (LinearLayout) findViewById (R. id. tab_bottom_friend); mTabWeixin. setOnClickListener (this); mTabFriend. setOnClickListener (this); // set the default fragmentsetdefafrfragment ();} private void setdefafrfragment () {FragmentManager fm = getFragmentManager (); FragmentTransaction transaction = fm. beginTransaction (); mWeixin = new ContentFragment (); transaction. replace (R. id. id_content, mWeixin); transaction. commit () ;}@ Overridepublic void onClick (View v) {FragmentManager fm = getFragmentManager (); // enable the Fragment transaction FragmentTransaction transaction = fm. beginTransaction (); switch (v. getId () {case R. id. tab_bottom_weixin: if (mWeixin = null) {mWeixin = new ContentFragment () ;}// use the current Fragment layout to replace the transaction control of id_content. replace (R. id. id_content, mWeixin); break; case R. id. tab_bottom_friend: if (mFriend = null) {mFriend = new FriendFragment ();} transaction. replace (R. id. id_content, mFriend); break;} // transaction. addToBackStack (); // transaction commit transaction. commit ();}}
We can see that FragmentManager is used to dynamically load Fragment. Here we use the replace method ~~ In the next section, I will detail the common APIs of FragmentManager.
Note: If you use versions earlier than Android3.0, You need to introduce the v4 package, then the Activity inherits the FragmentActivity, and then get the FragmentManager through getsuppfrfragmentmanager. However, we recommend that the minSdkVersion and targetSdkVersion of the uses-sdk of the Menifest file be changed to 11 or above, so that you do not need to introduce the v4 package.
There are two sub-classes of Fragment in the Code. ContentFragment has been seen above, and FriendFragment is actually similar:
package com.zhy.zhy_fragments;import android.app.Fragment;import android.os.Bundle;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;public class FriendFragment extends Fragment{@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState){return inflater.inflate(R.layout.fragment_friend, container, false);}}
:
We can see that this is a good implementation effect. In fact, this effect has also been seen in previous blogs. In blogs: main interface of the Tab type of the Android project, we will summarize Fragment + TabPageIndicator + ViewPager. If you are interested, please take a look. Ps: for the sake of code conciseness, I will not add button click changes or anything. I will mainly explain the functions ~~~
5. Common APIs of the Fragment family
Three Common Fragment classes:
Android. app. Fragment is mainly used to define Fragment
Android. app. FragmentManager is mainly used to operate Fragment in an Activity.
Android. app. FragmentTransaction ensures the atomicity of Fragment operations in some columns. You must be familiar with the term transaction ~
A. method for obtaining FragmentManage:
GetFragmentManager () // v4, getSupportFragmentManager
B. The main operations are the FragmentTransaction methods.
FragmentTransaction transaction = fm. benginTransatcion (); // start a transaction
Transaction. add ()
Add a Fragment to the Activity
Transaction. remove ()
Remove a Fragment from the Activity. If the removed Fragment is not added to the rollback stack (this will be detailed later), the Fragment instance will be destroyed.
Transaction. replace ()
Replacing the current one with another Fragment is actually a combination of remove () and add ~
Transaction. hide ()
Hiding the current Fragment is only invisible and will not be destroyed.
Transaction. show ()
Show Hidden Fragment
Detach ()
Detaching this Fragment from the Activity will destroy its layout, but will not destroy the instance
Attach ()
Re-associate the Fragment separated from the Activity to the Activity and recreate its view level.
Transatcion. commit () // submit a transaction
Note: Fragment buddies often encounter errors such as inconsistent Activity states: State loss. The main reason is that the commit method must be called before Activity. onSaveInstance.
The above is basically all the methods used to operate Fragment. You can add, remove, or replace multiple operations when a transaction is started to commit.
It is worth noting that if you like to use Fragment, you must know which of these methods will destroy the view, which will destroy the instance, and which is only hidden to better use them.
A. For example, I have filled in some data in EditText in FragmentA. When switching to FragmentB, if you want to see the data in A, it is suitable for hide and show. That is to say, if you want to keep the panel for user operations, you can use hide and show. Of course, do not try to make a non-null judgment on the new instance.
B. For example, if I do not want to retain user operations, you can use remove (), add (), or replace (), which has the same effect as remove and add.
C. There is a slight difference between remove and detach. If Stack rollback is not considered, remove will destroy the entire Fragment instance, while detach only destroys its view structure, the instance will not be destroyed. How can we choose between them? If your current Activity persists, you can use detach first if you do not want to retain user operations.
The above describes some of the methods commonly used in Fragment. I believe that after reading this article, you will be clear about the reasons for Fragment and how to use Fragment. You can also understand it based on the API explanation, I once thought that Fragment had some problems with column disorder, but it was because I didn't figure out its lifecycle.
Due to the length of the article, the remaining content is reserved for the next article. In the next article, we will introduce:
1. How to manage the Fragment rollback Stack
2. How Fragment interacts with Activity
3. Best practices for Fragment and Activity Interaction
4. Use of Fragment without a view
5. Create a dialog box using Fragment
6. How to integrate with ActionBar and MenuItem ~~
Next article: complete parsing of Android Fragment (below)
Okay. Please leave a message if you have any questions ~~
After the replace of Android fragment, you can see the content on the original fragment.
/**
* Jump to the page
*
* @ Param from
* @ Param
*/
Public void switchContent (Fragment from, Fragment ){
If (from! = ){
MContent =;
FragmentTransaction transaction = getSupportFragmentManager ()
. BeginTransaction ();
// To. getLoaderManager (). hasRunningLoaders ();
// First judge whether it has been added
If (! To. isAdded ()){
// Hide the current fragment and add the following to the Activity
Transaction. hide (from). add (R. id. content_view, to). commit ();
} Else {
// Hide the current fragment and display the next
Transaction. hide (from). show (to). commit ();
}
}
}
This is used by my project. For more information, see from. Here, from is the current page and To is the page you want To switch.
How does Android add listeners to controls in Fragment?
Same settings as activity
Package com. paiao. fragment;
Import android. app. Activity;
Import android. app. Fragment;
Import android. OS. Bundle;
Import android. util. Log;
Import android. view. LayoutInflater;
Import android. view. View;
Import android. view. View. OnClickListener;
Import android. view. ViewGroup;
Import android. widget. Button;
Public class BtFragment extends Fragment implements OnClickListener {
Private Button login;
Private Button reg;
@ Override
Public void onAttach (Activity activity ){
// TODO Auto-generated method stub
Super. onAttach (activity );
Log. I ("I", "Fragment executes onAttach ");
}
@ Override
Public void onCreate (Bundle savedInstanceState ){
// TODO Auto-generated method stub
Super. onCreate (savedInstanceState );
Log. I ("I", "Fragment executes onCreate ");
}
@ Override
Public View onCreateView (LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState ){
// TODO Auto-generated method stub
Log. I ("I", "Fragment executes onCreateView ");
View view = inflater. inflate (R. layout. main1, null, false );
Login = (Button) view. findViewById (R. id. login );
Reg = (Button) view. findViewById (R. id. reg );
Login. setOnClickListener (this );
Reg. setOnClickListener (this );
Return view;
}
@ Override
Public void onActivityCreated (Bundle savedInst ...... remaining full text>