Fragment(碎片)

1、碎片是什么

碎片(Fragment)是一种可以嵌入在活动当中的UI片段,它能让程序更加合理和充分地利用大屏幕的空间,因而在平板上应用的非常广泛。虽然碎片对你来说应该是个全新的概念,但我相信你学习起来应该毫不费力,因为它和活动实在是太像了,同样都能包含布局,同样都有自己的生命周期。你甚至可以将碎片理解成一个迷你型的活动,虽然这个迷你型的活动有可能和普通的活动是一样大的。

那么究竟要如何使用碎片才能充分地利用平板屏幕的空间呢?想象我们正在开发一个新闻应用,其中一个界面使用ListView展示了一组新闻的标题,当点击了其中一个标题,就打开另一个界面显示新闻的详细内容。如果是在手机中设计,我们可以将新闻标题列表放在一个活动中,将新闻的详细内容放在另一个活动中,如下图

可是如果在平板上也这么设计,那么新闻标题列表将会被拉长至填充满整个平板的屏幕,而新闻的标题一般都不会太长,这样将会导致界面上有大量的空白区域,如下图所示。


因此,更好的设计方案是将新闻标题列表界面和新闻详细内容界面分别放在两个碎片中,然后在同一个活动里引入这两个碎片,这样就可以将屏幕空间充分地利用起来了,如下图所示。

2、Fragment碎片的使用

(例子有点长,耐心看下去)

①、首先我们来定义一下一个主Activity的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"><FrameLayoutandroid:id="@+id/left_fragement"android:layout_width="0dp"android:layout_weight="1.5"android:layout_height="match_parent"android:background="#EBC781"/><FrameLayoutandroid:id="@+id/right_fragement"android:layout_width="0dp"android:layout_weight="3"android:layout_height="match_parent"android:background="#04AF90"/></LinearLayout>

效果大致是这样的,分为左边和右边两个部分,分别用来装左右两个碎片

②、接下来定义左边的布局文件 layout_menu.xml,这里定义的是ListView列表视图

<?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"><ListViewandroid:id="@+id/listview"android:layout_width="match_parent"android:layout_height="match_parent" /></LinearLayout>

③、再给这个列表视图定义一个名为layout_item.xml ,等下用来给列表插入内容

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:orientation="vertical"android:layout_height="match_parent"><ImageViewandroid:id="@+id/image"android:layout_width="wrap_content"android:layout_gravity="center_horizontal"android:layout_height="100dp"/><TextViewandroid:id="@+id/name"android:layout_gravity="center_horizontal"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textColor="#fff"android:textSize="18sp"android:layout_marginTop="5dp"android:layout_marginBottom="5dp"/></LinearLayout>

④、接下来定义右边的布局 layout_content.xml ,这个布局文件很简单,在这个右边的xml文件中定义一个TextView来装文字

<?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"><TextViewandroid:id="@+id/content"android:layout_width="match_parent"android:layout_height="match_parent"android:textSize="20sp"android:textColor="#fff"android:layout_margin="5dp"/></LinearLayout>

ok看完了所有的xml文件,接下来看一下java文件

