【Demo记录】Fragment 返回栈
来源:互联网 发布:cocos2d-js webgl 编辑:程序博客网 时间:2024/06/05 16:31
效果
toast打印的是返回之前显示的fragment的标记
点击返回键时,不会直接退出activity,而是返回到之前显示的Fragment(当前显示的是首页时,直接退出Activity)
Fragment 知识点
1、Fragment和Activity关联的主要方式在于:添加、替换
通过Activity中Fragment的管理器,将Fragment添加到Activity指定的布局中,每一次添加Fragment都会在原界面的基础上添加Fragment,可以理解为在原Fragment的基础上又覆盖了一层,如果Fragment之间背景透明,可以看到各个添加的Fragment内容重叠,所以,一般在第一个将Fragment显示到界面上时使用addFragment方式,要改变Fragment的内容,则通过replaceFragment来进行。替换的方式,不会出现内容重叠的情况。
2、Fragment 返回栈
Fragment 依附于Activity来做内容的显示,当在Activity中点击返回按钮时,这个Activity将会销毁。想点击返回实现Fragment的返回,而不是直接退出Activity,则需要使用到返回栈。
返回栈的相关操作:入栈、出栈、获取返回栈里的个数
入栈:addToBackStack(@Nullable String name);
示例代码:
FragmentManager mSupportFragmentManager = getSupportFragmentManager();mSupportFragmentManager.beginTransaction() .replace(R.id.frameLayout_content, fragments[0], "first") .addToBackStack("first") .commit();
出栈:
popBackStack();//将返回栈里面的栈顶元素pop出栈popBackStack(String name,int flags);//将标记为name之上的元素全部移除,flags表示标记为name的这个元素是否需要出栈,0表示不需要,POP_BACK_STACK_INCLUSIVE表示该元素需要出栈。popBackStack(int id,int flags);//将栈里面位置在id上面的元素都移除,根据flags来判断是否移除该位置的元素。popBackStackImmediate();//和上面相比,只是多了个Immediate 表示立即执行,其余的参数 则和上面一致。popBackStackImmediate(String name,int flags);popBackStackImmediate(int id,int flags);
获取返回栈中元素的个数
getBackStackEntryCount();
期间遇到的问题:在onCreate中执行获取的个数一直为0,解决方案:
在获取个数之前 使用executePendingTransitions();
最后还有一种获取元素个数有问题的操作,在onPressBack中进行的操作,详情 直接跳到文章末尾。
解决方案参考自:
http://stackoverflow.com/questions/13964409/why-fragmentmanagers-getbackstackentrycount-return-zero
Demo
界面设计:
Activity Layout:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.tjstudy.radiogrouptab.MainActivity"> <FrameLayout android:id="@+id/frameLayout_content" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> <RadioGroup android:id="@+id/radioGroup_tabs" android:layout_width="match_parent" android:layout_height="?android:actionBarSize" android:orientation="horizontal"> <RadioButton android:id="@+id/tab1" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="1" android:background="@drawable/selector_tabs" android:button="@null" android:gravity="center" android:text="第一个界面" /> <RadioButton android:id="@+id/tab2" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="1" android:button="@null" android:gravity="center" android:background="@drawable/selector_tabs" android:text="第二个界面" /> <RadioButton android:id="@+id/tab3" android:layout_width="wrap_content" android:layout_height="match_parent" android:background="@drawable/selector_tabs" android:layout_weight="1" android:button="@null" android:gravity="center" android:text="第三个界面" /> </RadioGroup></LinearLayout>
其中涉及到 selector_tabs 是选择器
背景颜色选择器
<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_checked="true"> <color android:color="#cc0000" /> </item> <item> <color android:color="#00cc00" /> </item></selector>
选择器相关:
http://blog.csdn.net/u012391876/article/details/52243797
三个Fragment准备,没有进行其他操作,界面指显示了一个TextView 显示是第几页 第一个Fragment 参考代码
/** * 第一个界面 tab1 */public class FirstFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_first, container, false); }}
<FrameLayout 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.tjstudy.radiogrouptab.fragment.FirstFragment"> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="第一个界面" /></FrameLayout>
其他两个Fragment的代码和这个类似-略
重点:Activity的操作
1、 界面默认显示第一页,addFragment1
2、 点击tab的时候,replaceFragment
3、 点击返回键的处理,回退到首页-默认的第一页,当前页已经是首页的情况下,直接结束这个activity。
package com.tjstudy.radiogrouptab;public class MainActivity extends AppCompatActivity implements View.OnClickListener { private RadioButton tab1; private RadioButton tab2; private RadioButton tab3; private FragmentManager mSupportFragmentManager; private Fragment[] fragments; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); initListener(); } private void initListener() { tab1.setOnClickListener(this); tab2.setOnClickListener(this); tab3.setOnClickListener(this); } private void initView() { tab1 = (RadioButton) findViewById(R.id.tab1); tab2 = (RadioButton) findViewById(R.id.tab2); tab3 = (RadioButton) findViewById(R.id.tab3); //初始化界面 mSupportFragmentManager = getSupportFragmentManager(); fragments = new Fragment[]{new FirstFragment(), new SecondFragment(), new ThirdFragment()}; mSupportFragmentManager.beginTransaction() .add(R.id.frameLayout_content, fragments[0], "first")// 第一个不添加到栈里面 添加到栈之后 点击返回按钮时,会将fragment出栈 这里出栈之后界面就变成空白的了// .addToBackStack("first") .commit(); tab1.setChecked(true); } @Override public void onClick(View v) { int id = v.getId(); switch (id) { case R.id.tab1: mSupportFragmentManager.beginTransaction() .replace(R.id.frameLayout_content, fragments[0], "first") .addToBackStack("first")//添加到返回栈 .commit(); break; case R.id.tab2: mSupportFragmentManager.beginTransaction() .replace(R.id.frameLayout_content, fragments[1], "second") .addToBackStack("second") .commit(); break; case R.id.tab3: mSupportFragmentManager.beginTransaction() .replace(R.id.frameLayout_content, fragments[2], "third") .addToBackStack("third") .commit(); break; } } @Override public void onBackPressed() { //需要判断当前界面是不是 就是默认的界面 int backStackEntryCount = mSupportFragmentManager.getBackStackEntryCount(); Toast.makeText(this, "backStackEntryCount:" + backStackEntryCount, Toast.LENGTH_SHORT).show(); if (backStackEntryCount > 0) { //1、获取返回栈 栈顶元素的标记 String name = mSupportFragmentManager.getBackStackEntryAt(backStackEntryCount - 1).getName(); Toast.makeText(this, name, Toast.LENGTH_SHORT).show(); //2、判断栈顶元素是不是默认界面 Toast.makeText(this, "getTag().name:" + fragments[0].getTag().equalsIgnoreCase(name), Toast.LENGTH_SHORT).show(); if (fragments[0].getTag().equalsIgnoreCase(name)) { //2.1 是默认界面则 直接退出activity finish(); } else { //将栈里面的元素全部回退// while (mSupportFragmentManager.getBackStackEntryCount() > 0) {// mSupportFragmentManager.popBackStackImmediate();// } //2.2 不是默认界面,则将返回栈中的元素全部出栈--由于第一个界面没有添加到栈 显示的则是第一个界面 mSupportFragmentManager.popBackStackImmediate(0, FragmentManager.POP_BACK_STACK_INCLUSIVE); } tab1.setChecked(true); } else { finish(); } }}
为什么在第一次操作添加Fragment到界面上时,不将其添加到返回栈中?
Fragment被添加到返回栈中,点击返回键时,会先执行将Fragment从返回栈中移除的操作,第一次添加Fragment时,将该Fragment添加到返回栈中,此时点返回键时,Fragment被移除,此时界面Fragment区域就变成一片空白了。
获取返回栈中元素个数遇到的问题:
在onBackPress中,获取返回栈元素个数 不是预期的值(比预期值少1),没有达到预期效果。解决方案参考上面提供的网址。
super.onPress();影响了相关代码的执行,获取返回栈的个数和进行出栈操作在super.onPress之前执行,由于将super.onPress放到后面,activity会直接退出,这里没有使用super.onPress方法,而是改用finish直接结束activity.
Demo源码
http://download.csdn.net/detail/u012391876/9729927
- 【Demo记录】Fragment 返回栈
- Fragment返回栈
- Fragment demo
- fragment demo
- Fragment demo
- fragment 加入返回栈失效
- Fragment栈结构压栈弹栈以及Demo
- Fragment返回Fragment
- 记录一下 fragment跳转后切换tabhost 返回之前tab 再按返回键失败
- Fragment记录
- Demo记录
- Fragment的生命周期和返回栈
- Android Fragment 在返回栈popBackStack() ,返回时onResume问题
- android Fragment demo学习
- android Fragment demo学习
- fragment的入门DEMO
- Fragment - 用法+demo
- Fragment复用Demo
- 上传文件至数据库并下载
- git 工作常用命令
- H5代码编写标准步骤
- 大神养成之路上的经验教训,持续不定期更新ing
- jQuery的动画-上下滑动
- 【Demo记录】Fragment 返回栈
- OpenSSL命令---ciphers
- 《Redis官方文档》用Redis构建分布式锁
- 输入函数对比
- 图片文件读取到内存,然后返回内存中图片,用于解除锁定
- OpenGL ES 2.0 笔记 - 着色语言的内置函数
- RecycleView之 DiffUtil的使用
- jQuery
- 数据结构与算法之Josephus问题(用Java解决)