利用Fragment实现仿微信Tab效果(Fragment的初步学习)

Android应用主界面Tab切换框架详解之Fragment 概述 时下APP主流主界面Tab切换框架之一 --- Fragment 的搭建。 Fragment作为内容区域:MainActivity只作为一个调度器,支配Fragment的显示和隐藏,使得管理的控件事件等不需放在MainActivity中造成代码冗长,便于复用及后期维护。 解决 ' 切换Tab反复初始化Fragment影响性能、增加流量消耗 ' 问题。 解决 ' 横竖屏切换导致 阅读详情

在前一次利用ViewPager实现仿微信Tab效果的后,又学习了利用Fragment实现该效果,刚好是对Fragment的一次学习理解。

效果图就不展示了,和ViewPager的界面类似,唯一的缺点就是,利用单纯的Fragment无法实现像ViewPager一样的左右滑切换。就当做一次对Fragment的理解学习吧。
这个Demo的难点总结:
1.Fragment的理解与使用。
2.FragmentTransaction与Fragment生命周期的关系。
3.FragmentTransaction中不同操作的区别。(此处遇到问题!)

接下来来详细阐述一下以上两点:
一、Fragment的理解使用。
原来一直都是在书上看完了Fragment的使用,只是知道Fragment的是用来在一个Activity中便于实现大量控件与事件的分类处理。利用这次机会刚好初步学习了一下Fragment的使用与理解。
http://blog.youkuaiyun.com/lmj623565791/article/details/37970961这篇大神的博客已经很详细的讲解了有关Fragment的理解与使用。看完过后知道了Fragment的基础使用方式两种:
(1)静态的使用Fragment
(2)动态的使用Fragment。
而本例中使用的就是第二种使用方式,利用FragmentTransaction实现动态使用Fragment。一开始还不理解动态的使用的含义,看完那篇博客后,了解到,就是利用FragmentManager在Activity中操作Fragment。
也就是说在Activity中动态的管理Fragment。具体方式步骤如下:
1.定义自己的mFragment继承Fragment(此处有一个要点就是:包名要一致,如果导入的是android.app.Fragment后面导入的都要是app下的包例如android.app.FragmentManager;而如果导入的是android.support.v4.app.Fragment,后面要一致导入v4包,不然会产生错误)。重写onCreateView方法:如下

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    Log.i("Tag", "onCreateView");
    // TODO Auto-generated method stub
    return inflater.inflate(R.layout.tab1, container, false);
}

2.获取FragmentManage,利用getFragmentManager()(v4中,getSupportFragmentManager)得到FragmentManage。

FragmentManager fm = getFragmentManager();

3.开启一个事务FragmentTransaction。

FragmentTransaction transaction = fm.beginTransaction();

4.调用add(),show(),remove(),replace(),hide()等相关操作实现所需功能。

代码如下:
MainActivity.java

package com.example.fragmenttab;


import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.ImageView;
import android.widget.LinearLayout;

