上篇文章介绍了,我怎么自定义一个 BaseActivity ,自然是少不了BaseFragment 了。
不多废话,直接上代码了啦!
public abstract class TBaseFragment extends Fragment implements View.OnClickListener { protected Context mContext;//上下文 protected View contentView;//parentView private int layoutResId;//布局 id private Toast toast; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { mContext = getActivity(); toast = Toast.makeText(mContext, "", Toast.LENGTH_SHORT); if (contentView == null) { contentView = inflater.inflate(layoutResId, container, false); } ViewGroup parent = (ViewGroup) contentView.getParent(); if (parent != null) { parent.removeView(contentView); } initViewAfterOnCreate(); initDataAfterOnCreate(); return contentView; } public void setContentLayout(int layoutResId) { this.layoutResId = layoutResId; } protected <T> T $(int id) { T view = (T) contentView.findViewById(id); return view; } protected void showToast(String str) { if (!TextUtils.isEmpty(str)) { toast.setText(str); toast.show(); } } protected void showToast(int strId) { showToast(getString(strId)); } protected void registerOnClickListener(TBaseFragment fragment, View... views) {//注册点击事件 for (View view : views) { view.setOnClickListener(fragment); } } @Override public void onClick(View v) { } /** * 用于从xml文件中inflate控件View */ public abstract void initViewAfterOnCreate(); /** * 给View填充数据 */ public abstract void initDataAfterOnCreate(); }注:(1)BaseFragment 的实现跟BaseActivity 的实现类似,不过,增加了自定义方法 setContentLayout() 用于传递布局的资源 id 到基类,通过这种方式,可以使用 Fragment 的子类的实现跟 Activity 的实现近乎一致,可以保持代码有较强的可读性
(2)protected<T> T $(int id) 方法的实现,借助 contentView 实现了 findViewById 与分离 onCreateView 的关系分离(否则,findViewById 需要依赖 onCreateView 创建的 View 来实现)
下面是一个简单的页面包含标题栏,返回按钮(及相应关闭事件),Activity界面内嵌一个 TestFragment,Fragment 页面里面只有一个“点击我,展示 Toast”的按钮(点击展示 Toast信息)
上面页面的代码如下
(1)TestActivity 页面 java代码
public class TestActivity extends TBaseActivity { @Override protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.act_test); super.onCreate(savedInstanceState); } @Override public void initViewAfterOnCreate() { backWithTitle("测试标题"); } @Override public void initDataAfterOnCreate() { getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout, new TestFragment()).commitAllowingStateLoss(); } }(2)TestActivity 的布局文件代码 <?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:fitsSystemWindows="true" android:orientation="vertical"> <include layout="@layout/title_bar"/> <FrameLayout android:id="@+id/frame_layout" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/> </LinearLayout> (3)TestFragment java 代码 public class TestFragment extends TBaseFragment { private TextView tv_test; @Override public void onCreate(@Nullable Bundle savedInstanceState) { setContentLayout(R.layout.frag_test); super.onCreate(savedInstanceState); } @Override public void initViewAfterOnCreate() { tv_test = $(R.id.tv_test); registerOnClickListener(this, tv_test);//注册点击事件 } @Override public void initDataAfterOnCreate() { } @Override public void onClick(View v) { switch (v.getId()) { case R.id.tv_test://点击按钮 showToast(tv_test.getText().toString()); break; } super.onClick(v); } } 注:可以发现 TestFragment 的的方法的实现跟 Activity 实现几乎一致,唯一的区别就是在 onCreate 方法里面调用了一个自定义的 setContentLayout 方法设置当前 Fragment 的布局文件
(4)TestFragment 布局文件代码
<?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_test" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/white" android:gravity="center" android:text="点击我,展示 Toast" android:textSize="20dp"/> </LinearLayout> 截止目前介绍了 BaseFragment 的实现及应用,通过这种方式有两个优点(1)使 Fragment 与普通的 Activity 保持一致的方法模式,代码更简洁易懂
(2)实现了 findViewById 与 onCreateView 方法的关系分离,同时民使用 findViewById 的调用更加简洁。
Demo GitHub 地址:https://github.com/chende008/TestProject