1.Fragment简介
2.添加Fragment的两种方式
方式一:通过xml属性配置
新建一个TitleFragment、一个ContentFragment均继承自Fragment,然后在布局文件中设置fragment属性(要有id,name);
新建两个xml,分别用来作为两个Fragment的视图,然后再Fragment中重写onCreateView()方法加载布局,返回的是view对象
activity_main.xml
<LinearLayout 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" android:orientation="horizontal" tools:context="com.example.fragmenttest.MainActivity" > <fragment android:id="@+id/title_fragment" android:name="com.example.fragmenttest.TitleFragment" android:layout_width="0dip" android:layout_height="match_parent" android:layout_weight="1" /> <fragment android:id="@+id/content_fragment" android:name="com.example.fragmenttest.ContentFragment" android:layout_width="0dip" android:layout_height="match_parent" android:layout_weight="3" /> </LinearLayout>
title_layout
<?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" android:background="#00ff00"> <Button android:id="@+id/btn_1" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="时间" /> <Button android:id="@+id/btn_2" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="地点"/> <Button android:id="@+id/btn_3" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="人物"/> </LinearLayout>
<?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:background="#00ddff" android:orientation="vertical" > <TextView android:id="@+id/content_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="not data" /> </LinearLayout>
TitleFragment.java'
package com.example.fragmenttest; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class TitleFragment extends Fragment{ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.title_layout, container, false); return view; } }
package com.example.fragmenttest; 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{ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.content_layout, container, false); return view; } }
方式二:通过代码添加Fragment(以contentFragment为例)
把content_layout.xml的<fragment/>改为<FragmentLayout></FragmentLayout>,并且删去android:name=""属性,
MainActivity.java
package com.example.fragmenttest; import android.app.Activity; import android.app.FragmentManager; import android.app.FragmentTransaction; import android.os.Bundle; public class MainActivity extends Activity { // TitleFragment titleFragment; ContentFragment contentFragment; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); addTitleLayout(); } /* * 通过代码加载contentFragment */ private void addTitleLayout() { // 1.获取一个Fragment管理器 FragmentManager fm = getFragmentManager(); // 2.开启一个Fragment事务 FragmentTransaction ft = fm.beginTransaction(); // 3.实例化Fragment对象 contentFragment = new ContentFragment(); // 4.添加fragment ft.add(R.id.content_layout, contentFragment); // ft.remove();删除 // ft.replace();替换 // 5.提交事务 ft.commit(); } }
<LinearLayout 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" android:orientation="horizontal" tools:context="com.example.fragmenttest.MainActivity" > <fragment android:id="@+id/title_fragment" android:name="com.example.fragmenttest.TitleFragment" android:layout_width="0dip" android:layout_height="match_parent" android:layout_weight="1" /> <FrameLayout android:id="@+id/content_layout" android:layout_width="0dip" android:layout_height="match_parent" android:layout_weight="3" ></FrameLayout> </LinearLayout>
3.Fragment出入栈操作
MainActivity
package com.example.fragmenttest2; import android.app.Activity; import android.app.FragmentTransaction; import android.os.Bundle; import android.view.KeyEvent; import android.view.View; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } // public void oneClick(View view) { MyFragment fragment1 = new MyFragment("one"); FragmentTransaction ft1 = getFragmentManager().beginTransaction(); ft1.replace(R.id.content_layout, fragment1); // 把ft1添加到返回栈 ft1.addToBackStack(null); ft1.commit(); } public void twoClick(View view) { MyFragment fragment1 = new MyFragment("two"); FragmentTransaction ft1 = getFragmentManager().beginTransaction(); ft1.replace(R.id.content_layout, fragment1); // 把ft1添加到返回栈 ft1.addToBackStack(null); ft1.commit(); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (getFragmentManager().getBackStackEntryCount() == 0) { finish(); } else { getFragmentManager().popBackStack();// 出栈 } return true; } return super.onKeyDown(keyCode, event); } }
<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" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.fragmenttest2.MainActivity" > <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:text="one" android:onClick="oneClick"/> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/button1" android:layout_alignParentRight="true" android:text="two" android:onClick="twoClick" /> <FrameLayout android:id="@+id/content_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignLeft="@+id/button1" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_below="@+id/button1" > </FrameLayout> </RelativeLayout>
MyFragment
package com.example.fragmenttest2; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; public class MyFragment extends Fragment { // public static MyFragment getInstance(String title){ // Bundle b = new Bundle(); // b.putString("title", title); // MyFragment myFragment = new MyFragment(); // myFragment.setArguments(b); // return myFragment; // // } // // @Override // public View onCreateView(LayoutInflater inflater, ViewGroup container, // Bundle savedInstanceState) { // View view = inflater.inflate(R.id.content_framelayout, container, false); // TextView textView = (TextView) view.findViewById(R.id.textView1); // textView.setText(getArguments().getString("title")); // return view; // } private String title; public MyFragment() { } public MyFragment(String title) { this.title = title; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.content_framelayout, container, false); TextView textView = (TextView) view.findViewById(R.id.textView1); textView.setText(title); return view; } }
content_framelayout
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/textView1" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="hello blank fragment" /> </FrameLayout>
4.Fragment传参方式
上述逻辑代码存在缺陷,即在旋转屏幕之后,原来的数据会丢失,说明重新创建了Activity
MyFragmenr
package com.example.fragmenttest2; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; public class MyFragment extends Fragment { /* * Fragment的传参方法 */ //通过构造一个getInstance方法传递参数 public static MyFragment getInstance(String title){ Bundle b = new Bundle(); b.putString("title", title); MyFragment myFragment = new MyFragment(); myFragment.setArguments(b); return myFragment; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.content_framelayout, container, false); TextView textView = (TextView) view.findViewById(R.id.textView1); textView.setText(getArguments().getString("title")); return view; } // private String title; // // public MyFragment() { // } // // public MyFragment(String title) { // this.title = title; // } // // @Override // public View onCreateView(LayoutInflater inflater, ViewGroup container, // Bundle savedInstanceState) { // View view = inflater.inflate(R.layout.content_framelayout, container, // false); // TextView textView = (TextView) view.findViewById(R.id.textView1); // textView.setText(title); // return view; // } }
MainActivity
package com.example.fragmenttest2; import android.app.Activity; import android.app.FragmentTransaction; import android.os.Bundle; import android.view.KeyEvent; import android.view.View; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void oneClick(View view) { // MyFragment fragment1 = new MyFragment("one"); MyFragment fragment1 = MyFragment.getInstance("one"); FragmentTransaction ft1 = getFragmentManager().beginTransaction(); ft1.replace(R.id.content_layout, fragment1); // 把ft1添加到返回栈 ft1.addToBackStack(null); ft1.commit(); } public void twoClick(View view) { // MyFragment fragment1 = new MyFragment("two"); MyFragment fragment1 = MyFragment.getInstance("two"); FragmentTransaction ft1 = getFragmentManager().beginTransaction(); ft1.replace(R.id.content_layout, fragment1); // 把ft1添加到返回栈 ft1.addToBackStack(null); ft1.commit(); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (getFragmentManager().getBackStackEntryCount() == 0) { finish(); } else { getFragmentManager().popBackStack();// 出栈 } return true; } return super.onKeyDown(keyCode, event); } }
5.Fragment与Activity交互
MainActivity
package com.example.fragmenttest3; import com.example.fragmenttest3.MyMenuFragment.MyMenuListener; import android.app.Activity; import android.os.Bundle; //宿主要实现定义的回调接口 public class MainActivity extends Activity implements MyMenuListener { private MyMenuFragment menuFragment; private MyInfoFragment infoFragment; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); menuFragment = (MyMenuFragment) getFragmentManager().findFragmentById( R.id.menuFragment); infoFragment = (MyInfoFragment) getFragmentManager().findFragmentById( R.id.infoFragment); } @Override public void changeValue(String value) { // TODO Auto-generated method stub infoFragment.changeTextViewValue(value); } }
activity_main
<LinearLayout 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="com.example.fragmenttest3.MainActivity" > <fragment android:id="@+id/menuFragment" android:name="com.example.fragmenttest3.MyMenuFragment" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" /> <fragment android:id="@+id/infoFragment" android:name="com.example.fragmenttest3.MyInfoFragment" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="2" /> </LinearLayout>
MyMenuFragment
package com.example.fragmenttest3; import android.app.Activity; 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.TextView; public class MyMenuFragment extends Fragment implements OnClickListener{ private MyMenuListener menuListener; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.menu_fragmentlayout, container,false); view.findViewById(R.id.btn_news).setOnClickListener(this); view.findViewById(R.id.btn_music).setOnClickListener(this); return view; } @Override public void onAttach(Activity activity) { super.onAttach(activity); //此时的menuListener代表的就是宿主Activity menuListener = (MyMenuListener) activity; } // //点击事件要触发,就要先调用需要的接口,所以要事先声明一个接口 (和视频一样,用xml里on
click方法报错,所以改用setOnClickListener方法) // public void newsClick(View v){ // menuListener.changeValue("news"); // } // // public void musicClick(View v){ // menuListener.changeValue("music"); // } //哪里要产生事件(这里有两个按钮触发点击事件),就在那里定义一个回调接口 public static interface MyMenuListener{ public void changeValue(String value); } @Override public void onClick(View v) { // TODO Auto-generated method stub switch(v.getId()){ case R.id.btn_news: menuListener.changeValue("news"); break; case R.id.btn_music: menuListener.changeValue("music"); break; } } }
MyInfoFragment
package com.example.fragmenttest3; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; public class MyInfoFragment extends Fragment{ private TextView textView; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.info_fragmentlayout, container,false); textView = (TextView) view.findViewById(R.id.tv); return view; } public void changeTextViewValue(String value){ textView.setText(value); } }
menu_fragmentlayout
<?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" > <Button android:id="@+id/btn_news" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="News" /> <Button android:id="@+id/btn_music" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Music" /> </LinearLayout>
info_fragmentlayout
<?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:id="@+id/tv" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="Hello"/> </LinearLayout>
6.PreferenceFragment