Android Fragments 详细使用

17、Android Studio 中使用 Fragments 示例教程 本文详细介绍在Android Studio中创建和使用Fragments的完整流程,通过一个具体示例实现两个Fragment之间的通信。内容涵盖项目创建、布局设计、Fragment类实现、界面交互以及通过Activity进行Fragment间数据传递,帮助开发者掌握Fragments在实际应用中的使用方法。 阅读详情

Android Fragments 详细使用

2012-02-17 14:29 by Terry_龙, 73021 阅读, 10 评论, 收藏, 编辑

   Fragments 诞生初衷

     自从Android 3.0中引入fragments 的概念,根据词海的翻译可以译为:碎片、片段。其上的是为了解决不同屏幕分辩率的动态和灵活UI设计。大屏幕如平板小屏幕如手机,平板电脑的设计使得其有更多的空间来放更多的UI组件,而多出来的空间存放UI使其会产生更多的交互,从而诞生了fragments 。fragments 的设计不需要你来亲自管理view hierarchy 的复杂变化,通过将Activity 的布局分散到frament 中,可以在运行时修改activity 的外观,并且由activity 管理的back stack 中保存些变化。

 

      Fragments 设计理念

      在设计应用时特别是Android 应用 ,有众多的分辨率要去适应,而fragments 可以让你在屏幕不同的屏幕上动态管理UI。例如:通讯应用程序(QQ),用户列表可以在左边,消息窗口在右边的设计。而在手机屏幕用户列表填充屏幕当点击某一用户时,则弹出对话窗口的设计,如下图:

 

Fragments的生命周期 

    每一个fragments 都有自己的一套生命周期回调方法和处理自己的用户输入事件。 对应生命周期可参考下图:

 

 其中大多数程序必须使用Fragments 必须实现的三个回调方法分别为:

onCreate

   系统创建Fragments 时调用,可做执行初始化工作或者当程序被暂停或停止时用来恢复状态,跟Activity 中的onCreate相当。 

onCreateView

   用于首次绘制用户界面的回调方法,必须返回要创建的Fragments 视图UI。假如你不希望提供Fragments 用户界面则可以返回NULL。 

onPause 

    当用户离开这个Fragments 的时候调用,这时你要提交任何应该持久的变化,因为用户可能不会回来。更多的事件可以参考上图的生命周期关系图。

Fragments 的类别

    系统内置了三种Fragments ,这三种Fragments 分别有不同的应用场景分别为:

DialogFragment

 对话框式的Fragments,可以将一个fragments 对话框并到activity 管理的fragments back stack 中,允许用户回到一个前曾摒弃fragments.

ListFragments

   类似于ListActivity 的效果,并且还提供了ListActivity 类似的onListItemCLick和setListAdapter等功能。

PreferenceFragments

   类似于PreferenceActivity .可以创建类似IPAD的设置界面。 

 

Fragments 的详细使用 

    首先先来看一张DEMO 效果图:

 

    左边点击时,右边的字符会与左边选中的项的字符相同。与IPAD上的设置界面很相似,这一点是否借鉴了ipad 上的UI呢?

相就的XML文件:

复制代码
<? xml version="1.0" encoding="utf-8" ?>
< LinearLayout  xmlns:android ="http://schemas.android.com/apk/res/android"
    android:layout_width
="match_parent"
    android:layout_height
="match_parent"
    android:orientation
="horizontal"   >

    < fragment  class ="com.xuzhi.fragment.FragmentDemoActivity$TitlesFragment"  android:id ="@+id/titles"  android:layout_weight ="1"
       android:layout_width
="0px"  android:layout_height ="match_parent"
       
/>
   
    < FrameLayout  android:id ="@+id/details"  android:layout_weight ="1"  android:layout_width ="0px"  android:layout_height ="match_parent"
       android:background
="?android:attr/detailsElementBackground"
       
></ FrameLayout >
</ LinearLayout >
复制代码

 

 

主界面代码(己做注释):

 

复制代码
package  com.xuzhi.fragment;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.app.ListFragment;
import android.os.Bundle;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.ScrollView;
import android.widget.TextView;

public  class FragmentDemoActivity  extends Activity {

     public  static String[] array = { "text1,", "text2", "text3", "text4",
            "text5,", "text6", "text7", "text8" };