public class MainActivity extends Activity implements OnClickListener{
    private LinearLayout l1, l2, l3, l4;
    private ImageView pic1, pic2, pic3, pic4;
    private Fragment f1,f2,f3,f4;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);
        initView();
        initEvent();
        setSelect(0);
    }
    private void initEvent() {
        // TODO Auto-generated method stub
        l1.setOnClickListener(this);
        l2.setOnClickListener(this);
        l3.setOnClickListener(this);
        l4.setOnClickListener(this);
    }

    private void initView() {
        // TODO Auto-generated method stub
        l1 = (LinearLayout) findViewById(R.id.lin1);
        l2 = (LinearLayout) findViewById(R.id.lin2);
        l3 = (LinearLayout) findViewById(R.id.lin3);
        l4 = (LinearLayout) findViewById(R.id.lin4);
        pic1 = (ImageView) findViewById(R.id.pic1);
        pic2 = (ImageView) findViewById(R.id.pic2);
        pic3 = (ImageView) findViewById(R.id.pic3);
        pic4 = (ImageView) findViewById(R.id.pic4);
    }
    private void setSelect(int i){
        FragmentManager fm = getFragmentManager();
        FragmentTransaction transaction = fm.beginTransaction();
        hideFragment(transaction);
        switch (i) {
        case 0:
            if(f1 == null){
                f1 = new OneFragment();
                transaction.add(R.id.content, f1);
            }else{
                transaction.show(f1);
            }
            pic1.setImageResource(R.drawable.tab_weixin_pressed);
            break;
        case 1:
            if(f2 == null){
                f2 = new SecondFragment();
                transaction.add(R.id.content, f2);
            }else{
                transaction.show(f2);
            }
            pic2.setImageResource(R.drawable.tab_find_frd_pressed);
            break;
        case 2:
            if(f3 == null){
                f3 = new ThirdFragment();
                transaction.add(R.id.content, f3);
            }else{
                transaction.show(f3);
            }
            pic3.setImageResource(R.drawable.tab_address_pressed);
            break;
        case 3:
            if(f4== null){
                f4 = new FourthFragment();
                transaction.add(R.id.content, f4);
            }else{
                transaction.show(f4);
            }
            pic4.setImageResource(R.drawable.tab_settings_pressed);
            break;
        }
        transaction.commit();
    }
    private void hideFragment(FragmentTransaction transaction) {
        //隐藏所有Fragment
        if(f1 != null){
            transaction.hide(f1);
        }
        if(f2 != null){
            transaction.hide(f2);
        }
        if(f3 != null){
            transaction.hide(f3);
        }
        if(f4 != null){
            transaction.hide(f4);
        }
    }
    @Override
    public void onClick(View v) {
        resetImage();
        switch (v.getId()) {
        case R.id.lin1:
            setSelect(0);
            break;
        case R.id.lin2:
            setSelect(1);
            break;
        case R.id.lin3:
            setSelect(2);
            break;
        case R.id.lin4:
            setSelect(3);
            break;
        }
    }

    private void resetImage() {
        // 重置所有图片
        pic1.setImageResource(R.drawable.tab_weixin_normal);
        pic2.setImageResource(R.drawable.tab_find_frd_normal);
        pic3.setImageResource(R.drawable.tab_address_normal);
        pic4.setImageResource(R.drawable.tab_settings_normal);
    }
}

OneFragment.java

package com.example.fragmenttab;


import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class OneFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    Log.i("Tag", "onCreateView");
    // TODO Auto-generated method stub
    return inflater.inflate(R.layout.tab1, container, false);
}
}

activity_main.xml

<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">
    <include layout="@layout/top" />
    <FrameLayout 
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"></FrameLayout>
    <include layout="@layout/bottom" />
</LinearLayout>

其他界面和前一个例子相同。

以上就是这次所有的总结,这样就结束了吗?NO!NO!NO!
在这个例子中一个无意的操作引发了一个自己无法解决的问题。
问题如下:
在这个例子中原理就是,每次点击之前都回执行hideFragment()方法用户将所有的Fragment利用transaction.hide()方法隐藏掉,然后再二次点击时利用show()方法显示。这些看似很基础,但是我一开始写的时候,不小心将hide()方法写成了remove()方法,这时候问题来了!!!运行效果是第一次点击都是好的,但是第二次点击后界面就为空白了。
问题原因:
设置断点调试,发现原因很简单,执行remove后,二次点击在这一步:

if(f1 == null){
                f1 = new OneFragment();
                transaction.add(R.id.content, f1);
            }else{
                transaction.show(f1);
            }

这时f1不为null,执行show()方法,而f1已经被remove了所以show是空白。
但是看似简单的问题原因,仔细一想,FragmentTransaction的remove方法定义是从Activity中移除一个Fragment,如果被移除的Fragment没有添加到回退栈(回退栈后面会详细说),这个Fragment实例将会被销毁。
销毁?对,你没有看错,销毁后不应该为null吗?为什么判断的时候不是null哪?纠结啊,看了Fragment的源码和FragmentTransaction的源码还是无法理解原因,Tag了Fragment的生命周期发现,remove后确实执行了onDetach()方法,也就是说该Fragment已经的确被销毁了,但是判null的时候不是null,纠结啊!!!希望有大神能解决这个问题啊。我自己也在寻找原因,希望下次博客能够发出解决贴吧!