⑤、首先看一下主文件MainActivity.java 。 其中的一大段文字可以忽略不看。

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentTransaction;
import android.os.Bundle;public class MainActivity extends AppCompatActivity {private int [] icon={R.drawable.foot_one,R.drawable.bg_people,R.drawable.bg_people2};private String [] content={"自由的行走,更是一路寻味日料的美食狂欢!\n" +"农业、畜牧业和水产业都很发达的 北海道 有着得天独厚的优势,道产的丰富食材在 日本 从来都是高品质的代名词。\n" +"再加上 欧洲 美食文化的深远影响,让人在这里不仅仅能吃到拉面、寿司等传统地道日式料理。\n" +"更有超赞的甜品、烤肉、海鲜等等,绝对让人大快朵颐、流连忘返。","港口的开放带动了市井的繁荣,数不清的西洋人与西洋文化从这里上岸,源源不断的向内陆传播。\n" +"踏上这片已近零下的冰雪大地。\n" +"山日出- Greenpia大沼滑雪场-七饭滑雪场Peak Cafe- 函馆 山百万夜景-八幡坂-一文字 函馆 盐味拉面\n" +"朝市-大沼国定公园-Sushidokoro Kihara寿司料理- 函馆 市热带植物园-无印良品-丸井今井 函馆 -五棱郭夜景\n","年假东拼西凑9天,不想像去年的 青海 一样赶。 云南 是很慢节奏的,放空发呆无疑是最好的形容词。\n" +"没有很多行程安排,随意走进一家店喝杯东西发发呆就很舒服了,亦或是在民宿楼顶吹吹风拍拍照。\n" +"这次出行最让我上心的大概就是订民宿了,网红打卡(小红书推荐)的民宿都要提前三个月左右预定,没有订到不重要,其实还有很多环境不错只是没有被发掘到的店\n" +"关于远方的梦你准备什么时候出发?"};private String [] name={"舌尖上的浪漫狂欢","慢行日本","远方的第一个梦"};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);start();}public  void start(){MenuActivity menuActivity;ContentActivity contentActivity;menuActivity = new MenuActivity();contentActivity = new ContentActivity();FragmentTransaction fragmentTransaction=getSupportFragmentManager().beginTransaction();fragmentTransaction.replace(R.id.left_fragement,menuActivity);fragmentTransaction.replace(R.id.right_fragement,contentActivity);fragmentTransaction.commit();}
//这里的三个get方法是用来后面给MenuActivity.java文件中调用此文件中的数据用的public int[] getIcon() {return icon;}public String[] getContent() {return content;}public String[] getName() {return name;}
}

看这一段代码的意思

  • 创建待添加的碎片实例。
  • 获取到FragmentManager,在活动中可以直接调用getFragmentManager()方法得到。
  • 开启一个事务,通过调用beginTransaction()方法开启。
  • 向容器内加入碎片,一般使用replace()方法实现,需要传入容器的id和待添加的碎片实例。
  • 提交事务,调用commit()方法来完成。
public  void start(){MenuActivity menuActivity;ContentActivity contentActivity;menuActivity = new MenuActivity();contentActivity = new ContentActivity();FragmentTransaction fragmentTransaction=getSupportFragmentManager().beginTransaction();fragmentTransaction.replace(R.id.left_fragement,menuActivity);fragmentTransaction.replace(R.id.right_fragement,contentActivity);fragmentTransaction.commit();
}

⑥、接下来看ContentActivity.java文件。

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;public class ContentActivity extends Fragment {private TextView textView;@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {View view=inflater.inflate(R.layout.layout_content,container,false);if(view!=null){textView=view.findViewById(R.id.content);}MainActivity mainActivity=new MainActivity();String [] str=mainActivity.getContent();textView.setText(str[0]);return view;}//这段代码在接下来的MenuActivity.java中起到点击类表中那个视图就改变右边内容的目的void setContent(String str){textView.setText(str);}
}

下面我们看一下这个ContentActivity.java文件中关键的代码

  • 这里仅仅是重写了Fragment的onCreateView()方法,然后在这个方法中通过LayoutInflater的inflate()方法将刚才定义的layout_content.xml布局动态加载进来。
  • 我在这里加了一个判断,让文件一开始启动就会显示默认显示第一个内容
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {View view=inflater.inflate(R.layout.layout_content,container,false);if(view!=null){textView=view.findViewById(R.id.content);}MainActivity mainActivity=new MainActivity();String [] str=mainActivity.getContent();textView.setText(str[0]);return view;
}

⑦、接下来看一下最主要的文件MenuActivity.java 。这里的代码有点多,我们慢慢看