     /**  Called when the activity is first created.  */
    @Override
     public  void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState); 
        setContentView(R.layout.main);
    }

        
     public  static  class TitlesFragment  extends ListFragment {

         boolean mDualPane;
         int mCurCheckPosition = 0;
        
        @Override
         public  void onCreate(Bundle savedInstanceState) {
             //  TODO Auto-generated method stub
             super.onCreate(savedInstanceState);
            System.out.println("Fragment-->onCreate");
        }
        
        @Override
         public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
             //  TODO Auto-generated method stub
            System.out.println("Fragment-->onCreateView");
             return  super.onCreateView(inflater, container, savedInstanceState);
        }
        
        @Override
         public  void onPause() {
             //  TODO Auto-generated method stub
             super.onPause();
            System.out.println("Fragment-->onPause");
        }
        
        
        @Override
         public  void onStop() {
             //  TODO Auto-generated method stub
             super.onStop();
            
            System.out.println("Fragment-->onStop");
        }
        
        @Override
         public  void onAttach(Activity activity) {
             //  TODO Auto-generated method stub
             super.onAttach(activity);
            System.out.println("Fragment-->onAttach");
        }
        
        @Override
         public  void onStart() {
             //  TODO Auto-generated method stub
             super.onStart();
            System.out.println("Fragment-->onStart");
        }
        
        @Override
         public  void onResume() {
             //  TODO Auto-generated method stub
             super.onResume();
            System.out.println("Fragment-->onResume");
        }
        
        @Override
         public  void onDestroy() {
             //  TODO Auto-generated method stub
             super.onDestroy();
            System.out.println("Fragment-->onDestroy");
        }
        
        

        @Override
         public  void onActivityCreated(Bundle savedInstanceState) {
             //  TODO Auto-generated method stub
             super.onActivityCreated(savedInstanceState);
            System.out.println("Fragment-->onActivityCreted");
            setListAdapter( new ArrayAdapter<String>(getActivity(),
                    android.R.layout.simple_list_item_1, array));

            View detailsFrame = getActivity().findViewById(R.id.details);

            mDualPane = detailsFrame !=  null
                    && detailsFrame.getVisibility() == View.VISIBLE;

             if (savedInstanceState !=  null) {
                mCurCheckPosition = savedInstanceState.getInt("curChoice", 0);  // 从保存的状态中取出数据
            }

             if (mDualPane) {
                getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);

                showDetails(mCurCheckPosition);
            }
        }

        @Override
         public  void onSaveInstanceState(Bundle outState) {
             //  TODO Auto-generated method stub
             super.onSaveInstanceState(outState);

            outState.putInt("curChoice", mCurCheckPosition); // 保存当前的下标
        }

        @Override
         public  void onListItemClick(ListView l, View v,  int position,  long id) {
             //  TODO Auto-generated method stub
             super.onListItemClick(l, v, position, id);
            showDetails(position);
        }

         void showDetails( int index) {
            mCurCheckPosition = index; 
             if (mDualPane) {
                getListView().setItemChecked(index,  true);
                DetailsFragment details = (DetailsFragment) getFragmentManager()
                        .findFragmentById(R.id.details); 
                 if (details ==  null || details.getShownIndex() != index) {
                    details = DetailsFragment.newInstance(mCurCheckPosition); 

                     // 得到一个fragment 事务(类似sqlite的操作)
                    FragmentTransaction ft = getFragmentManager()
                            .beginTransaction();
                    ft.replace(R.id.details, details); // 将得到的fragment 替换当前的viewGroup内容,add则不替换会依次累加
                    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); // 设置动画效果
                    ft.commit(); // 提交
                }
            }  else {
                 new AlertDialog.Builder(getActivity()).setTitle(
                        android.R.string.dialog_alert_title).setMessage(
                        array[index]).setPositiveButton(android.R.string.ok,
                         null).show();
            }
        }
    }

     /**
     * 作为界面的一部分,为fragment 提供一个layout
     * 
@author  terry
     *
     
*/
     public  static  class DetailsFragment  extends Fragment {

         public  static DetailsFragment newInstance( int index) { 
            DetailsFragment details =  new DetailsFragment();
            Bundle args =  new Bundle();
            args.putInt("index", index);
            details.setArguments(args);
             return details;
        }

         public  int getShownIndex() {
             return getArguments().getInt("index", 0);
        }

        @Override
         public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
             //  TODO Auto-generated method stub
             if (container ==  null)
                 return  null;

            ScrollView scroller =  new ScrollView(getActivity());
            TextView text =  new TextView(getActivity());

             int padding = ( int) TypedValue.applyDimension(
                    TypedValue.COMPLEX_UNIT_DIP, 4, getActivity()
                            .getResources().getDisplayMetrics());
            text.setPadding(padding, padding, padding, padding);
            scroller.addView(text);

            text.setText(array[getShownIndex()]);
             return scroller;
        }
    }
}
复制代码

 注意:

  1. 如果你想在Fragment 里面创建menu,则必须在onCreate的时候设置让它可以存在optionMenu才可以创建,代码为:
    复制代码
    public  static  class DetailsFragment  extends Fragment {

            @Override
             public  void onCreate(Bundle savedInstanceState) {
                 //  TODO Auto-generated method stub
                 super.onCreate(savedInstanceState);
                setHasOptionsMenu( true);
            }
    }
    复制代码
    之后的操作即可以像平常Android的menu用法一样,代码为:
    复制代码
    @Override
             public  void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
                 //  TODO Auto-generated method stub
                 super.onCreateOptionsMenu(menu, inflater);
                 menu.add("Menu 1a").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
                    menu.add("Menu 1b").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
            }
            
            @Override
             public  boolean onOptionsItemSelected(MenuItem item) {
                 //  TODO Auto-generated method stub
                Toast.makeText(getActivity(), "index is"+getShownIndex()+" && menu text is "+item.getTitle(), 1000).show();
                 return  super.onOptionsItemSelected(item);
            }
    复制代码
