栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

仿qq底部Tab导航,安卓app开发软件

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

仿qq底部Tab导航,安卓app开发软件

运行上述代码及可以看到如下效果图


使用RadioGroup和RadioButton实现仿qq底部切换


第一步 ,先看布局文件

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:id="@+id/fl"

android:layout_width=“match_parent”

android:layout_height=“0dp”

android:layout_weight=“1”>

android:id="@+id/rg"

android:layout_width=“match_parent”

android:layout_height=“wrap_content”

android:orientation=“horizontal”

android:id="@+id/rb_home"

android:drawableTop="@drawable/sel_home"

android:text=“首页”/>

android:id="@+id/rb_course"

android:drawableTop="@drawable/sel_course"

android:text=“课程”/>

android:id="@+id/rb_direct_seeding"

android:drawableTop="@drawable/sel_direct_seeding"

android:text=“直播”/>

android:id="@+id/rb_me"

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();

}

}

思路解析

  • 实例化各个控件,这里代码就不贴出来了

  • 初始化 Fragemnt 和选中各个tab

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();

}

  • 第三步,通过监听RadioGroup的 OnCheckedChangeListener事件,来实现tab和Fragemnt的切换

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切换


第一步,我们 同样先看布局代码

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:id="@+id/viewPager"

android:layout_width=“match_parent”

android:layout_height=“0dp”

android:layout_weight=“1”>

android:id="@+id/rg"

android:layout_width=“match_parent”

android:layout_height=“wrap_content”

android:orientation=“horizontal”

android:id="@+id/rb_home"

android:drawableTop="@drawable/sel_home"

android:text=“首页”/>

android:id="@+id/rb_course"

android:drawableTop="@drawable/sel_course"

android:text=“课程”/>

android:id="@+id/rb_direct_seeding"

android:drawableTop="@drawable/sel_direct_seeding"

android:text=“直播”/>

android:id="@+id/rb_me"

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

《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享

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);

}

});

}

}

思路解析如下

  • 实例化ViewPager和RadioGroup

mViewPager = (ViewPager) findViewById(R.id.viewPager);

mRg = (RadioGroup) findViewById(R.id.rg);

  • 第二步,初始化ViewPager的适配器和选中 那个tab

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);

  • 第三步,监听ViewPager 的滑动事件和RadioGroup的OnCheckedChangeListener事件,分别切换到相应的 Fragemnt 和同步ViewPager中 position 与RadioGroup之间的联系

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);

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/667362.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号