Fragment的优雅实践并杂谈细节

作者 : 开心源码 本文共6659个字,预计阅读时间需要17分钟 发布时间: 2022-05-12 共173人阅读

尽管Fragment设计的初衷是为了大屏幕的平板设施,但走着走着它目前已经广泛应用于我们的手机设施上了。比方下面我们常见的设计即可以使用fragment实现,先来个图片三连:

program.pngRead.pngmanageMoney.png

对于这个设计有很多种方式实现,比方可以使用TabLayout+Fragment,不过我想快速且优雅的实现,所以最终借助了一个第三方库实现下面的布局Table,采用了BottomNavigation+Fragment的方式。

BottomNavigation的GitHub地址:
armcha/LuseenBottomNavigation

也可以直接

implementation 'com.github.armcha:LuseenBottomNavigation:1.8.2'

那么下面就开始本文的重点内容了

一、主页面布局

activity_main.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:id="@+id/main_content"    android:layout_width="match_parent"    android:layout_height="match_parent">  <FrameLayout      android:id="@+id/fr_content"      android:layout_width="match_parent"      android:layout_height="match_parent">  </FrameLayout><com.luseen.luseenbottomnavigation.BottomNavigation.BottomNavigationView    android:id="@+id/bnv_item"    android:layout_width="match_parent"    android:layout_height="30dp"    app:bnv_colored_background="false"    android:layout_alignParentBottom="true"></com.luseen.luseenbottomnavigation.BottomNavigation.BottomNavigationView></RelativeLayout>

主页面的布局很简洁,FrameLayout就是展现fragment内容的地方,下面的BottomNavigationView就是底部导航栏控件。

二、实现底部导航栏布局效果

