项目源码GIThub:https://github.com/307572384/Fragment
之前搞完一个项目里面使用到fragment但是效果虽然是有但是还有些不是太明白所以今天就作为一个知识的整理。
关于fragment的基础知识可以学习一下这篇文章
Fragment详解之一——概述
静态添加Fragment
第一步先写一个:t_fragment_1.xml
<?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">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这是第一个Fragment"
android:textColor="@color/colorAccent"
android:textSize="35sp"/>
</LinearLayout>
第二步先写一个:t_fragment_2.xml
<?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">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这是第二个Fragment"
android:textColor="@color/colorPrimary"
android:textSize="35sp"/>
</LinearLayout>
第三步绑定Fragment
这里需要注意如果Acitivity使用V4的Fragment包的话那么我们就需要使用V4的包在Fragment中,就是import android.support.v4.app.Fragment;需要与Activity中的import android.support.v4.app.FragmentActivity;这两个需要相同否则在Activity中引用的时候会出现找不到这种情况。
新建一个T_Fragment_1
package com.beta.fragment.Fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.support.v4.app.Fragment;
import com.beta.fragment.R;
//这个第一个Fragment
public class T_Fragment_1 extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.t_fragment_1, container, false);
}
}
新建一个T_Fragment_2
package com.beta.fragment.Fragment;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.beta.fragment.R;
//这是第二个Fragment
public class T_Fragment_2 extends Fragment{
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.t_fragment_2, container, false);
}
}
第四步在Activity中显示
新建一个TActivity
package com.beta.fragment.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import com.beta.fragment.R;
/*静态添加Fragment*/
public class TActivity extends FragmentActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.t_fragment_main);
}
}
到这里我们就可以看到我们自己的Fragmen效果了。
动态Fragment添加
我们需要创建一个t_fragment_main_dt.xml作为我们的主activity的mainlayout其余的Fragment不做更改和变化
<?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">
<Button
android:id="@+id/btn_show_fragment1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="显示Fragment1"/>
<Button
android:id="@+id/btn_show_fragment2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="显示Fragment2"/>
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
新建一个TDActivity
package com.beta.fragment.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import com.beta.fragment.Fragment.T_Fragment_1;
import com.beta.fragment.Fragment.T_Fragment_2;
import com.beta.fragment.R;
/**
* Created by Kevein on 2019/1/23.13:02
*/
//动态添加Fragment
public class TDActivity extends FragmentActivity implements View.OnClickListener {
private Button btn_show_fragment1;
private Button btn_show_fragment2;
private FrameLayout fragment_container;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.t_fragment_main_dt);
initView();
}
private void initView() {
btn_show_fragment1 = (Button) findViewById(R.id.btn_show_fragment1);
btn_show_fragment2 = (Button) findViewById(R.id.btn_show_fragment2);
fragment_container = (FrameLayout) findViewById(R.id.fragment_container);
btn_show_fragment1.setOnClickListener(this);
btn_show_fragment2.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_show_fragment1:
btn_show_fragment1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FragmentManager manager = getSupportFragmentManager();
//新建一个fragment的管理器
FragmentTransaction transaction = manager.beginTransaction();
//控制Fragment的并传输
T_Fragment_1 fragment1 = new T_Fragment_1();//新建一个Fragment对象
transaction.add(R.id.fragment_container,fragment1);
//动态添加fragment1进去
transaction.commit();
}
});
break;
case R.id.btn_show_fragment2:
btn_show_fragment2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
T_Fragment_2 fragment2 =new T_Fragment_2();//新建一个Fragment对象
transaction.add(R.id.fragment_container,fragment2);
transaction.commit();
}
});
break;
}
}
}
然后我们就完成了Fragment的动态添加和静态添加。
让我们来看看效果。
需要进行背景的替换不然单纯文字的颜色改变的话会出现覆盖的情况,也就是第二个的fragment不会自己消失。
实现Fragment的添加和删除还有Replace事件
在我们原来的基础上新增一些代码。
t_fragment_main_dt.xml
<?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">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btn_show_fragment1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="显示Fragment1" />
<Button
android:id="@+id/btn_show_fragment2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="显示Fragment2" />
<Button
android:id="@+id/add_frag1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="添加fragment1" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/add_frag2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="添加fragment2" />
<Button
android:id="@+id/remove_frag1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="移除Fragment1" />
<Button
android:id="@+id/remove_frag2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="移除Fragment2" />
</LinearLayout>
<Button
android:id="@+id/btn_repalce_frag1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="replace Fragment1" />
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Fragment的添加事件写法
private void addFragment(Fragment fragment, String tag) {
FragmentManager manager = getSupportFragmentManager();
//初始化FragmentManager
FragmentTransaction transaction = manager.beginTransaction();
//新建一个transaction用于传输Fragment
transaction.add(R.id.fragment_container, fragment, tag);
transaction.commit();
//开始传输
}
Fragment的删除事件写法
private void removeFragment2() {
FragmentManager manager = getSupportFragmentManager();
Fragment fragment = manager.findFragmentByTag("fragment2");
FragmentTransaction transaction = manager.beginTransaction();
transaction.remove(fragment);
transaction.commit();
/*因为fragment1在fragment2的下方所以我们如果移除的的时候不用tag的话那么我们将不会看到移除的效果*/
}
Fragment的Replace(替代)事件写法
private void replaceFragment1()
{
FragmentManager manager = getSupportFragmentManager();
T_Fragment_2 fragment2 = new T_Fragment_2();
//因为2是在1的下面所以就用2替换掉1,具体看情况而定。
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.fragment_container,fragment2);
transaction.commit();
}
然后我们再看看详细的代码TDActivity
个人建议控件太多的时候可以使用butterknife
ButterKnife使用方法详解
不过我这个是使用LayoutCreator自动生成的控件就暂时不考虑太多乐。
package com.beta.fragment.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import com.beta.fragment.Fragment.T_Fragment_1;
import com.beta.fragment.Fragment.T_Fragment_2;
import com.beta.fragment.R;
//动态删除、添加、替换Fragment
public class TDActivity extends FragmentActivity implements View.OnClickListener {
private Button btn_show_fragment1;
private Button btn_show_fragment2;
private FrameLayout fragment_container;
private Button add_frag1;
private Button add_frag2;
private Button remove_frag1;
private Button remove_frag2;
private Button btn_repalce_frag1;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.t_fragment_main_dt);
initView();
}
private void addFragment(Fragment fragment, String tag) {
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.fragment_container, fragment, tag);
transaction.commit();
}
private void initView() {
btn_show_fragment1 = (Button) findViewById(R.id.btn_show_fragment1);
btn_show_fragment2 = (Button) findViewById(R.id.btn_show_fragment2);
fragment_container = (FrameLayout) findViewById(R.id.fragment_container);
btn_show_fragment1.setOnClickListener(this);
btn_show_fragment2.setOnClickListener(this);
add_frag1 = (Button) findViewById(R.id.add_frag1);
add_frag1.setOnClickListener(this);
add_frag2 = (Button) findViewById(R.id.add_frag2);
add_frag2.setOnClickListener(this);
remove_frag1 = (Button) findViewById(R.id.remove_frag1);
remove_frag1.setOnClickListener(this);
remove_frag2 = (Button) findViewById(R.id.remove_frag2);
remove_frag2.setOnClickListener(this);
btn_repalce_frag1 = (Button) findViewById(R.id.btn_repalce_frag1);
btn_repalce_frag1.setOnClickListener(this);
}
private void removeFragment2() {
FragmentManager manager = getSupportFragmentManager();
Fragment fragment = manager.findFragmentByTag("fragment2");
FragmentTransaction transaction = manager.beginTransaction();
transaction.remove(fragment);
transaction.commit();
/*因为fragment1在fragment2的下方所以我们如果移除的的时候不用tag的话那么我们将不会看到移除的效果*/
}
private void removeFragment1() {
FragmentManager manager = getSupportFragmentManager();
Fragment fragment = manager.findFragmentByTag("fragment1");
FragmentTransaction transaction = manager.beginTransaction();
transaction.remove(fragment);
transaction.commit();
}
private void replaceFragment1()
{
FragmentManager manager = getSupportFragmentManager();
T_Fragment_2 fragment2 = new T_Fragment_2();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.fragment_container,fragment2);
transaction.commit();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_show_fragment1:
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
T_Fragment_1 fragment1 = new T_Fragment_1();//新建一个Fragment对象
transaction.add(R.id.fragment_container, fragment1);
transaction.commit();
break;
case R.id.btn_show_fragment2:
FragmentManager manager2 = getSupportFragmentManager();
FragmentTransaction transaction2 = manager2.beginTransaction();
T_Fragment_2 fragment2 = new T_Fragment_2();//新建一个Fragment对象
transaction2.add(R.id.fragment_container, fragment2);
transaction2.commit();
break;
case R.id.add_frag1:
T_Fragment_1 fragmenta1 = new T_Fragment_1();
addFragment(fragmenta1,"fragment1");
break;
case R.id.add_frag2:
T_Fragment_2 fragmenta2 = new T_Fragment_2();
addFragment(fragmenta2,"fragment2");
break;
case R.id.remove_frag1:
T_Fragment_1 fragment_1 = new T_Fragment_1();
removeFragment1();
break;
case R.id.remove_frag2:
T_Fragment_2 fragment_2 = new T_Fragment_2();
removeFragment2();
break;
case R.id.btn_repalce_frag1:
replaceFragment1();
break;
}
}
}
然后我们来看看运行时的效果。
这里需要注意一下如果不是添加进去的fragment点击删除会出现崩溃的Bug原因就是不是指定添加的Fragmen
更多详细请参考:
Fragment详解之四——管理Fragment(2)
Fragment的隐藏和显示事件
public FragmentTransaction hide(Fragment fragment);//将指定的fragment隐藏不显示
public FragmentTransaction show(Fragment fragment);//将以前hide()过的fragment显示出来
Fragment隐藏事件写法
private void hideFragment1()
{
FragmentManager manager = getSupportFragmentManager();
//创建一个Fragment管理器
Fragment fragment1 = manager.findFragmentByTag("fragment1");
//绑定fragment TAG 为Fragment1
FragmentTransaction transaction = manager.beginTransaction();
//初始化传输
transaction.hide(fragment1);
//隐藏fragment1
transaction.addToBackStack("hide fragment1");
//回滚到隐藏fragment1
transaction.commit();
//开始事件
}
Fragment显示事件写法
private void showFragment1()
{
FragmentManager manager = getSupportFragmentManager();
//创建一个Fragment管理器
Fragment fragment1 = manager.findFragmentByTag("fragment1");
//绑定fragment TAG 为Fragment1
FragmentTransaction transaction = manager.beginTransaction();
//初始化传输
transaction.show(fragment1);
//隐藏fragment1
transaction.addToBackStack("show fragment1");
//回滚到隐藏fragment1
transaction.commit();
//开始事件
}
布局中的添加原来的t_fragment_main_dt.xml中新增这两个Button控件即可。
<Button
android:id="@+id/btn_hide_frag1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="hideFragment1" />
<Button
android:id="@+id/btn_show_frag1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="showFragment1" />
然后我们接着再TDActivity中的OnClick添加这两个即可使用
case R.id.btn_hide_frag1:
hideFragment1();
break;
case R.id.btn_show_frag1:
showFragment1();
break;
让我们来看一下效果
现实中的一些问题如果我们使用replace来切换页面,那么在每次切换的时候,Fragment都会重新实例化,重新加载一边数据,这样非常消耗性能和用户的数据流量。
这是因为replace操作,每次都会把container中的现有的fragment实例清空,然后再把指定的fragment添加进去,就就造成了在切换到以前的fragment时,就会重新实例会fragment。
正确的切换方式是add(),切换时hide(),add()另一个Fragment;再次切换时,只需hide()当前,show()另一个。
这样就能做到多个Fragment切换不重新实例化:(基本算法如下)
public void switchContent(Fragment from, Fragment to) {
if (!to.isAdded()) { // 先判断是否被add过
transaction.hide(from).add(R.id.content_frame, to).commit(); // 隐藏当前的fragment,add下一个到Activity中
} else {
transaction.hide(from).show(to).commit(); // 隐藏当前的fragment,显示下一个
}
}
更多详细请参考:
Fragment详解之四——管理Fragment(2)
Fragment(五)Transaction 源码分析
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/134150.html