Android应用主界面Tab切换框架详解之Fragment
来源:互联网 发布:js 读取ios沙盒文件 编辑:程序博客网 时间:2024/05/18 16:16
概述
- 时下APP主流主界面Tab切换框架之一 --- Fragment 的搭建。
- Fragment作为内容区域:MainActivity只作为一个调度器,支配Fragment的显示和隐藏,使得管理的控件事件等不需放在MainActivity中造成代码冗长,便于复用及后期维护。
- 解决 ' 切换Tab反复初始化Fragment影响性能、增加流量消耗 ' 问题。
- 解决 ' 横竖屏切换导致内容重叠 ' 问题。
- 源码:https://github.com/tyyecec/EczomFrame
代码详解
1. 主界面布局解析。
<RadioButton style="@style/tab_style" android:id="@+id/rb_e" android:drawableTop="@drawable/rb_e_selector" />// RadioButton抽取style<style name="tab_style"> <item name="android:layout_width">0dp</item> <item name="android:layout_height">wrap_content</item> <item name="android:layout_gravity">center_vertical</item> <item name="android:button">@null</item> <item name="android:background">@null</item> <item name="android:gravity">center</item> <item name="android:layout_weight">1</item> <item name="android:paddingTop">8dp</item></style>// RadioButton选择器<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_checked="true" android:drawable="@drawable/e_pressed" /> <item android:drawable="@drawable/e_normal" /></selector>
2. 创建BaseFragment抽象类继承Fragment便于代码复用。
// 在onCreate()中getActivity()得到上下文bfContext// 在onCreateView()中initView()// 在onActivityCreated()中initData()// 由子类实现不同的视图效果public abstract View initView();// 子类需联网请求数据时重写public void initData() { }
3. 创建EFragment | CFragment | ZFragment | OFragment | MFragment继承BaseFragment,另四个类将E改为对应字母。
public class EFragment extends BaseFragment { private TextView textView; @Override public View initView() { textView = new TextView(bfContext); textView.setGravity(Gravity.CENTER); textView.setTextSize(70); return textView; } @Override public void initData() { super.initData(); textView.setText("E"); }}
4. 在MainActivity onCreate()中initFragment(),初始化各Fragment 。
// 各Fragment实例private EFragment eFragment;private CFragment cFragment;private ZFragment zFragment;private OFragment oFragment;private MFragment mFragment;private void initFragment() { eFragment = new EFragment(); cFragment = new CFragment(); zFragment = new ZFragment(); oFragment = new OFragment(); mFragment = new MFragment();}
5. 在MainActivity onCreate()中initListener(),监听RadioGroup选择事件。
private void initListener() { rgTab.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup radioGroup, int i) { Fragment fragment = null; switch (i) { case R.id.rb_e: fragment = eFragment; break; case R.id.rb_c: fragment = cFragment; break; case R.id.rb_z: fragment = zFragment; break; case R.id.rb_o: fragment = oFragment; break; case R.id.rb_m: fragment = mFragment; break; } // 切换对应Fragment switchFragment(cacheFragment, fragment); } }); // 默认选择E rgTab.check(R.id.rb_e);}
6. 切换对应Fragment 。
由于replace()会导致每次切换Tab都重新初始化Fragment,造成性能上的影响及流量的多余消耗。此次,采用add() + hide() + show()的方式实现Fragment只初始化一次。
7. 解决 ' 切换Tab反复初始化Fragment影响性能、增加流量消耗 ' 问题。
// 当前Fragment缓存private Fragment cacheFragment;private void switchFragment(Fragment nowFragment, Fragment toFragment) { if (nowFragment != toFragment) { // 缓存即将切换的Fragment,以便下一次对比判断 cacheFragment = toFragment; // 开启事物 FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); // 判断即将切换的Fragment是否add过 if (!toFragment.isAdded()) { // 初始无缓存,需判断 if (nowFragment != null) { // 隐藏当前Fragment ft.hide(nowFragment); } // 添加即将切换的Fragment,并提交事物 ft.add(R.id.fl_main, toFragment).commit(); } else { // 初始无缓存,需判断 if (nowFragment != null) { // 隐藏当前Fragment ft.hide(nowFragment); } // 显示即将切换的Fragment,并提交事物 ft.show(toFragment).commit(); } }}
8. 解决 ' 横竖屏切换导致内容重叠 ' 问题。
// AndroidManifest.xml中配置configChanges属性,禁止切换时重新加载Activity<activity android:name=".activity.MainActivity" android:configChanges="orientation|screenSize|keyboardHidden" />
完整代码
1. 欢迎界面 --- WelcomeActivity.java
package com.eczom.eczomframe.activity;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.os.Handler;import com.eczom.eczomframe.R;public class WelcomeActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_welcome); //2s后进入主界面 new Handler().postDelayed(new Runnable() { @Override public void run() { startActivity(new Intent(WelcomeActivity.this,MainActivity.class)); finish(); } },2000); }}
2. 主界面 --- activity_main.xml
<?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:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.eczom.eczomframe.activity.MainActivity"> <include layout="@layout/title" /> <FrameLayout android:id="@+id/fl_main" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:background="#DDDDDD" /> <RadioGroup android:id="@+id/rg_tab" android:layout_width="match_parent" android:layout_height="50dp" android:background="#ffffff" android:orientation="horizontal"> <RadioButton style="@style/tab_style" android:id="@+id/rb_e" android:drawableTop="@drawable/rb_e_selector" /> <RadioButton android:id="@+id/rb_c" style="@style/tab_style" android:drawableTop="@drawable/rb_c_selector" /> <RadioButton android:id="@+id/rb_z" style="@style/tab_style" android:drawableTop="@drawable/rb_z_selector" /> <RadioButton android:id="@+id/rb_o" style="@style/tab_style" android:drawableTop="@drawable/rb_o_selector" /> <RadioButton android:id="@+id/rb_m" style="@style/tab_style" android:drawableTop="@drawable/rb_m_selector" /> </RadioGroup></LinearLayout>
3. 主界面 --- MainActivity.java
package com.eczom.eczomframe.activity;import android.os.Bundle;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentActivity;import android.support.v4.app.FragmentTransaction;import android.widget.RadioGroup;import com.eczom.eczomframe.R;import com.eczom.eczomframe.fragment.CFragment;import com.eczom.eczomframe.fragment.EFragment;import com.eczom.eczomframe.fragment.MFragment;import com.eczom.eczomframe.fragment.OFragment;import com.eczom.eczomframe.fragment.ZFragment;import butterknife.BindView;import butterknife.ButterKnife;public class MainActivity extends FragmentActivity { @BindView(R.id.rg_tab) RadioGroup rgTab; // 各Fragment实例 private EFragment eFragment; private CFragment cFragment; private ZFragment zFragment; private OFragment oFragment; private MFragment mFragment; // 当前Fragment缓存 private Fragment cacheFragment; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); initFragment(); initListener(); } private void initFragment() { // 初始化各Fragment eFragment = new EFragment(); cFragment = new CFragment(); zFragment = new ZFragment(); oFragment = new OFragment(); mFragment = new MFragment(); } private void initListener() { // 监听RadioGroup选择事件 rgTab.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup radioGroup, int i) { Fragment fragment = null; switch (i) { case R.id.rb_e: fragment = eFragment; break; case R.id.rb_c: fragment = cFragment; break; case R.id.rb_z: fragment = zFragment; break; case R.id.rb_o: fragment = oFragment; break; case R.id.rb_m: fragment = mFragment; break; } // 切换对应Fragment switchFragment(cacheFragment, fragment); } }); // 默认选择E rgTab.check(R.id.rb_e); } private void switchFragment(Fragment nowFragment, Fragment toFragment) { if (nowFragment != toFragment) { // 缓存即将切换的Fragment,以便下一次对比判断 cacheFragment = toFragment; // 开启事物 FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); // 判断即将切换的Fragment是否add过 if (!toFragment.isAdded()) { // 初始无缓存,需判断 if (nowFragment != null) { // 隐藏当前Fragment ft.hide(nowFragment); } // 添加即将切换的Fragment,并提交事物 ft.add(R.id.fl_main, toFragment).commit(); } else { // 初始无缓存,需判断 if (nowFragment != null) { // 隐藏当前Fragment ft.hide(nowFragment); } // 显示即将切换的Fragment,并提交事物 ft.show(toFragment).commit(); } } }}
最终效果
0 0
- Android应用主界面Tab切换框架详解之Fragment
- Android Tab切换之Fragment方法
- [Android] 使用 Fragment 实现底部 Tab 切换界面
- android Fragment实现APP主界面Tab页面切换和点击事件
- Android应用经典主界面框架之二:仿网易新闻客户端、CSDN 客户端 (Fragment ViewPager)
- Android应用经典主界面框架之二:仿网易新闻客户端、CSDN 客户端 (Fragment ViewPager)
- Android应用经典主界面框架之二:仿网易新闻客户端、CSDN 客户端 (Fragment ViewPager)
- Android应用经典主界面框架之二:仿网易新闻客户端、CSDN 客户端 (Fragment ViewPager)
- Android应用经典主界面框架之二:仿网易新闻客户端、CSDN 客户端 (Fragment ViewPager)
- Android应用经典主界面框架之二:仿网易新闻客户端、CSDN 客户端 (Fragment ViewPager)
- Android fragment+viewpager 切换Tab
- android Tab 类型切换界面
- [Android] Android项目Tab类型主界面Fragment+TabPageIndicator+ViewPager
- Android项目Tab类型主界面大总结 Fragment+ViewPager
- Android之Fragment实现界面切换学习笔记
- android:使用fragment实现tab切换
- Android UI 详解之ActionBar+ViewPager+Fragment 实现滑动Tab
- [应用妹 --第二篇 主界面Tab搭建] android应用市场之快速开发
- Vi语法总结
- JQueryEasyUI 组件 datagrid组件(数据表格组件)
- 数据结构 — 查找I
- 485. Max Consecutive Ones
- SPOJ 纽约大学ACM第一题TEST
- Android应用主界面Tab切换框架详解之Fragment
- 数据结构 — 查找II
- 数据结构 — 查找II
- [问题笔记]串口只能显示不能输入
- C++ 建立本地网络服务器 (Boost.Asio库)
- 欢迎使用CSDN-markdown编辑器
- 520. Detect Capital
- Linux常见目录
- 欢迎使用CSDN-markdown编辑器