public class MainActivity extends AppCompatActivity {    @BindView(R.id.fr_content)    FrameLayout frContent;    @BindView(R.id.bnv_item)    BottomNavigationView mBottomView;    //...    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        ButterKnife.bind(this);        BottomNavigationItem bottomNavigationItem=new BottomNavigationItem("首页",                ContextCompat.getColor(this,R.color.mainPager),R.drawable.loudspeaker);        BottomNavigationItem bottomNavigationItem1=new BottomNavigationItem("编程",                ContextCompat.getColor(this,R.color.programCode),R.drawable.program);        BottomNavigationItem bottomNavigationItem2=new BottomNavigationItem("读书",                ContextCompat.getColor(this,R.color.readPager),R.drawable.book);        BottomNavigationItem bottomNavigationItem3=new BottomNavigationItem("理财",                ContextCompat.getColor(this,R.color.manageMoneyPager),R.drawable.money);        mBottomView.addTab(bottomNavigationItem);        mBottomView.addTab(bottomNavigationItem1);        mBottomView.addTab(bottomNavigationItem2);        mBottomView.addTab(bottomNavigationItem3);        //...        }

代码很清晰,创立多个底部的每个item实例,再将其加入到view中。

这里我做了一下怪[啊哈哈],使用了ButterKnife来获取控件,你可以不用,按照最原始的方式就可。到这里已经完成了一小半了,够快吧….

三、准备一个Fragment

这里我们创立了4个fragment,分别是首页、编程、读书和理财。我就拿理财来举例了(最近迷上了理财这个东西),其余三个都是一样的,或者许这就是传说中的举一反三吧。

ManageMoneyFragment.class

public class ManageMoneyFragment extends Fragment {    private static final String TAG = "ManageMoneyFragment";    @Override    public void onAttach(Context context) {        Log.d(TAG, "onAttach: ");        super.onAttach(context);    }    @Nullable    @Override    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {        Log.d(TAG, "onCreateView: ");        return inflater.inflate(R.layout.manage_money_fragment,null);    }    @Override    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {        Log.d(TAG, "onViewCreated: ");        super.onViewCreated(view, savedInstanceState);    }    @Override    public void onActivityCreated(@Nullable Bundle savedInstanceState) {        Log.d(TAG, "onActivityCreated: ");        super.onActivityCreated(savedInstanceState);    }    @Override    public void onCreate(@Nullable Bundle savedInstanceState) {        Log.d(TAG, "onCreate: ");        super.onCreate(savedInstanceState);    }    @Override    public void onStart() {        Log.d(TAG, "onStart: ");        super.onStart();    }    @Override    public void onResume() {        Log.d(TAG, "onResume: ");        super.onResume();    }    @Override    public void onPause() {        Log.d(TAG, "onPause: ");        super.onPause();    }    @Override    public void onStop() {        Log.d(TAG, "onStop: ");        super.onStop();    }    @Override    public void onDestroy() {        Log.d(TAG, "onDestroy: ");        super.onDestroy();    }    @Override    public void onDestroyView() {        Log.d(TAG, "onDestroyView: ");        super.onDestroyView();    }    @Override    public void onDetach() {        Log.d(TAG, "onDetach: ");        super.onDetach();    }}

什么鬼,写了这么长一串感觉啥也没干啊,这不都是activity的生命周期方法嘛。哈哈,精确的这些都是Fragment的生命周期方法,写这些是为了下面小谈少量它的生命周期。

其实Fragment可以算Android里的第五大组件了,之前,有人把View作为第五大组件,但是因为相对于四大组件来说它没有生命周期,所以从这个角度来说,Fragment更适合称为第五大组件。

创立一个fragment到客户能看到的状态经历了以下的生命周期

创立fragment.png

同样销毁一个fragment会经历如下生命周期

销毁fragment.png

或者许这张图看起来会更清晰明了一点

fragment生命周期.png

相比于Activity,它的生命周期方法多了几个,比方它最开始的方法走的是onAttach,销毁的最后一步是onDetach方法,它们是一对方法由于fragment是需要依附Activity存在的,所以就有了这样的两个方法。

好,可以回来了,在上面代码中和我们的页面view直接相关的是 onCreateView方法,用inflater.inflate方法把fragment的页面布局填充进去就好了

    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {        Log.d(TAG, "onCreateView: ");        return inflater.inflate(R.layout.manage_money_fragment,null);    }

随意写了一个简单的布局

R.layout.manage_money_fragment

<?xml version="1.0" encoding="utf-8"?><RelativeLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/frag_manage_money"    android:layout_width="match_parent"    android:layout_height="match_parent">  <TextView      android:layout_width="wrap_content"      android:layout_height="wrap_content"      android:textSize="35sp"      android:layout_centerInParent="true"      android:text="  在别人贪婪的时候,我们要恐惧;  在别人恐惧的时候,我们要贪婪;"/></RelativeLayout>

四、依附到Activity中

这是最后一步也是最关键的一步,fragment是需要依附到Activity中的。

在底部的导航栏view中,是有个点击方法的,通过这个点击方法我们对每个item进行选择,从而切换到相应的fragment

public class MainActivity extends AppCompatActivity {    //当前的fragment    private Fragment mCurrFragment=new Fragment();    //理财的fragment    private ManageMoneyFragment mManageMoneyFragment=new ManageMoneyFragment();    //编程的fragment    private ProgramFragment mProgramFragment=new ProgramFragment();    //阅读的fragment    private ReadFragment mReadFragment=new ReadFragment();    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //....省略上面已展现的        //点击底部按钮选择对应的fragment        mBottomView.setOnBottomNavigationItemClickListener(new OnBottomNavigationItemClickListener() {            @Override            public void onNavigationItemClick(int index) {                switch (index){                    case 0:                        skipToHome();                        break;                    case 1:                       skipToProgram();                        break;                    case 2:                        skipToRead();                        break;                    case 3:                        skipToManage();                        break;                    default:                        break;                }            }        });    }    //跳转到理财fragment    private void skipToManage() {       switchFragment(mManageMoneyFragment);    }        //.....

由于在增加导航栏的item时,它的内部实现是ArrayList,所以只要要判断它的index即可以获取对应的item了。

选择完后,进行fragment的展现。这里我们使用的hide和show的方式,对于没有增加到ArrayList的,需要先增加再展现,对于已经增加过的我们直接展现就好了,注意在展现之前要将当前展现的先隐藏。

对于隐藏这样的方式就有个好处,我们不需要重复创立它的实例,节省了不必要消耗的性能和客户的流量。

  private void switchFragment(Fragment targetFragment){        FragmentTransaction fragmentTransaction=getSupportFragmentManager().beginTransaction();         //隐藏目前的fragment,展现目标fragment        if(!targetFragment.isAdded()){            fragmentTransaction.hide(mCurrFragment)             .add(R.id.fr_content,targetFragment,targetFragment.getClass().getName())                    .commit();        }else {            fragmentTransaction.hide(mCurrFragment)                    .show(targetFragment)                    .commit();        }        mCurrFragment=targetFragment;    }

到这里,就实现了笔者最开始的素质三连图的最后一张了。对于其余两张图我们只要要再增加两个fragment,再依附到Activity中就ok了.整个过程还是很优雅的哈[蜜汁微笑QAQ]

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » Fragment的优雅实践并杂谈细节

发表回复