Fragment微信界面Tab标签切换案例 Fragment微信界面Tab标签切换案例 此案例共有1个Activity和4个Fragment。 代码如下: MainActivity.java public class MainActivity extends AppCompatActivity implements View.OnClickListener { private ImageView imageView1; private ImageView imageView2; private ImageView image 阅读详情

相关推荐

使用Fragment实现Tab切换(高仿微信主界面)

先来看效果图: 在2.x版本时代,我们都是使用TabActivity和TabHost组合来实现页面的tab切换。TabActivity是一个特殊的Activity,它继承自ActivityGroup,内部可容纳多个Activity,违反了Activity的单一窗口原则,虽风靡一时却难免被抛弃。 3.0版本出现之后,Google推出了一个新的类Fragment,且TabAct

ruancoder的博客 8790

tab+Fragment管理最佳实践

现在的app视图中tab+fragment是最常用的一种布局,但是如果使用才是更简洁更有效的呢?下面通过一个demo的分类测试来分析下:add remove replace detach attach hide show这些方法的使用对Fragment生命周期的影响分析: 顺便分析下Fragment所依赖的Activity的生命周期;测试代码如下: MainActivity的代码如下:packa

u013168615的专栏 5288

用Fragment实现Android微信样式Tab切换

项目要求 实现模仿微信式点击底部Button进行Tab切换效果 点击Button时有相应的按钮高亮处理 实现思路 List item

中国好码农13号 548

Android UI之Tab(ActionBar+Fragment实现)

Fragment和ActionBar都是Android3.0之后出现的,Fragment,碎片,主要是为了支持更多的UI设计在大屏幕设备上,如平板。因为现在设备的屏幕越来越大,使用Fragment可以更灵活的管理视图层次的变化。像Activity一样,可以创建Fragment来包含View,进行布局,但是Fragment必须嵌入在Activity中,不能单独存在,而且一个Activity可以嵌入多

6688

Android开发——使用fragment仿微信底部菜单栏

Android在3.0版本加入了Fragment,主要是为了解决Android Pad屏幕比较大,空间不能充分利用的问题,但现在即使只是在手机上,也有很多的场景可以。然而现在Fragment的应用的场景越来越多,Fragment意为碎片的意思,就是为了替代TabActivity。 例如,微信下方的tab: 可以将Fragment理解为Activity的“碎片”,也就是其一部分,故而Fragment的

newAppZ 7498

Android Tab切换之Fragment实现方法

在Android开发中,Tab切换是一种常见的界面交互方式,可以让用户方便地在不同的功能页面之间进行切换。而Fragment是Android中用来构建灵活、可重用的界面组件的一种机制。本文将介绍如何使用Fragment实现Android Tab切换功能。以上就是使用Fragment实现Android Tab切换的方法。通过创建多个Fragment和PagerAdapter,配合ViewPager和TabLayout,可以轻松实现Tab切换的效果。Android Tab切换之Fragment实现方法。

HackDashX的博客 763

仿微信底部Tab切换,TabHost+Fragment的用法

今天没什么事情,所以研究了一下,微信的Tab效果。效果比较粗糙,朋友们先凑合着看,后面有时间会优化。             基本就是点击下面的tab,就会切换到不同的fragment。      main_activity.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xm

Langxingtianxi的专栏 1875

Android TabLayout实战:仿微信底部Tab导航设计与实现

在Android UI发展进程中,Google提出的Material Design不仅是一套视觉规范,更是一种以用户为中心的交互语言。作为其关键组件之一,TabLayout承载着页面导航的核心职责,体现了“层级清晰、操作直观、反馈明确”的设计理念。它通过统一的标签样式、平滑的滑动指示器和可预测的状态反馈,提升应用的可用性与一致性。例如,在微信等主流App中,底部Tab采用图文混排、颜色状态切换等方式,精准引导用户行为,正是TabLayout结合Material Design原则的实际体现。

weixin_29155599的博客 1264

Android~仿微信(Fragment+ViewPager)

仿微信(Fragment+ViewPager),实现效果,滑动或者点击,页面随Tab顶部切换,效果如下所示: 思维导图 详细代码如下: 1、MainActivity .java public class MainActivity extends AppCompatActivity implements View.OnClickListener { private TextView title; private TextView mTextHome; private TextVi

~~~的博客 945

Android的Fragment实现Tab切换

之前做项目零基础开始了Android开发,期间用到了Fragment的Tab切换功能,但网上好多帖子甚至代码都有点错误,于是我自己写了一个,希望能帮助到大家

机械设计师必看:如何用Autodesk Inventor高效完成钣金设计(附实战案例)

本文为机械设计师详细解析了如何利用Autodesk Inventor Professional高效完成钣金设计。文章通过一个钣金防护罩的实战案例,系统介绍了从核心设计逻辑、建模流程、参数化技巧到工程图输出的完整工作流,旨在帮助设计师掌握智能化的设计方法,显著提升从概念到制造的设计效率与准确性。

honey的博客 1181

ViewPager+Fragment实现Tab主界面

毕竟是第一次做项目,所以在每一点上都做得特别认真,接下来我来给大家大致讲述一下用ViewPager+Fragment来实现app Tab主界面,突然想起来LZ居然2天没去上课了......(>.... package com.bob.tabui; import android.support.v4.app.*; import android.os.Bundle; import android.

My life,my way 6526

【AI智能体】图像处理-生成营销 Banner 图

生成营销 Banner 图是一款用于制作营销图片的智能体,它可以根据指定的营销活动内容,快速生成活动 Banner 图片,降低活动运营成本、提高制图效率。

AI创变工坊,和1000万新个体创业者一起成长!愿大家都能跟上时代的洪流,不被社会淘汰,愿大家的生活工作收入都能具备竞争力! 1175

android 底部tab效果,Android 仿微信底部渐变Tab效果

先来看一下效果图除了第三个的发现Tab有所差别外,其他的基本还原了微信的底部Tab渐变效果每个Tab都是一个自定义View,根据ImageView的tint属性来实现颜色渐变效果,tint属性的使用可以看我的上一篇文章我将自定义View命名为ShadeView,包含四个自定义属性意思分别为图标、背景色、底部文本、底部文本大小ShadeView的定义如下,主要是进行绘图操作,并向外提供改变透明度和图...

weixin_33595317的博客 479

Docker拉取ubuntu22.04镜像使用ROS2 humble及仿真工具可视化进行导航

Docker中安装Ubun22以及ROS,gazebo可视化等

lovebc的博客 1676

保姆级教程:在Rockchip RK3588 SDK中,如何为你的新硬件板子创建第一个DTS文件

本文提供在Rockchip RK3588 SDK中为自定义硬件创建首个DTS文件的详细教程。通过分析DTS在RK3588开发中的角色、快速定位参考设计、实操步骤及调试验证方法,帮助开发者高效完成硬件板级配置,特别适合嵌入式Linux系统开发者参考。

weixin_28678831的博客 283

使用ViewPager + Fragment实现微信底部Tab效果

下面是最常用的Tab布局,最终实现效果 MainActivity的主文件代码: public class MainActivity extends FragmentActivity implements View.OnClickListener { //声明ViewPager private ViewPager mViewPager; //适配器 ...

weixin_30307267的博客 196

wpa_supplicant EAPOL状态机分析

wpa_supplicant EAPOL状态机分析

加油鸭 1476

使用Fragment+ViewPager,仿微信实现多页Tab切换

我们今天实现类似微信的首页的滑动Tab效果:                郭霖有一篇博客  http://blog.youkuaiyun.com/guolin_blog/article/details/13171191,讲过如果实现,但是他的demo不同通过滑动切换,只能通过点击按钮切换。 通过viewpager,我们可以完全实现微信的效果。 先看看我的实现效果: pa

陆业聪 3522

《Long-CLIP: Unlocking the Long-Text Capability of CLIP》

总的来说,Long-CLIP是一个改进的视觉-语言预训练模型,它通过知识保留的位置上插值和主要成分匹配策略,有效解决了原始CLIP模型在处理长文本输入时的限制。这一模型不仅在长文本图像检索任务中表现出色,而且在零样本图像分类任务中保持了与原始CLIP相当的性能,同时还能以即插即用的方式增强图像生成任务中的长文本处理能力。

Angelina_Jolie的博客 1378

复现:Mamba-UNet:降水临近预报的创新解决方案

Mamba-UNet通过其创新的双分支Mamba融合模块、多尺度时空注意力模块和动态分位数加权损失函数,在降水临近预报领域取得了显著的性能提升。它不仅在多种降水场景下表现出色,尤其在预测强降水事件方面展现出了强大的能力。这一创新模型为降水临近预报提供了一种新的解决方案,有望在未来的研究和应用中发挥更大的作用,为应对气候变化带来的挑战提供有力支持。随着技术的不断发展和优化,我们期待Mamba-UNet在更广泛的气象预报任务中发挥更大的价值,为各行各业提供更精准、更可靠的降水预报服务。

hanfeng5268的博客 912

Andriod Studio编写仿微信界面

Andriod Studio编写仿微信界面实验要求实验内容最终页面显示需要创建的文件样式文件的内容top.xmllayout_main.xmlbottom.xml主要的Java代码MainActivity代码链接 实验要求 请根据课堂展示结果设计APP门户界面,包含4个tab切换效果。 实验内容 最终页面显示 四个TAB页面显示 需要创建的文件 样式文件的内容 这里只写主要的三个文件的内容,分别是top,bottom,layout_main top.xml 只需要修改字体样式 android:l

weixin_45665377的博客 3279

数仓建模—维度建模之维度表

首先要学会识别维度,维度是相对稳定的、可抽象具有共性的、固有的(天然的)描述度量或事实的上下文属性信息,失去维度信息的度量信息是没有意义的或者说是失去维度信息的事实表是没有意义的。其次要掌握维度表的设计原则和设计流程,从而更加科学的设计维度表,其实这些东西都是术,我们一直都说一句话大道至简,其实如果你掌握了精髓,抛开这些术也可以做到得心应手,这就像张无忌练太极剑一样,忘记了才能达到道的境界,也就是无我,如果做不到就记住这些原则加以应用从而达到术的境界。

2401_84052244的博客 4361

三种实现Android主界面Tab的方式

转载于:https://www.cnblogs.com/caobotao/p/5103673.html 在平时的Android开发中,我们经常会使用Tab来进行主界面的布局。由于手机屏幕尺寸的限制,合理使用Tab可以极大的利用屏幕资源,给用户带来良好的体验。学会Tab的使用方法已经成为学习Android开发必不可少的技能了。我们经常使用的微信、QQ就是使用Tab的方式进行主界面的布局的。   ...

taoerchun的专栏 7636

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Fragment实现Tab

Fragment实现Tab 1.1 效果 1.2 目录 1.3 素材 1.4 顶部提示栏top.xml 1.5 底部标签bottom.xml 1.6 activity_main.xml 1.7 四个切换界面 1.7.1 tab01.xml 1.7.2 tab02.xml 1.7.3 tab03.xml 1.7.4 tab04.xml 1.8 四个自定义Fragment 1.8.1 Weix...

amoscxy的博客 271

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Android ViewPager和Fragment实现顶部导航界面滑动效果、标签下的tab位置

在项目中,我们常常需要实现界面滑动切换的效果。例如,微信界面的左右滑动切换效果。那这种效果是怎么实现的?今天我就带大家简单了解ViewPager,并通过实例来实现该效果。 一. ViewPager 官方API 首先我们来看一下ViewPager官方给出的解释,如图: 具体意思如下: Layout 管理器允许用户可以在页面上,左右滑动来翻动页面。你可以考虑实现Pa

Sun的专栏 3926

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

上一篇: 利用ViewPager实现仿微信Tab效果
下一篇: FragmentTransaction的add和Fragment的onCreateView()相关问题
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值