全面掌握Android Fragments的实践教程 本文还有配套的精品资源,点击获取 简介:本教程深入分析Android Fragments,探讨其概念、生命周期、管理、通信、保存状态、事务优化和在导航架构中的应用。通过详细的学习和实践,开发者可以利用Fragments构建适应多屏幕尺寸、功能丰富的Android应用,并保持代码清晰和模块化。 1. Android Fragments的基本概念和用途 Andr... 阅读详情

相关推荐

Appsflyer S2S事件上报实战:从参数获取到避坑指南(附Firebase对比)

本文详细解析了Appsflyer S2S事件上报的实战技巧,包括核心参数获取、测试环境搭建、生产环境最佳实践以及高级场景处理。通过对比Firebase的事件上报机制,帮助开发者高效避坑并优化数据上报流程,提升应用分析与营销效果。

egg99的博客 885

交换机端口常见的报文统计类型说明

交换机驱动开发

Limit_Fly的博客 1852

使用modelscope加载报错:ImportError: cannot import name ‘AutoTokenizer’ from ‘modelscope’...如何解决?| 提供多种解决方案

🏆本文收录于 《全栈Bug调优(实战版)》 专栏,该专栏专注于分享我在真实项目开发中遇到的各类疑难Bug及其深层成因,并系统提供高效、可复现的解决思路和实操方案。无论你是刚入行的新手开发者,还是拥有多年项目经验的资深工程师,本专栏都将为你提供一条系统化、高质量的问题排查与优化路径,助力你加速成长,攻克技术壁垒,迈向技术价值最大化与职业发展的更高峰🚀!

**My Coding Family** 1243

android Fragments详解四:管理fragment

要管理fragment们,需使用FragmentManager,要获取它,需在activity中调用方法getFragmentManager()。 你可以用FragmentManager来做以上事情: FragmentManagerfragmentManager=getFragmentManager(); FragmentTransactionfragmentTransact

Dream It Possible 1670

20、认知负荷理论在教育技术中的应用

本文深入探讨了认知负荷理论(Cognitive Load Theory, CLT)在教育技术中的应用,重点分析了如何通过优化教学设计减少学习者的认知负荷,提高学习效率。文章介绍了认知负荷的三种类型:内在认知负荷、外在认知负荷和germane认知负荷,并结合多媒体学习原则(如模态效应、空间连续性原则、时间连续性原则等)提出了减少外在认知负荷的具体策略。此外,文章通过实证研究和教学案例,展示了认知负荷理论在不同学科和个性化教学中的广泛应用和有效性。最终,文章总结了应用认知负荷理论进行教学设计的具体流程,强调其在

solidity8miner的博客 923

OpenSpec 完全指南 config.yaml文件

不管是项目内还是全局存放,自定义工作流都要遵守以下规则,否则会导致OpenSpec无法识别,新手一定要记牢:一个文件夹 = 一个工作流:工作流文件夹的名称,就是中schema字段要填写的名称;每个工作流文件夹必须包含:这是工作流的核心定义文件,没有它,OpenSpec无法识别这个工作流;模板文件统一放templates/目录:如果需要自定义生成文件的模板(比如统一的提案模板、任务模板),就放在工作流文件夹下的templates/里,OpenSpec会自动识别;

h a 6 6 6 c k 为 你解决复杂难题! 1422

性能统计中常遇到的网络术语

1,转自http://welshie.blogcn.com/diary,29927725.shtmlAligment Error:一般指Ethernet帧里字节的部分bit位被丢失了,会造成FCS错的情况,更明确的说法是字节对齐错误.Byte Aligment Error,即接收到的内容为非整数倍的字节数.因为有部分 bit丢掉了,而以太网收发规范是以整数倍的字节作为基础的,如64~1518字