import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;public class MenuActivity extends Fragment implements AdapterView.OnItemClickListener {private int[] seticon;private String [] setname;private String [] setcontent;private MainActivity mainActivity=new MainActivity();private ListView listView;@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {View view=inflater.inflate(R.layout.layout_menu,container,false);seticon=mainActivity.getIcon();setname=mainActivity.getName();setcontent=mainActivity.getContent();if (view!=null){listView=view.findViewById(R.id.listview);listView.setAdapter(new MyAdapter());}listView.setOnItemClickListener(this);return view;}@Overridepublic void onAttach(Context context) {mainActivity= (MainActivity) context;super.onAttach(context);}@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {mainActivity= (MainActivity) getActivity();FragmentManager fm=mainActivity.getSupportFragmentManager();ContentActivity contentActivity= (ContentActivity) fm.findFragmentById(R.id.right_fragement);contentActivity.setContent(setcontent[position]);}class MyAdapter extends BaseAdapter{@Overridepublic int getCount() {return setname.length;}@Overridepublic Object getItem(int position) {return setname[position];}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder;if (convertView==null){holder=new ViewHolder();convertView=View.inflate(getActivity(),R.layout.layout_item,null);holder.imageView=convertView.findViewById(R.id.image);holder.textView=convertView.findViewById(R.id.name);convertView.setTag(holder);}else{holder= (ViewHolder) convertView.getTag();}holder.imageView.setBackgroundResource(seticon[position]);holder.textView.setText(setname[position]);return convertView;}}static class ViewHolder{ImageView imageView;TextView textView;}
}

我们可以把这部分的代码分为两份,一份是ListView部分的代码,一部分是Fragment部分的代码

  • 首先我们看一下ListView部分
    关于这里ListView的作用就不细说,这又是另外一个知识点了。反正左右就是把layout_item导入ListView的每个列表中
class MyAdapter extends BaseAdapter{@Overridepublic int getCount() {return setname.length;}@Overridepublic Object getItem(int position) {return setname[position];}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder;if (convertView==null){holder=new ViewHolder();convertView=View.inflate(getActivity(),R.layout.layout_item,null);holder.imageView=convertView.findViewById(R.id.image);holder.textView=convertView.findViewById(R.id.name);convertView.setTag(holder);}else{holder= (ViewHolder) convertView.getTag();}holder.imageView.setBackgroundResource(seticon[position]);holder.textView.setText(setname[position]);return convertView;}
}static class ViewHolder{ImageView imageView;TextView textView;
}

我们重点看一下这里重写的Fragment中的onCreateView方法内的内容,我们将代码内容从上往下分析

  • 我们先定义了一个类MainActivity的对象mainActivity,并将MainActivity类中的三个get方法写到了本类中
  • 接下来进行一个判断,如果视图不为空,那么就用将适配器中的内容放入ListView中。然后设置ListView的点击事件
  • 接下来是重写onAttach方法,让Fragment随Activity一起启动
  • 下面就是定义的ListView事件了,点击事件触发时:
    getActivity(); 这个方法能够得到与本Fragment关联的那个Acitivty,通过强制转换可以得到MainActivity对象,(MainActivity)getActivity() 得到了MainActivity对象
    getSupportFragmentManager();通过Activity下的这个方法getSupportFragmentManager()来得到 FragmentManager 对象。
    findFragmentById(); 这个 FragmentManager下的方法 findFragmentById()来找到指定ID的Fragment对象。 这里将值赋给了ContentActivity的对象
    再调用ContentActivity中的setContent方法,将指定内容的文本方法右边的Fragment上
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {View view=inflater.inflate(R.layout.layout_menu,container,false);seticon=mainActivity.getIcon();setname=mainActivity.getName();setcontent=mainActivity.getContent();if (view!=null){listView=view.findViewById(R.id.listview);listView.setAdapter(new MyAdapter());}listView.setOnItemClickListener(this);return view;}@Overridepublic void onAttach(Context context) {mainActivity= (MainActivity) context;super.onAttach(context);}@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {mainActivity= (MainActivity) getActivity();FragmentManager fm=mainActivity.getSupportFragmentManager();ContentActivity contentActivity= (ContentActivity) fm.findFragmentById(R.id.right_fragement);contentActivity.setContent(setcontent[position]);}

最后我们来看一下效果图

点击左边的内容之后改变右边的文本
内容有点少,后面我们可以通过数据库来添加数据

好啦,关于Fragment的案例就到这里

博客中引用到的文章链接:

Android Fragment的用法

Fragment的用法,举例介绍相关推荐

  1. c++ hashset的用法_c++ stl容器set成员函数介绍及set集合插入,遍历等用法举例

    c++ stl集合set介绍 c++ stl集合(Set)是一种包含已排序对象的关联容器.set/multiset会根据待定的排序准则,自动将元素排序.两者不同在于前者不允许元素重复,而后者允许. 1 ...

  2. android studio 导入包分不分动态静态,详解Android studio 动态fragment的用法

    fragment的使用时Android的基础,它有两种用法,第一个就是静态的fragment.第二个则是动态的fragment. 静态fragment直接在layout创建你想要的fragment的X ...

  3. Fragment的基础知识介绍详解必看

    一.Fragment的基础知识介绍 1.1概述 1.1.1 特性 Fragment是activity的界面中的一部分或一种行为.可以把多个Fragment组合到一个activity中来创建一个多界面 ...

  4. sequence.pad_sequences 的用法举例

    sequence.pad_sequences 的用法举例_power的专栏-CSDN博客

  5. 【转】awk 里的substr函数用法举例

    awk 里的substr函数用法举例: 要截取的内容: 2007-08-04 04:45:03.084 - SuccessfulTradeResult(status: 1, currencyPair: ...

  6. linux nc命令用法举例

    nc命令用法举例 什么是nc nc是netcat的简写,有着网络界的瑞士军刀美誉.因为它短小精悍.功能实用,被设计为一个简单.可靠的网络工具 nc的作用 (1)实现任意TCP/UDP端口的侦听,nc可 ...

  7. html post举例,html post请求之a标签的两种用法举例

    html post请求之a标签的两种用法举例 1.使用ajax来发起POST请求 HTML代码如下:发起POST请求a> JQuery代码如下:$(".a_post").on ...

  8. fclose在c语言中的作用,c语言fcloseall函数用法实例介绍

    c语言fcloseall函数用法实例介绍.fcloseall函数的返回值,函数 fcloseall() 将所有打开的流与其底层的文件或功能集合关闭.任何缓冲的数据都将首先被写入,使用 fflush(3 ...

  9. 车辆保险详细说明举例介绍

    轉:http://blog.163.com/cheliang_baoxian/blog/static/180520164201111883859383/ 车辆保险详细说明举例介绍 交强险 交强险是法律 ...

最新文章

  1. 让我去健身的不是漂亮小姐姐,居然是贝叶斯统计!
  2. java的线程管理器,QuickThread - Java线程池管理器
  3. Golang 入门系列(九) 如何读取YAML,JSON,INI等配置文件...
  4. pb更新oracle表格,PB自定义retrieve刷新函数、PB导入excel表、打印
  5. SqlServer 根据一个表数据更新另外一个表
  6. CVPR2016:ResNet 从根本上解决深度网络退化问题
  7. 服务器配置 | 3306端口被占用,phpStudy无法启动Apache
  8. Facebook史上最严重宕机,全网宕机近七小时,到底是怎么回事?
  9. softmax回归的从零开始实现
  10. 用matlab实现视频截图字幕部分的拼接
  11. iOS原生的AVFoundation扫描二维码/条形码
  12. 十四、springBoot2.0 自定义异常
  13. mc:Ignorable=“d“什么意思?
  14. 有那些适合苹果手机用的蓝牙耳机?适合苹果手机用的蓝牙耳机推荐
  15. Java日期有效性验证
  16. 解决最新版 mac os sierra usb网卡不能使用的问题
  17. 解决:SCRIPT5011: Can't execute code from a freed script
  18. MySql索引优化及Explain工具使用
  19. 内存泄漏检测工具:Deleaker 2022
  20. 怎么看手机计算机的记录表,教您如何查看6个月前的通话记录,包括中国联通手机!...

热门文章

  1. [又值奥运季] 2016年里约奥运会--8月20日赛事
  2. 个人总结php笔试题五
  3. DIV+CSS布局概述、属性(浮动、定位等)、布局类型、常见布局技巧
  4. 最近几天小说站的观察
  5. Android入门(四)——页面跳转
  6. mysql安装时卡在starting server的解决方法
  7. Intellig IDEA 中文设置 汉化
  8. matlab中显示变量大小写,科学网—一些MATLAB的编程规范总结1.0版 - 何亮的博文
  9. java实现QQ互联登录
  10. 边缘自适应的插值算法