| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 移动开发 -> 仿qq底部Tab导航,安卓app开发软件 -> 正文阅读 |
|
[移动开发]仿qq底部Tab导航,安卓app开发软件 |
运行上述代码及可以看到如下效果图使用RadioGroup和RadioButton实现仿qq底部切换 第一步 ,先看布局文件<?xml version="1.0" encoding="utf-8"?><LinearLayout android:id="@+id/activity_second_style" xmlns:android=“http://schemas.android.com/apk/res/android” android:layout_width=“match_parent” android:layout_height=“match_parent” android:orientation=“vertical” <FrameLayout android:id="@+id/fl" android:layout_width=“match_parent” android:layout_height=“0dp” android:layout_weight=“1”> <RadioGroup android:id="@+id/rg" android:layout_width=“match_parent” android:layout_height=“wrap_content” android:orientation=“horizontal” <RadioButton android:id="@+id/rb_home" style="@style/bottom_tab" android:drawableTop="@drawable/sel_home" android:text=“首页”/> <RadioButton android:id="@+id/rb_course" style="@style/bottom_tab" android:drawableTop="@drawable/sel_course" android:text=“课程”/> <RadioButton android:id="@+id/rb_direct_seeding" style="@style/bottom_tab" android:drawableTop="@drawable/sel_direct_seeding" android:text=“直播”/> <RadioButton android:id="@+id/rb_me" style="@style/bottom_tab" android:drawableTop="@drawable/sel_me" android:text=“我的”/> 其实每一个tab的选中时利用RadioGroup中RadioButton的互相排斥的特性,即每一次只能选中一个 RadioButton 至于bottom_tab的style,只不过是将相同的arr提取出来,减少布局的代码量和方便统一修改而已,平时我们在写布局代码 的时候也可以这样 第二步,我们来看一下Activity的 代码public class ThreeActivity extends AppCompatActivity { FrameLayout mFl; RadioGroup mRg; private FragmentManager mFragmentManager; private int position = 0; public static final String[] mTiltles = new String[]{ “首页”, “课程”, “直播”, “个人” }; private List mFragments; private Fragment mCurFragment; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_three); mFl = (FrameLayout) findViewById(R.id.fl); mRg = (RadioGroup) findViewById(R.id.rg); mFragments = new ArrayList<>(); for (int i = 0; i < mTiltles.length; i++) { ItemFragement itemFragement = ItemFragement.newInstance(mTiltles[i]); mFragments.add(itemFragement); } mCurFragment = mFragments.get(position); replaceFragment(mCurFragment); ((RadioButton)mRg.getChildAt(position)).setChecked(true); initListener(); } private void initListener() { mRg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { RadioButton radioButton = (RadioButton) group.findViewById(checkedId); if (false == radioButton.isChecked()) { return; } switch (checkedId) { case R.id.rb_home: position = 0; break; case R.id.rb_course: position = 1; break; case R.id.rb_direct_seeding: position = 2; break; case R.id.rb_me: position = 3; break; default: position = 0; break; } LUtils.i(“position==” + position); Fragment to = mFragments.get(position); showFragment(mCurFragment, to); mCurFragment = to; } }); } private void showFragment(Fragment from, Fragment to) { FragmentManager supportFragmentManager = getSupportFragmentManager(); FragmentTransaction transaction = supportFragmentManager.beginTransaction(); if (!to.isAdded()) { // 先判断是否被add过 transaction.hide(from).add(R.id.fl, to).commit(); // 隐藏当前的fragment,add下一个到Activity中 } else { transaction.hide(from).show(to).commit(); // 隐藏当前的fragment,显示下一个 } } /**
*/ private void replaceFragment(Fragment fragmeny) { FragmentManager supportFragmentManager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction(); fragmentTransaction.replace(R.id.fl, fragmeny).commit(); } } 思路解析
mFragments = new ArrayList<>(); for (int i = 0; i < mTiltles.length; i++) { ItemFragement itemFragement = ItemFragement.newInstance(mTiltles[i]); mFragments.add(itemFragement); } mCurFragment = mFragments.get(position); replaceFragment(mCurFragment); ((RadioButton)mRg.getChildAt(position)).setChecked(true); private void replaceFragment(Fragment fragmeny) { FragmentManager supportFragmentManager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction(); fragmentTransaction.replace(R.id.fl, fragmeny).commit(); }
mRg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { RadioButton radioButton = (RadioButton) group.findViewById(checkedId); if (false == radioButton.isChecked()) { return; } switch (checkedId) { case R.id.rb_home: position = 0; break; case R.id.rb_course: position = 1; break; case R.id.rb_direct_seeding: position = 2; break; case R.id.rb_me: position = 3; break; default: position = 0; break; } LUtils.i(“position==” + position); Fragment to = mFragments.get(position); showFragment(mCurFragment, to); mCurFragment = to; } }); 使用RadioGroup和ViewPager 实现可以滑动切换的仿qq底部Tab切换 第一步,我们 同样先看布局代码<?xml version="1.0" encoding="utf-8"?><LinearLayout android:id="@+id/activity_second_style" xmlns:android=“http://schemas.android.com/apk/res/android” android:layout_width=“match_parent” android:layout_height=“match_parent” android:orientation=“vertical” <android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width=“match_parent” android:layout_height=“0dp” android:layout_weight=“1”> </android.support.v4.view.ViewPager> <RadioGroup android:id="@+id/rg" android:layout_width=“match_parent” android:layout_height=“wrap_content” android:orientation=“horizontal” <RadioButton android:id="@+id/rb_home" style="@style/bottom_tab" android:drawableTop="@drawable/sel_home" android:text=“首页”/> <RadioButton android:id="@+id/rb_course" style="@style/bottom_tab" android:drawableTop="@drawable/sel_course" android:text=“课程”/> <RadioButton android:id="@+id/rb_direct_seeding" style="@style/bottom_tab" android:drawableTop="@drawable/sel_direct_seeding" android:text=“直播”/> <RadioButton android:id="@+id/rb_me" style="@style/bottom_tab" android:drawableTop="@drawable/sel_me" android:text=“我的”/> 第二步,我们一起来看一下Activity代码public class SecondStyleActivity extends AppCompatActivity { public static final String[] mTiltles = new String[]{ “首页”, “课程”, “直播”, “个人” }; private List mFragments; ViewPager mViewPager; RadioGroup mRg; pr
ivate int position = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second_style); mViewPager = (ViewPager) findViewById(R.id.viewPager); mRg = (RadioGroup) findViewById(R.id.rg); initListener(); initData(); } private void initData() { mFragments = new ArrayList<>(); for (int i = 0; i < mTiltles.length; i++) { ItemFragement itemFragement = ItemFragement.newInstance(mTiltles[i]); mFragments.add(itemFragement); } BaseFragmentAdapter fragmentAdapter = new BaseFragmentAdapter (getSupportFragmentManager(), mFragments, mTiltles); mViewPager.setAdapter(fragmentAdapter); mViewPager.setCurrentItem(position); ((RadioButton) mRg.getChildAt(position)).setChecked(true); } private void initListener() { mViewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { @Override public void onPageSelected(int position) { RadioButton radioButton = (RadioButton) mRg.getChildAt(position); radioButton.setChecked(true); } }); mRg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { RadioButton rb = (RadioButton) group.findViewById(checkedId); if (!rb.isChecked()) { return; } switch (checkedId) { case R.id.rb_home: position = 0; break; case R.id.rb_course: position = 1; break; case R.id.rb_direct_seeding: position = 2; break; case R.id.rb_me: position = 3; break; default: position = 0; break; } mViewPager.setCurrentItem(position); } }); } } 思路解析如下
mViewPager = (ViewPager) findViewById(R.id.viewPager); mRg = (RadioGroup) findViewById(R.id.rg);
mFragments = new ArrayList<>(); for (int i = 0; i < mTiltles.length; i++) { ItemFragement itemFragement = ItemFragement.newInstance(mTiltles[i]); mFragments.add(itemFragement); } BaseFragmentAdapter fragmentAdapter = new BaseFragmentAdapter (getSupportFragmentManager(), mFragments, mTiltles); mViewPager.setAdapter(fragmentAdapter); mViewPager.setCurrentItem(position); ((RadioButton) mRg.getChildAt(position)).setChecked(true);
mViewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { @Override public void onPageSelected(int position) { RadioButton radioButton = (RadioButton) mRg.getChildAt(position); radioButton.setChecked(true); } }); mRg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { RadioButton rb = (RadioButton) group.findViewById(checkedId); if (!rb.isChecked()) { return; } switch (checkedId) { case R.id.rb_home: position = 0; break; case R.id.rb_course: position = 1; break; case R.id.rb_direct_seeding: position = 2; break; case R.id.rb_me: position = 3; break; default: position = 0; break; } mViewPager.setCurrentItem(position); } }); 注意事项我们可以通过以下方法设置ViewPager左右页面 能缓存的fragment 数量 // 设置左右页面 能缓存的fragment 数量 mViewPager.setOffscreenPageLimit(fragmentAdapter.getCount() - 1); 到此仿qq底部tab切换的集中方法已经讲解完毕,之所以讲解了 三种方法,是想让大家了解多种实现方式,因为每一个人的习惯都不一样,有些人习惯使用与第一种方式,有人习惯使用第二种方式 。。。。。。了解多种 实现方式以后,我们要读懂别人的代码也容易得多了,其实我们还可以使用自定义控件来实现,方法也比较简单,这里就不讲解了,有兴趣的话,可以自行搜索 下面我将为大家讲解Fragment的 一些优化 解决Fragment多次实例化的几种方案 目前本人了解到的解决方案 ,无非是利用一下两种思想 第一种解决方法在onCreateView中避免多次实例化View,可通过判断View是否为空,来实现相应的 逻辑操作,核心代码如下 public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { LUtils.i(getClass().getSimpleName()+">>>>>>>>>>> onCreateView"); if(mView==null){ mContext = getContext(); mView=View.inflate(mContext,getLayoutId(),null); initView(mView); LUtils.i(getClass().getSimpleName()+">>>>>>>>>>> initView"); }else{ // 缓存的rootView需要判断是否已经被加过parent,如果有parent需要从parent删除, // 要不然会发生这个rootview已经有parent的错误。 ViewGroup parent =(ViewGroup) mView.getParent(); if(parent!=null){ parent.removeView(mView); } LUtils.i(getClass().getSimpleName()+">>>>>>>>>>> removeView"); } return mView; } 第二种解决方案在项目中需要进行Fragment的切换,用hide()和show()方法结合起来来替代replace()方法来实现Fragment的切换: private void showFragment(Fragment from, Fragment to) { FragmentManager supportFragmentManager = getSupportFragmentManager(); FragmentTransaction transaction = supportFragmentManager.beginTransaction(); if (!to.isAdded()) { // 先判断是否被add过 transaction.hide(from).add(R.id.fl, to).commit(); // 隐藏当前的fragment,add下一个到Activity中 } else { transaction.hide(from).show(to).commit(); // 隐藏当前的fragment,显示下一个 } } /**
*/ private void replaceFragment(Fragment fragmeny) { FragmentManager supportFragmentManager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction(); fragmentTransaction.replace(R.id.fl, fragmeny).commit(); } 关于 避免Fragment的多次实例化的分析与优化到此为止,下面我们一起来看一下 则那样实现Fragemnt 的 懒加载 Fragemnt的懒加载(网上很多人称之为Fragemnt的最优加载) 关于懒加载的这部分,代码是参考这篇 博客的 ViewPager+Fragment LazyLoad最优解 我们知道 ViewPager通常 会有预加载机制,默认情况下会先加载左右一页的数据,有时候我们想等待页面可见的时候在去加载网络 数据 ,解决方案如下 下面 先贴出代码 public abstract class BasePageFragment extends Fragment { protected View mView; /**
*/ protected boolean isViewInitiated; /**
*/ protected boolean isVisibleToUser; /**
*/ protected boolean isDataInitiated; private Context mContext; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LUtils.i(getClass().getSimpleName() + “>>>>>>>>>>> onCreate”); } @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { LUtils.i(getClass().getSimpleName() + “>>>>>>>>>>> onCreateView”); if (mView == null) { mContext = getContext(); mView = View.inflate(mContext, getLayoutId(), null); initView(mView); LUtils.i(getClass().getSimpleName() + “>>>>>>>>>>> initView”); } else { // 缓存的rootView需要判断是否已经被加过parent,如果有parent需要从parent删除, // 要不然会发生这个rootview已经有parent的错误。 ViewGroup parent = (ViewGroup) mView.getParent(); if (parent != null) { parent.removeView(mView); } LUtils.i(getClass().getSimpleName() + “>>>>>>>>>>> removeView”); } return mView; } protected abstract void initView(View view); protected abstract int getLayoutId(); @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); LUtils.i(getClass().getSimpleName() + “>>>>>>>>>>> onActivityCreated”); isViewInitiated = true; initData(); prepareFetchData(); } @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); s().getSimpleName() + “>>>>>>>>>>> onCreate”); } @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { LUtils.i(getClass().getSimpleName() + “>>>>>>>>>>> onCreateView”); if (mView == null) { mContext = getContext(); mView = View.inflate(mContext, getLayoutId(), null); initView(mView); LUtils.i(getClass().getSimpleName() + “>>>>>>>>>>> initView”); } else { // 缓存的rootView需要判断是否已经被加过parent,如果有parent需要从parent删除, // 要不然会发生这个rootview已经有parent的错误。 ViewGroup parent = (ViewGroup) mView.getParent(); if (parent != null) { parent.removeView(mView); } LUtils.i(getClass().getSimpleName() + “>>>>>>>>>>> removeView”); } return mView; } protected abstract void initView(View view); protected abstract int getLayoutId(); @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); LUtils.i(getClass().getSimpleName() + “>>>>>>>>>>> onActivityCreated”); isViewInitiated = true; initData(); prepareFetchData(); } @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); |
|
移动开发 最新文章 |
Vue3装载axios和element-ui |
android adb cmd |
【xcode】Xcode常用快捷键与技巧 |
Android开发中的线程池使用 |
Java 和 Android 的 Base64 |
Android 测试文字编码格式 |
微信小程序支付 |
安卓权限记录 |
知乎之自动养号 |
【Android Jetpack】DataStore |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 9:15:14- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |