Android手机APP起航系列
本博客文章基于android官方sdk的docs文档,目的是通过此教程巩固android手机app开发的一些应知应会的基础知识,也希望能帮助同在学习android开发的小伙伴们,共同进步,如有写的不到之处,还请各位小伙伴们不吝赐教。
主要内容
1、设计思想
2、静态加载
3、动态加载
4、生命周期
5、数据交互
一、设计思想
fragment的设计是一种更加动态、更加灵活的UI设计,可以让我们的app更加简单地同时运行在较大屏幕设备(如pad)和手持移动设备(如智能手机)。它可以有效降低app的层级,使之更加简单。同时也提高我们代码的可重用性。比如同一个fragment既可以嵌在activity A中,又可以嵌在activity B中。
二、静态加载
方法:在activity的布局文件中加入fragment标签,将name属性标记为该fragment类的完整类名,示例如下:
在FirstActivity中静态加载FirstFragment,FirstActivity的布局文件为activity_first.xml文件,FirstActivity的关键代码如下:
public class FirstActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
}
}
FirstActivity的布局文件activity_first.xml代码如下,其包含一个TextView标签和一个fragment标签:
<TextView
android:background="#e2d40a"
android:id="@+id/tv"
android:text="这是first activity 的内容"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<fragment
android:id="@+id/frame_first"
android:name="com.jiaqian.fragmentdemo.fragments.FirstFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
FirstFragment代码如下,其布局文件为fragment_first.xml:
public class FirstFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.i("msg","FirstFragment Method--->onCreateView");
View view = inflater.inflate(R.layout.fragment_first,container,false);
TextView textView = (TextView) view.findViewById(R.id.tv_first);
return view;
}
}
布局文件fragment_first.xml中的包含TextView代码如下:
<TextView
android:id="@+id/tv_first"
android:layout_gravity="center"
android:text="这是 first fragment 的内容"
android:layout_width="match_parent"
android:layout_height="match_parent" />
运行结果如下,可以看到fragment已经被包含在activity里面:
三、动态加载
有时我们需要在程序运行时动态加载fragment,如在新闻app中,当点击新闻标题列表(fragment A)时,需要切换到您点击的新闻的具体内容界面(fragment B),这是就需要将activity中的内容有fragment a(新闻标题列表)替换为fragment b(新闻具体内容)。
方法:通过Fragment管理器(FragmentManager)得到一个Fragment事务(FragmentTransaction),开启事务后再添加各种事务(可以对fragment进行添加add、删除remove、替换replace以及添加到后台栈addToBackStack等操作),最后提交(commit)。具体实现的关键代码如下:
FirstFragment firstFragment = new FirstFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.second_activity_frame, firstFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
R.id.second_activity_frame为activity的布局文件中用户存放fragment的容器id,作为被添加的fragment的根元素。
四、生命周期
1、fragment的完整生命周期图,其中onAttach、onCreate()、onDestroy()、onDetach有且仅执行一次。另外,fragment不能单独存在,必须要嵌入在activity使用。
onAttach()
当fragment与activity关联的时候调用此方法,与onDetach()对应。
onCreateView()
当创建fragment的视图层级(内部内容组件)时调用此方法,返回View表示fragment有UI界面,返回null表示fragment没有UI界面,与onDestroyView()对应。
onActivityCreated()
当宿主activity创建完成时调用。
2、fragment生命周期方法与宿主activity的生命周期方法的对应关系
五、数据交互
在app中,数据一般不能直接从一个fragment传递到另一个fragment,我们需要将数据先传递到宿主activity,再从activity传递到另一个fragment。fragment与activity之间数据传输通常有几种方法:1、实现接口的方法;2、设置handler的方法;3、通过广播的方法。这里我们只介绍实现接口的方法完成数据传输(也是官方推荐的一种方法),其他两种方法自行脑补。
5.1、通过实现接口的方法,从fragment发送数据到activity
(1)、首先,我们需要在fragment中定义一个接口,接口中申明一个回调方法,将需要传递的数据作为参数回传给activity;
(2)、宿主activity实现上面fragment中定义的接口,在该activity的实现接口方法中实现自己的业务逻辑。
具体代码如下:
fragment相关代码如下:
//申明接口
private OnButtonPressListener mListener;
//接口定义
public interface OnButtonPressListener{
public void callback(String msg);
}
@Override
public void onResume() {
super.onResume();
Log.i("info", "====>>>onResume");
final EditText editText = (EditText) getActivity().findViewById(R.id.et1);
Button button = (Button) getActivity().findViewById(R.id.btn_send);
//通过点击fragment中的button,把fragment的中的EditText文本信息传递到activity
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mListener !=null){
//通过fragment自己的业务逻辑实现向activity传递数据
mListener.callback(editText.getText().toString());
}else{
}
}
});
}
@Override
//在fragment的onAttach方法中初始化接口
public void onAttach(Activity activity) {
super.onAttach(activity);
if(activity instanceof OnButtonPressListener){
mListener = (OnButtonPressListener) activity;
}else{
throw new RuntimeException(activity.toString()
+ " must implement OnButtonPressListener");
}
}
@Override
//在fragment的onAttach方法中置空接口实例
public void onDetach() {
super.onDetach();
mListener = null;
}
activity相关代码如下:
public class SecondActivity extends Activity implements ArticleFragment.OnButtonPressListener {
private TextView textView;
//参数msg为fragment传递过来的数据,在callback方法中实现自己的业务逻辑
@Override
public void callback(String msg) {
textView.append(msg);
}
}