fragment基础【替换、传值、回掉】
2016-01-07 02:48
274 查看
总结知识点:
fragment的替换、fragment调用activity中的参数和组件、activity调用fragment中的参数、回掉监听事件
1.fragment的替换。先看下面的一张图,应用场景【左边不同位置的单击事件,在右侧显示不同的内容:音乐歌词播放器--》对应歌曲曲目列表和曲目信息】
需要掌握:会FragmentTransaction的相关方法、了解FragmentManager类、addOnBackStackChangedListener、getBackStackEntryCount、getBackStackEntryAt方法.
j
重要代码:
下面代码主要看Bundle在fragment内部传参。
2)Fragment中可以调用Activity中的字段和方法
fragment中掉activity中的组件:
activity中调用fragment中相关信息:如图,
这里强调为什么调用fragment中的组件,Adapter相关信息呢?这里设计到生命周期的问题。在activity的oncreatView中的时候,只是加载布局,并未填充数据,等。我在显示onResume()【界面数据加载完成】,再获取!
3)接口回掉:
应用场景:
在某些案例中,可能需要Fragment与Activity共享事件。在Fragment内部定义一个回调接口是一个好方法,并且规定由持有它的Activity实现这个回调方法。当Activity通过接口接受回调时,它能在必要时与布局中的其他Fragment共享信息。
例如,如果一个音乐播放器的应用程序在一个Activity中有两个Fragment---一个用来显示歌曲列表(Fragment A),另一个用来显示歌曲信息(Fragment B),然后在列表项目被选中时Fragment A必须告诉Activity,以便它能告诉Fragment B显示对应的歌曲信息。在下面的例子中在Fragment A的内部声明了onMp3ChangedListener接口。
先看一个入门:activity中实现TextView的OnClickListener事件。可是发现TextView中并没有接口回掉,OnClickListener。看源码,TextView的父类View中确实有这个接口OnClickListener.
那么我们自己实现一个CallBack回掉。
步骤:1.定义一个接口--》2)哪个类中要回掉它,哪个类就集成它。 一般要共享事件,那么就在activity中的控件中去绑定它。
简单例子:
定义接口:
控件中定义,让外界可以监听:
使用它的activity去实现接口,并绑定:
理解这个思想后,来看看上面场景的应用:
然后,持有这个Fragment的Activity要实现onMp3ChangedListener接口,并且要重写onMp3Changed()方法把来自Fragment A的事件通知给Fragment B。要确保持有Fragment的Activity实现这个接口, Fragment A 的onAttach()回调方法(当Fragment被添加到Activity时系统调用这个方法)通过类型转换onAttach()传入的Activity来实例化一个onMp3ChangedListener的实例。
如果这个Activity没有实现这个接口,那么Fragment会抛出ClassCastException异常。
如果成功,那么mListener成员就会拥有Activity实现的onMp3ChangedListener对象的引用,以便Fragment A能够通过onMp3ChangedListener接口定义的回调方法和Activity共享事件。例如,Fragment A继承了ListFragment,那么用户每次点击列表项时,系统都会调用Fragment中的onListItemClick()方法,然后调用onMp3Changed()方法和Activity共享事件:
传递给onListItemClick()的position参数是被点击项目的行ID,Activity(或其他的Fragment)使用这个ID从歌曲列表中获取对应的歌曲信息。
工作中遇到这样的一个问题:
MainActivity中嵌套4个Fragment作为底部的四个Tab,每次点击MainActivity下面的四个Tab图标切换到四个Fragment,那么怎么实现每次Fragment切换的需求,并且Fragment每次不会重新实例话,只是影藏和显示的动态切换呢。
最基本的知道fragment相关的FragmentTransaction的相关方法的用法,特别是.replace(),.add(),.show(),.hide()的用法。思路:首先添加【add】fragment进去,然后.show(),.hide()即可.
参考项目中的代码:
private void setSelect(int i) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
hideFragment(transaction);
switch (i) {
case 0:
if (mTab01 == null) {
mTab01 = new MainFragment();
transaction.add(R.id.id_content, mTab01);
} else {
if(!mTab01.isAdded()){
transaction.add(R.id.id_content, mTab01);
}else{
transaction.show(mTab01);
}
//transaction.replace(R.id.id_content, mTab01);
}
tabExerseImg.setImageResource((R.drawable.exerise_y));
id_tab_exerse_tv.setTextColor(Color.parseColor("#55aee5"));
transaction.commit();
break;
case 1:
if (mTab02 == null) {
mTab02 = new ExaminationFragment();
transaction.add(R.id.id_content, mTab02);
} else {
if(!mTab01.isAdded()){
transaction.add(R.id.id_content, mTab02);
}else{
transaction.show(mTab02);
}
//transaction.replace(R.id.id_content, mTab02);
}
//.refreshData();
tabExameImg.setImageResource((R.drawable.examination_y));
id_tab_exame_tv.setTextColor(Color.parseColor("#55aee5"));
transaction.commit();
break;
case 2:
if (mTab03 == null) {
mTab03 = new FoundFragment();
transaction.add(R.id.id_content, mTab03);
} else {
if(!mTab03.isAdded()){
transaction.add(R.id.id_content, mTab03);
}else{
transaction.show(mTab03);
}
}
tabFindImg.setImageResource((R.drawable.found_y));
id_tab_find_tv.setTextColor(Color.parseColor("#55aee5"));
transaction.commit();
break;
case 3:
if (mTab04 == null) {
mTab04 = new MineFragment();
transaction.add(R.id.id_content, mTab04);
} else {
if(!mTab04.isAdded()){
transaction.add(R.id.id_content, mTab04);
}else{
transaction.show(mTab04);
}
}
tabMineImg.setImageResource((R.drawable.mine_y));
id_tab_mine_tv.setTextColor(Color.parseColor("#55aee5"));
transaction.commit();
break;
default:
break;
}
transaction.commit();
}
private void hideFragment(FragmentTransaction transaction) {
if (mTab01 != null) {
transaction.hide(mTab01);
}
if (mTab02 != null) {
transaction.hide(mTab02);
}
if (mTab03 != null) {
transaction.hide(mTab03);
}
if (mTab04 != null) {
transaction.hide(mTab04);
}
}
Fragment应用场景:1.大型设备适配:平板 2.组合控件:ViewPager、ViewGroup 3.界面大量切换的时候【试卷、书签】
fragment的替换、fragment调用activity中的参数和组件、activity调用fragment中的参数、回掉监听事件
1.fragment的替换。先看下面的一张图,应用场景【左边不同位置的单击事件,在右侧显示不同的内容:音乐歌词播放器--》对应歌曲曲目列表和曲目信息】
需要掌握:会FragmentTransaction的相关方法、了解FragmentManager类、addOnBackStackChangedListener、getBackStackEntryCount、getBackStackEntryAt方法.
j
重要代码:
private void showContent(int position) { //新的fragment MyContentFragment contentFragment = MyContentFragment.getInstance(position); //旧的fragment MyContentFragment mf = (MyContentFragment) fm.findFragmentById(R.id.content1); if(mf == null||mf.getMindex()!=position){ //需要将新的fragment替换成旧的 //开启事务 FragmentTransaction ft = fm.beginTransaction();// ft.replace(R.id.content1, contentFragment); ft.addToBackStack("fragment"+position); //提交 ft.commit();
下面代码主要看Bundle在fragment内部传参。
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub //根据星期日期不同,显示不同的内容 Bundle bundle = this.getArguments(); int index = bundle.getInt("index"); this.mIndex = index; String name = bundle.getString("name"); String content = contents[index]; TextView tv = new TextView(getActivity()); tv.setText(name+content); tv.setGravity(Gravity.CENTER); return tv; } public static MyContentFragment getInstance(int index){ MyContentFragment contentFragment = new MyContentFragment();//创建fragment Bundle bundle = new Bundle();// bundle.putInt("index", index); bundle.putString("name", "坑总"); contentFragment.setArguments(bundle);//设置参数进去 return contentFragment; }
2)Fragment中可以调用Activity中的字段和方法
fragment中掉activity中的组件:
//先将dota数据改成activity里面的sleep mActivity = (MainActivity) this.getActivity(); TextView tv = (TextView) mActivity.findViewById(R.id.tv);</span>
activity中调用fragment中相关信息:如图,
这里强调为什么调用fragment中的组件,Adapter相关信息呢?这里设计到生命周期的问题。在activity的oncreatView中的时候,只是加载布局,并未填充数据,等。我在显示onResume()【界面数据加载完成】,再获取!
3)接口回掉:
应用场景:
在某些案例中,可能需要Fragment与Activity共享事件。在Fragment内部定义一个回调接口是一个好方法,并且规定由持有它的Activity实现这个回调方法。当Activity通过接口接受回调时,它能在必要时与布局中的其他Fragment共享信息。
例如,如果一个音乐播放器的应用程序在一个Activity中有两个Fragment---一个用来显示歌曲列表(Fragment A),另一个用来显示歌曲信息(Fragment B),然后在列表项目被选中时Fragment A必须告诉Activity,以便它能告诉Fragment B显示对应的歌曲信息。在下面的例子中在Fragment A的内部声明了onMp3ChangedListener接口。
先看一个入门:activity中实现TextView的OnClickListener事件。可是发现TextView中并没有接口回掉,OnClickListener。看源码,TextView的父类View中确实有这个接口OnClickListener.
那么我们自己实现一个CallBack回掉。
步骤:1.定义一个接口--》2)哪个类中要回掉它,哪个类就集成它。 一般要共享事件,那么就在activity中的控件中去绑定它。
简单例子:
定义接口:
import android.view.View; public interface OnTextViewClickListener { void onTextViewClick(View v); }
控件中定义,让外界可以监听:
public class MyTextView extends View{ private float touchX,touchY; private OnTextViewClickListener onTextViewClickListener; public OnTextViewClickListener getOnTextViewClickListener() { return onTextViewClickListener; } public void setOnTextViewClickListener( OnTextViewClickListener onTextViewClickListener) { this.onTextViewClickListener = onTextViewClickListener; } public MyTextView(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub }
@Override public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: touchX = event.getX(); touchY = event.getY(); break; case MotionEvent.ACTION_UP: float x = event.getX(); float y = event.getY(); Log.i("INFO", "DownX:"+touchX+"----upX:"+x); if(touchX == x &&touchY == y){ //产生了onclick事件 onTextViewClickListener.onTextViewClick(this); } break; default: break; }
使用它的activity去实现接口,并绑定:
public class MainActivity extends Activity implements OnTextViewClickListener{</span>
<span style="font-size:18px;"> //定会回调函数 public void onTextViewClick(View v) { // TODO Auto-generated method stub Toast.makeText(this, "ontextViewClick", 1000).show(); }
理解这个思想后,来看看上面场景的应用:
public static class FragmentA extends ListFragment { ... //持有它的Activity必须实现这个回调方法 public interface onMp3ChangedListener{ public void onMp3Changed(int index);//index表示的是歌曲在列表中的序号 } ... }
然后,持有这个Fragment的Activity要实现onMp3ChangedListener接口,并且要重写onMp3Changed()方法把来自Fragment A的事件通知给Fragment B。要确保持有Fragment的Activity实现这个接口, Fragment A 的onAttach()回调方法(当Fragment被添加到Activity时系统调用这个方法)通过类型转换onAttach()传入的Activity来实例化一个onMp3ChangedListener的实例。
onMp3ChangedListener的实例。 public static class FragmentA extends ListFragment { onMp3ChangedListener mListener; ... @Override public void onAttach(Activity activity) { super.onAttach(activity); try { mListener = (onMp3ChangedListener) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener"); } ... }
如果这个Activity没有实现这个接口,那么Fragment会抛出ClassCastException异常。
如果成功,那么mListener成员就会拥有Activity实现的onMp3ChangedListener对象的引用,以便Fragment A能够通过onMp3ChangedListener接口定义的回调方法和Activity共享事件。例如,Fragment A继承了ListFragment,那么用户每次点击列表项时,系统都会调用Fragment中的onListItemClick()方法,然后调用onMp3Changed()方法和Activity共享事件:
public static class FragmentA extends ListFragment { OnArticleSelectedListener mListener; ... @Override public void onListItemClick(ListView l, View v, int position, long id) { mListener.onMp3Changed(position); } ... }
传递给onListItemClick()的position参数是被点击项目的行ID,Activity(或其他的Fragment)使用这个ID从歌曲列表中获取对应的歌曲信息。
工作中遇到这样的一个问题:
MainActivity中嵌套4个Fragment作为底部的四个Tab,每次点击MainActivity下面的四个Tab图标切换到四个Fragment,那么怎么实现每次Fragment切换的需求,并且Fragment每次不会重新实例话,只是影藏和显示的动态切换呢。
最基本的知道fragment相关的FragmentTransaction的相关方法的用法,特别是.replace(),.add(),.show(),.hide()的用法。思路:首先添加【add】fragment进去,然后.show(),.hide()即可.
参考项目中的代码:
private void setSelect(int i) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
hideFragment(transaction);
switch (i) {
case 0:
if (mTab01 == null) {
mTab01 = new MainFragment();
transaction.add(R.id.id_content, mTab01);
} else {
if(!mTab01.isAdded()){
transaction.add(R.id.id_content, mTab01);
}else{
transaction.show(mTab01);
}
//transaction.replace(R.id.id_content, mTab01);
}
tabExerseImg.setImageResource((R.drawable.exerise_y));
id_tab_exerse_tv.setTextColor(Color.parseColor("#55aee5"));
transaction.commit();
break;
case 1:
if (mTab02 == null) {
mTab02 = new ExaminationFragment();
transaction.add(R.id.id_content, mTab02);
} else {
if(!mTab01.isAdded()){
transaction.add(R.id.id_content, mTab02);
}else{
transaction.show(mTab02);
}
//transaction.replace(R.id.id_content, mTab02);
}
//.refreshData();
tabExameImg.setImageResource((R.drawable.examination_y));
id_tab_exame_tv.setTextColor(Color.parseColor("#55aee5"));
transaction.commit();
break;
case 2:
if (mTab03 == null) {
mTab03 = new FoundFragment();
transaction.add(R.id.id_content, mTab03);
} else {
if(!mTab03.isAdded()){
transaction.add(R.id.id_content, mTab03);
}else{
transaction.show(mTab03);
}
}
tabFindImg.setImageResource((R.drawable.found_y));
id_tab_find_tv.setTextColor(Color.parseColor("#55aee5"));
transaction.commit();
break;
case 3:
if (mTab04 == null) {
mTab04 = new MineFragment();
transaction.add(R.id.id_content, mTab04);
} else {
if(!mTab04.isAdded()){
transaction.add(R.id.id_content, mTab04);
}else{
transaction.show(mTab04);
}
}
tabMineImg.setImageResource((R.drawable.mine_y));
id_tab_mine_tv.setTextColor(Color.parseColor("#55aee5"));
transaction.commit();
break;
default:
break;
}
transaction.commit();
}
private void hideFragment(FragmentTransaction transaction) {
if (mTab01 != null) {
transaction.hide(mTab01);
}
if (mTab02 != null) {
transaction.hide(mTab02);
}
if (mTab03 != null) {
transaction.hide(mTab03);
}
if (mTab04 != null) {
transaction.hide(mTab04);
}
}
Fragment应用场景:1.大型设备适配:平板 2.组合控件:ViewPager、ViewGroup 3.界面大量切换的时候【试卷、书签】
相关文章推荐
- iOS NSLog去掉时间戳及其他输出样式
- 新知识:Java 利用itext填写pdf模板并导出(昨天奋战到深夜四点,知道今天两点终于弄懂)
- Mindjet 14中文版 无法导出pdf文件 解决经验参考
- java.lang.IllegalAccessException:modifiers "private"
- 页游安全攻与防,SWF加密和隐藏密匙
- onInterceptTouchEvent、onTouchEvent、GestureDetector、SimpleOnGestureListener
- 单链表的增删改查
- 用v7包没有发现ActionBarActivity
- 用v7包没有发现ActionBarActivity
- 史上最详细的Android Studio系列教程四--Gradle基础
- oc的try catch & NSError ....
- Android Studio如何更改JDK和SDK的路径?
- 消除SDK更新时的“https://dl-ssl.google.com refused”异常
- JSP自定义标签rtexprvalue属性用法实例分析
- Webstorm9配置SASS编译环境
- Spring基础—装配bean(二)
- sysbench利用fabric磁盘IO测试
- jquery获得option的值和对option进行操作
- MapReduce 中的两表 join 几种方案简介
- ITOO4.1之NuGet发布问题