Android开发教程之Fragment定义、创建与使用方法详解
Fragment是Android平台中一种重要的组件类型,用于在活动中展示多个页面。本文将详细介绍Fragment的定义、创建、使用以及如何实现Fragment和Activity之间的通讯,同时还会讨论如何在Fragment中执行事务。
Fragment的定义和创建
定义Fragment
Fragment是一种用户界面组件,可以被插入到一个Activity中,属于该Activity的一部分。它能够独立的执行交互操作、添加或移除。因此,常把Fragment比喻为“Activity的模块”或者“Activity内的子Activity”。
定义一个Fragment,需要继承android.app.Fragment或者android.support.v4.app.Fragment类。
public class ExampleFragment extends Fragment {
}
在Fragment中完成界面布局,是很重要的步骤,通过重写onCreateView方法实现。
public class ExampleFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
//加载fragment布局
View view = inflater.inflate(R.layout.fragment_example, container, false);
return view;
}
}
创建Fragment
Fragment的创建,必须依存在一个Activity当中。具体步骤分为以下几步:
1.定义Fragment布局
在创建一个Fragment前,我们先定义Fragment的布局,例如我们定义一个简单的TextView,布局文件名为“fragment_example.xml”:
<TextView
android:id="@+id/tv_example"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="This is an example fragment"/>
2.创建Fragment
通过FragmentManager.beginTransaction()方法获取一个FragmentTransaction对象,可用于添加、移除或替换Fragment。用户可以使用add()方法将一个Fragment添加到Activity当中。
ExampleFragment exampleFragment = new ExampleFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.add(R.id.fragment_container, exampleFragment);
transaction.commit();
在上述代码中,我们通过实例化ExampleFragment对象,再通过FragmentTransaction.add()方法加入Activity当中。
3.将Fragment添加到Activity当中
在上一步中,我们把Fragment的显示容器放置在Activity中。因此,用户可以通过XML来定义Fragment的显示容器,例如下面的例子:
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
when we add Fragment,我们需要指定容器id与Fragment映射
transaction.add(R.id.fragment_container, exampleFragment);
使用Fragment
在创建了Fragment并将其添加到Activity中之后,我们可以直接通过FragmentManager.findFragmentById()或者FragmentManager.findFragmentByTag()方法获取该Fragment,并使用该对象来执行相应的操作。
ExampleFragment fragment = (ExampleFragment)getSupportFragmentManager().findFragmentById(R.id.form_bottom_sheet);
使用findFragmentById方法用来找到之前我们定义的fragment_container视图中的Fragment。
如同Activity一样,Fragment也有生命周期的概念,重写对应的生命周期方法可以实现Fragment对应状态的监听或者处理:
生命周期 | 描述 |
---|---|
onAttach() | 当Fragment被添加到Activity时调用 |
onCreate() | 当Fragment被创建时调用 |
onCreateView() | 创建Fragment的布局时调用,该方法必须返回一个View,该view即显示在activity中的Fragment布局 |
onActivityCreated | 当 Fragment 所在的Activity 完成了其 onCreate() 生命周期后,调用该方法,可以获取所有的 view 资源 |
onResume() | 当Fragment对用户可见时调用,Fragment进入前台,从后台返回 |
onPause() | 当Fragment不再对用户可见时调用,Fragment前台退至后台 |
onStop() | 当Fragment被退到栈顶面之后调用 |
onDestroyView() | 当Fragment被销毁或与Activity的关联被切断时触发 |
onDestroy() | 当Fragment被销毁时调用 |
onDetach() | 当Fragment与Activity脱离关联时调用 |
Fragment和Activity交互
在Fragment中获取Activity的引用
当Fragment作为Activity的子组件运行时,可以通过getActivity()方法获得Activity对象的引用。在Fragment中获取Activity对象的引用示例如下:
public class ExampleFragment extends Fragment {
private MainActivity mainActivity;
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof MainActivity) {
mainActivity = (MainActivity) context;
} else {
throw new IllegalArgumentException("Activity must instanceof MainActivity");
}
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_example, container, false);
final TextView textView = (TextView)view.findViewById(R.id.tv_example);
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mainActivity.changeText("change text from Fragment");
}
});
return view;
}
}
在上述代码中,在Fragment中声明了一个MainActivity对象,之后在onAttach()方法中通过getContext()方法获得了一个Activity对象。接着在Fragment的onCreateView()方法中初始化Fragment的布局。当用户点击TextView时,就可以调用Activity中的方法,从而实现了Fragment和Activity的交互。
在Activity中获取Fragment的引用
在Activity中获取到Fragment的引用,可以通过Fragment管理器来完成,具体而言,就是通过FragmentManager.findFragmentById()或者FragmentManager.findFragmentByTag()方法获取Fragment。
ExampleFragment exampleFragment = (ExampleFragment)getSupportFragmentManager().findFragmentById(R.id.fragment_container);
在上述代码中,我们通过实例化ExampleFragment对象来获取R.id.fragment_container中的Fragment对象。
Fragment本身并不允许直接修改相邻的Activity,所以Fragment中的事件不能直接影响Activity中的操作。而Fragment和Activity之间的通信则需要使用接口方法。
例如,在Activity中定义一个接口,并在Fragment中实现该接口就可以实现两者之间的交互。
public class MainActivity extends AppCompatActivity implements ExampleFragment.OnButtonClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ExampleFragment exampleFragment = new ExampleFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.add(R.id.fragment_container, exampleFragment);
transaction.commit();
}
@Override
public void onButtonClick(String text) {
TextView textView = findViewById(R.id.tv_example);
textView.setText(text);
}
}
在上述MainActivity代码中,我们实现了由ExampleFragment.OnButtonClickListener接口定义的onButtonClick()方法,并且在ExampleFragment中定义了该接口,从而完成了Activity和Fragment的交互。
public class ExampleFragment extends Fragment {
public interface OnButtonClickListener {
void onButtonClick(String text);
}
private OnButtonClickListener clickListener;
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnButtonClickListener) {
clickListener = (OnButtonClickListener) context;
} else {
throw new IllegalArgumentException("Activity must instance of MainActivity");
}
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_example, container, false);
Button button = (Button) view.findViewById(R.id.btn_example);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
clickListener.onButtonClick("Dialog Fragment!");
}
});
return view;
}
}
在上述ExampleFragment代码中,我们定义了一个OnClicklistener接口来完成点击事件,在onAttach方法中获取clickListener接口的实现,并当clickListener被执行时,调用onButtonClick方法从而完成了Activity和Fragment之间的交互。
Fragment的事务操作
通过事务操作可以对Fragment的可见性以及执行remove、add、detach和replace等操作来进行动态添加或替换等操作。通常,在一个FragmentTransaction中可以执行多项操作。
例如:
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.add(R.id.fragment_container, exampleFragment);
transaction.addToBackStack(null);
transaction.commit();
在上述代码中,我们通过调用FragmentTransaction.addToBackStack()方法将前一次事务操作前的状态加入到后退栈中,这样当用户按下返回键时,就可以回到之前的状态。
常用事务操作的示例如下:
//新建一个Fragment
ExampleFragment exampleFragment = new ExampleFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
//设置事务动画
transaction.setCustomAnimations(R.anim.slide_left_in, R.anim.slide_right_out);
//添加一个Fragment
transaction.add(R.id.fragment_container, exampleFragment);
//替换fragment
transaction.replace(R.id.fragment_container, exampleFragment, "tag");
//将前一个事务状态加入到后退栈中
transaction.addToBackStack(null);
//Set是否保留要实例化的Fragment的状态
transaction.setReorderingAllowed(true);
//提交事务
transaction.commit();
在上述代码中,我们依次执行了设置事务动画、添加Fragment、替换Fragment、将前一个事务的状态加入后退栈、设置是否保留要实例化的Fragment的状态等多项操作。
其他相关方法
从Fragment中调用另一个Fragment的方法
Fragment和Fragment之间传递参数并不是象Activity和Activity那样方便,在Fragment中调用另一个Fragment的方法有一定的限制。例如,可以使用FragmentManager.findFragmentById()方法获得一个Fragment的实例,然后调用它的方法。
public class ExampleFragment extends Fragment {
private ExampleFragment2 exampleFragment2;
private TextView tvText;
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
FragmentManager fm = getActivity().getSupportFragmentManager();
exampleFragment2 = (ExampleFragment2) fm.findFragmentById(R.id.fragment_example2);
tvText = (TextView)getView().findViewById(R.id.tv_example);
}
public void changeText(String string) {
tvText.setText(string);
}
public void changeTextFromFragment2(String string) {
tvText.setText(string);
}
}
在上述ExampleFragment中,我们实现了两个方法changeText()和changeTextFromFragment2(),并在onActivityCreated()方法中获得了ExampleFragment2的实例。
判断当前Fragment是否被添加到Activity中
可以通过isAdded()方法来判断当前的Fragment是否被添加到Activity中,使用方法如下:
public class ExampleFragment extends Fragment {
@Override
public void onResume() {
super.onResume();
if (isAdded()) {
//执行逻辑
}
}
}
示例说明
示例一:Fragment完成简单计算器功能
本示例中,我们创建一个简单的Fragment,并在其中实现简单的加减乘除等计算器功能。
首先,在MainActivity中添加一个Fragment容器,并将ShowResultFragment添加进来,这样可以在Activity界面上看到AddFragment中的界面。
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/fragment_calculate"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.example.android.fragmentaddexample.ShowResultFragment"/>
</FrameLayout>
下面是AddFragment的布局文件add_fragment.xml,该文件包含一个编辑框和四个按钮,分别是addBtn(加法)、subBtn(减法)、mulBtn(乘法)和divBtn(除法),我们可以在add_fragment.xml中添加如下代码:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/first_edit_Text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<Button
android:id="@+id/addBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="+"/>
<Button
android:id="@+id/subBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="-"/>
<Button
android:id="@+id/mulBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="*"/>
<Button
android:id="@+id/divBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="/"/>
</LinearLayout>
接下来我们就可以在ShowResultFragment.java中实现计算器的逻辑。我们使用EditText控件来获取用户输入的两个数值,并通过四个按钮的点击事件来实现相应的计算逻辑。
public class ShowResultFragment extends Fragment {
private EditText mFirstInputEdittext;
private EditText mSecondInputEdittext;
private Button mAddBtn;
private Button mSubBtn;
private Button mMulBtn;
private Button mDivBtn;
private View.OnClickListener mOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
int firstNum = 0;
int secondNum = 0;
if(!TextUtils.isEmpty(mFirstInputEdittext.getText())){
firstNum = Integer.parseInt(mFirstInputEdittext.getText().toString());
}
if(!TextUtils.isEmpty(mSecondInputEdittext.getText())){
secondNum = Integer.parseInt(mSecondInputEdittext.getText().toString());
}
int res = 0;
switch (view.getId()){
case R.id.addBtn:
res = firstNum+secondNum;
break;
case R.id.subBtn:
res = firstNum - secondNum;
break;
case R.id.mulBtn:
res = firstNum*secondNum;
break;
case R.id.divBtn:
res = firstNum/secondNum;
break;
default:
break;
}
Toast.makeText(getActivity(),String.valueOf(res),Toast.LENGTH_SHORT).show();
}
};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.add_fragment, container, false);
mFirstInputEdittext = (EditText) view.findViewById(R.id.first_edit_Text);
mSecondInputEdittext = (EditText) view.findViewById(R.id.second_edit_Text);
mAddBtn = (Button) view.findViewById(R.id.addBtn);
mSubBtn = (Button) view.findViewById(R.id.subBtn);
mMulBtn = (Button) view.findViewById(R.id.mulBtn);
mDivBtn = (Button) view.findViewById(R.id.divBtn);
mAddBtn.setOnClickListener(mOnClickListener);
mSubBtn.setOnClickListener(mOnClickListener);
mMulBtn.setOnClickListener(mOnClickListener);
mDivBtn.setOnClickListener(mOnClickListener);
return view;
}
}
接下来我们就可以在MainActivity中启动Fragment并执行计算器的逻辑:
private void addFragment() {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, new ShowResultFragment());
transaction.commit();
}
最后运行代码,可以在Activity中看到一个简单的计算器界面,可以计算加减乘除等运算。
示例二:Fragment之间的通讯
在本示例中,我们演示了Fragment之间的通讯。我们分别定义了两个Fragment,一个是AddFragment,另一个是ShowResultFragment,在AddFragment中实现了EditText控件的输入功能,并把结果显示在TextView中; ShowResultFragment中实现了一个Button可以清空TextView中的内容,两个Fragment之间通过Button来通讯。
我们首先在MainActivity中添加这两个Fragment:
private void addFragment() {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container_add, new AddFragment(),"add");
transaction.replace(R.id.fragment_container_show, new ShowResultFragment(),"show");
transaction.commit();
}
在AddFragment中的布局文件add_fragment.xml中添加一个TextView,并在ShowResultFragment中的布局文件show_fragment.xml中添加一个Button,用于清空AddFragment中的TextView,布局文件内容
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Android开发教程之Fragment定义、创建与使用方法详解【包含Activity通讯,事务执行等】 - Python技术站