主界面一般来说都是底部几个按钮,点击按钮可切换不同页面。一般来说我们是用fragment来实现的。给按钮设置监听事件,监听到点击按钮时候 展示对应fragmnt,而实现fragment方式有两种,一种是静态的 建一个继承fragment类重写onCreateView方法 写一个xml文件关联上(这里xml里要写上对应的是哪个fragment文件要不然找不到)然后在主界面xml文件里直接fragment控件引入进来就可以了。但是一般我们不用这种写法,这种简单的fragment还可以 复杂的就不行了。我们一般用第二种 动态的。用法同样需要写一个继承fragment的类及对应xml文件(不需要写对应哪个fragment),不同的是主界面activity的处理,需要这么几步
【1】Activity中获得FragmentManager对象,通过getSupportFragmentManager()
FragmentManager fm = getSupportFragmentManager();
【2】获得FragmentTransaction对象,通过fm.beginTransaction()
FragmentTransaction ft = fm.beginTransaction();
【3】调用add()方法或者repalce()方法加载Fragment;
Fragment fl = new mFragment1(); ft.add(R.id.fragment,fl);
【4】最后调用commit()方法提交事务
ft.commit();
本来这个也挺简单的,因为急着赶项目 于是乎我便在网上找了个示例直接贴过来了(之前也用过fragment 想着没啥坑) 狗血的事情开始了直接报错
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.recanapp/com.example.recanapp.sjjk.SjjkActivity}: java.lang.IllegalArgumentException: No view found for id 0x7f0800f6 (com.example.recanapp:id/sjjk_fdj_fragment) for fragment fdjFragment{93a9f95 (0865f1ea-90ee-43df-aeb4-01e0d5ae908f) id=0x7f0800f6}
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2451)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2511)
at android.app.ActivityThread.access$900(ActivityThread.java:165)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1375)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:150)
at android.app.ActivityThread.main(ActivityThread.java:5621)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:684)
Caused by: java.lang.IllegalArgumentException: No view found for id 0x7f0800f6 (com.example.recanapp:id/sjjk_fdj_fragment) for fragment fdjFragment{93a9f95 (0865f1ea-90ee-43df-aeb4-01e0d5ae908f) id=0x7f0800f6}
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:875)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:434)
找不到对应fragment的view,我便开始排查fragment的xml文件 如图所示
就一个文本框还没开始往里写东西呢 这也没错呀。难道要find一下这个文件结果又报了fragment空对象问题 刚new出来对象这么是空呢 难道是我导入包不对,可是如果是这样原因 应该报对应错呀。于是认认真真排查代码 发现是transaction.add(R.id.one_fragment, onefragment);时候错了。这里应该是装这个fragment容器id而不是fragmen文件的id。我们在activity里面xml文件里会用一个帧布局来装fragment 如图
这个transaction对象add的应该是帧布局也就是装fragment父布局id 而不是fragment本身id
找到问题当然就好解决了
贴上修改后activity核心代码
private TextView tab01, tab02, tab03, tab04;
tab01 = findViewById(R.id.fdj); tab02 = findViewById(R.id.yyxt); tab03 = findViewById(R.id.dqxt); tab04 = findViewById(R.id.qt); /*为四个按钮绑定点击监听*/ tab01.setOnClickListener(this); tab02.setOnClickListener(this); tab03.setOnClickListener(this); tab04.setOnClickListener(this);
/*创建四个Fragment对象*/ private Fragment fdj_Fragment; private Fragment yyxt_Fragment; private Fragment dqxt_Fragment; private Fragment qt_Fragment;
/*将四个Fragment对象创建为对应的Fragment*/ fdj_Fragment = new fdjFragment(); yyxt_Fragment = new yyxtFragment(); dqxt_Fragment = new dqxtFragment(); qt_Fragment = new qtFragment();
/*创建一个FragmentManager和FragmentTransaction*/ private FragmentManager manager; private FragmentTransaction transaction;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //remove title bar 即隐藏标题栏 //requestWindowFeature(Window.FEATURE_NO_TITLE); // 隐藏ActionBar //getSupportActionBar().hide(); //remove notification bar 即全屏 //getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.sjjk_activity); init(); initFragment(); selectTab(1);//默认选中第一个Tab }
@Override public void onClick(View view) { //先将四个Button置为黑色 buttonColor(); switch (view.getId()) { case R.id.fdj: selectTab(1); break; case R.id.yyxt: selectTab(2); break; case R.id.dqxt: selectTab(3); break; case R.id.qt: selectTab(4); break; default: break; }
}
//进行选中Tab的处理 private void selectTab(int i) { //获取FragmentManager对象 FragmentManager manager = getSupportFragmentManager(); //获取FragmentTransaction对象 FragmentTransaction transaction = manager.beginTransaction(); //先隐藏所有的Fragment hideFragments(transaction); switch (i) { //当选中点击的是第一页的Tab时 case 1: //设置第一页的Button为铜色 tab01.setBackgroundResource(R.color.Copper); //如果第一页对应的Fragment没有实例化,则进行实例化,并显示出来 if (fdj_Fragment == null) { fdj_Fragment = new dqxtFragment(); } if (fdj_Fragment.isAdded() == false) { transaction.add(R.id.sjjk_fragment, fdj_Fragment); } transaction.show(fdj_Fragment); break; case 2: tab02.setBackgroundResource(R.color.Copper); if (yyxt_Fragment == null) { yyxt_Fragment = new yyxtFragment(); } if (yyxt_Fragment.isAdded() == false){ transaction.add(R.id.sjjk_fragment, yyxt_Fragment); } transaction.show(yyxt_Fragment); break; case 3: tab03.setBackgroundResource(R.color.Copper); if (dqxt_Fragment == null) { dqxt_Fragment = new dqxtFragment(); } if (dqxt_Fragment.isAdded() == false){ transaction.add(R.id.sjjk_fragment, dqxt_Fragment); } transaction.show(dqxt_Fragment); break; case 4: tab04.setBackgroundResource(R.color.Copper); if (qt_Fragment == null) { qt_Fragment = new qtFragment(); } if(qt_Fragment.isAdded() == false) { transaction.add(R.id.sjjk_fragment, qt_Fragment); } transaction.show(qt_Fragment); break; } //不要忘记提交事务 transaction.commit(); } /*隐藏Fragment*/ private void hideFragments(FragmentTransaction transaction) { if (fdj_Fragment != null) { transaction.hide(fdj_Fragment); } if (yyxt_Fragment != null) { transaction.hide(yyxt_Fragment); } if (dqxt_Fragment != null) { transaction.hide(dqxt_Fragment); } if (qt_Fragment != null) { transaction.hide(qt_Fragment); } } private void buttonColor() { tab01.setBackgroundResource(R.color.black); tab02.setBackgroundResource(R.color.black); tab03.setBackgroundResource(R.color.black); tab04.setBackgroundResource(R.color.black); }