violetfeeling的专栏 1565

基于V7-690T FPGA纯逻辑实现NVMe SSD盘的读写(不使用软核)

a.NVMe的Admin CQ与Admin SQ命令放在Host内存中;因此SQ的64B要用FPGA的DDR或开一个bram空间存放,同理NVME写到HOST的CQ命令也需要存放在FPGA的DDR或一个bram空间,host收到NVME传来的MSI/MSI-X中断后,去CQ存放空间取CQ指令;b. 发送identify命令后,需要发送tial doorbell通知NVME;(发送CNS01h获取4096字节的固件信息等;发送CNS02h获取1024字节的namaspace list)

宝沐熙的博客 835

getSupportFragmentManager().getFragments() 抛出空指针异常

背景很简单,在一个FragmentActivity上显示我想要的fragment。 每次显示Fragment的时候我都调用一个函数:public static boolean showFragmentInActivity(SdkFragment frag, String tag, SdkActivity actv) { if (frag == null || actv == null ||

lintcgirl的博客 8761

【异常】Milvus 向量数据库字段缺失错误分析与解决 MilvusVectorStoreServiceV2 - Failed to insert batch [0-1]: The field:

本文分析了Milvus向量数据库插入操作中出现的字段缺失错误。错误显示age_mode字段未提供,导致批量插入失败。根本原因是Milvus Schema要求所有定义字段必须存在,但代码中对部分字段采用条件添加方式。解决方案是将条件添加改为始终添加,为可能为null的字段提供空字符串默认值。文章总结了Schema约束、防御性编程等经验,并建议通过Schema变更检查、单元测试覆盖和数据校验层等预防措施避免类似问题。该问题影响product、mac、source等多个字段,修改后确保了数据插入的可靠性。

奶爸的编程之路,也就一周冷个三天 407

【论文复现】——基于欧式聚类的车载点云道路提取

针对车载激光点云道路信息提取的问题,提出了一种基于欧式聚类的道路提取方法。首先通过统计滤波去除噪点以免对后续处理结果产生影响,然后用坡度滤波去除路坎点,使道路边界与人行道、绿化带等与路坎相连的地物形成10~25 cm的高程阶跃,最后用欧式聚类将路面点云与其他地物点云聚类为一簇或多簇并保留道路簇,从而实现道路点云的精确提取。

点云侠的博客 1135

2024年安卓最新Android Fragments 详细使用详细介绍,面试官打击你

说一千道一万,不如自己去行动。要想在移动互联网的下半场是自己占有一席之地,那就得从现在开始,从今天开始,马上严格要求自己,既重视业务实现能力,也重视基础和原理。基础夯实好了,高楼才能够平地而起,稳如泰山。最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的24套腾讯、字节跳动、阿里、百度2020-2021面试真题解析,我把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节。还有。

2401_84558983的博客 975

风险登记册vs问题日志:项目经理必须掌握的区别与应用

在项目管理的世界里,风险登记册和问题日志就像是项目经理的两个得力助手。我们的目的就是要搞清楚这两个助手各自的特点、区别以及如何在项目中好好使用它们。范围涵盖了项目从启动到结束的整个过程,无论是小项目还是大项目,都能从对这两个工具的正确使用中受益。我们先会用有趣的故事引出风险登记册和问题日志的概念,然后像给小学生讲故事一样解释它们是什么。接着分析它们之间的关系和区别,再用代码示例模拟它们在项目中的应用,之后介绍实际的应用场景、推荐相关工具和资源,探讨未来的发展趋势和挑战。

项目管理的博客 875

安卓学习(三) Android Fragments

安卓学习(三) Android Fragments摘要: 本文介绍Android的Fragments, Fragments和activity有点像,也有xml布局文件,也有对应的类文件,但它在Android中是一种共享机制,就像一个动态的组件,应用可以动态地添加或删除。在本文中,会介绍Fragment的相关内容,包括啥是Fragment,怎样创建Fragments,最后通过一个apk演示Fragm

leehaoran的专栏 914

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

Android Fragments 详细使用详细介绍

左边点击时,右边的字符会与左边选中的项的字符相同。与IPAD上的设置界面很相似,这一点是否借鉴了ipad 上的UI呢?

2501_90252669的博客 204

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

上一篇: Java Serializable(序列化)的理解和总结
下一篇: 使用NDK移植开源项目,JNI的使用技巧
HabbyGe
博客等级 码龄16年 46粉丝 143原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值