Android利用FlexboxLayout轻松实现流动布局
作者:爱开发 发布时间:2021-06-24 02:41:53
前言
相信大家应该都有所体会,在以前我们要实现流动性布局,比较繁琐,Google开源了一个项目叫FlexboxLayout,相信大家都不陌生。下面我们来学习一下FlexboxLayout基础知识,并通过一个案例来加深理解。如果你对FlexboxLayout很熟悉,请忽略本文。
一、什么是 Flexbox
简单来说 Flexbox 是属于web前端领域CSS的一种布局方案,是2009年W3C提出了一种新的布局方案,可以响应式地实现各种页面布局,并且 React Native 也是使用的 Flex 布局。
我们可以简单的理解为 Flexbox 是CSS领域类似 Linearlayout 的一种布局,但比 Linearlayout 要强大的多。
二、 什么是 FlexboxLayout?
我们在 Android 开发中使用 Linearlayout + RelativeLayout 基本可以实现大部分复杂的布局,但是Google就想了,有没有类似 Flexbox 的一个布局呢?这使用起来一个布局就可以搞定各种复杂的情况了,于是 FlexboxLayout 就应运而生了。
所以 FlexboxLayout 是针对 Android 平台的,实现类似 Flexbox 布局方案的一个开源项目
我们先看看官方Demo的效果图
开源地址:https://github.com/google/flexbox-layout
本地下载:点击这里
三、使用方式
使用方式很简单,只需要添加以下依赖:
compile 'com.google.android:flexbox:0.2.2'
在xml布局中我们可以这样使用
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/flexbox_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:flexWrap="wrap">
<TextView
android:id="@+id/tv1"
android:layout_width="120dp"
android:layout_height="80dp"
app:layout_flexBasisPercent="50%" />
<TextView
android:id="@+id/tv2"
android:layout_width="80dp"
android:layout_height="80dp"
app:layout_alignSelf="center"/>
<TextView
android:id="@+id/tv3"
android:layout_width="160dp"
android:layout_height="80dp"
app:layout_alignSelf="flex_end"/>
</com.google.android.flexbox.FlexboxLayout>
代码中可以这样使用
FlexboxLayout flexboxLayout = (FlexboxLayout) findViewById(R.id.flexbox_layout);
flexboxLayout.setFlexDirection(FlexboxLayout.FLEX_DIRECTION_COLUMN);
View view = flexboxLayout.getChildAt(0);
FlexboxLayout.LayoutParams lp = (FlexboxLayout.LayoutParams) view.getLayoutParams();
lp.order = -1;
lp.flexGrow = 2;
view.setLayoutParams(lp);
我们来看看要模仿的布局
下面我们来实现它,先来看最终实现的效果:
实现方法如下:
1. 新建activity_flow.xml布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/flexbox_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:flexWrap="wrap" />
</RelativeLayout>
布局很简单,只有一个FlexboxLayout 因为我们需要动态创建它的item,所以就在这里固定写TextView了
2. 新建ActivityFlow Activity,填充数据源
String[] tags = {"婚姻育儿", "散文", "设计", "上班这点事儿", "影视天堂", "大学生活", "美人说", "运动和健身", "工具癖", "生活家", "程序员", "想法", "短篇小说", "美食", "教育", "心理", "奇思妙想", "美食", "摄影"};
flexboxLayout = (FlexboxLayout) findViewById(R.id.flexbox_layout);
for (int i = 0; i < tags.length; i++) {
Book model = new Book();
model.setId(i);
model.setName(tags[i]);
flexboxLayout.addView(createNewFlexItemTextView(model));
}
其中Book为一个实体,这个不是关键,关键的是createNewFlexItemTextView方法
我们要动态加载FlexboxLayout其FlexItem 并且让FlexboxLayout中的item支持点击事件,因为我们需要知道用户点击了哪个专题跳转。
我们来看一下createNewFlexItemTextView方法
/**
* 动态创建TextView
* @param book
* @return
*/
private TextView createNewFlexItemTextView(final Book book) {
TextView textView = new TextView(this);
textView.setGravity(Gravity.CENTER);
textView.setText(book.getName());
textView.setTextSize(12);
textView.setTextColor(getResources().getColor(R.color.colorAccent));
textView.setBackgroundResource(R.drawable.tag_states);
textView.setTag(book.getId());
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.e(TAG, book.getName());
}
});
int padding = Util.dpToPixel(this, 4);
int paddingLeftAndRight = Util.dpToPixel(this, 8);
ViewCompat.setPaddingRelative(textView, paddingLeftAndRight, padding, paddingLeftAndRight, padding);
FlexboxLayout.LayoutParams layoutParams = new FlexboxLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
int margin = Util.dpToPixel(this, 6);
int marginTop = Util.dpToPixel(this, 16);
layoutParams.setMargins(margin, marginTop, margin, 0);
textView.setLayoutParams(layoutParams);
return textView;
}
其他有关Book实体和Util类,也贴出来一下
Book实体
public class Book {
private int id;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Book() {
}
}
Util工具类
public class Util {
public static int pixelToDp(Context context, int pixel) {
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
return pixel < 0 ? pixel : Math.round(pixel / displayMetrics.density);
}
public static int dpToPixel(Context context, int dp) {
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
return dp < 0 ? dp : Math.round(dp * displayMetrics.density);
}
}
这样关于流动布局[FlexboxLayout],我们就实现完成了,是不是很简单。
来源:http://www.jianshu.com/p/217b3f4a1a18
猜你喜欢
- 简介基于springboot,mybatis plus集成了一套多数据源的解决方案,在使用时引入相应的插件dynamic-datasourc
- 1 初识Mybatis-Plus MyBatis-Plus简称 MP,是一个 MyBatis的增强工具,在MyBatis的基础上只做增强不
- 1. JNI简介JNI是Java Native Interface的英文缩写,意为Java本地接口。问题来源:由于Java编写底层的应用较难
- 手动编写 SQL 语句和映射实体类的过程常常是繁琐且易出错的。这时,我们就可以借助 MyBatis Generator (MBG) 这个强大
- 本文实例讲述了Android实现长按back键退出应用程序的方法。分享给大家供大家参考。具体分析如下:最近在做一个Android上的应用,碰
- 本文实例讲述了Java实现克隆的三种方式。分享给大家供大家参考,具体如下:1、浅复制(浅克隆)这种浅复制,其实也就是把被复制的这个对象的一些
- 说明本项目采用 maven 结构,主要演示了 spring mvc + mybatis,controller 获取数据后以json 格式返回
- 小伙伴们在使用ICP提供的各种能力进行集成开发时常常会遇到一些技术上的困扰,例如ICP中很多接口是通过OCX控件的方式提供的,如何调用这些接
- 在《Spring Boot Hello World》中介绍了一个简单的spring boot例子,体验了spring boot中的诸多特性,
- 1:Xxtea支持中文;2:支持JS和C#加解密之间的互转;一:C#部分class XXTEA2 {
- 前言Android 8.0系统更新之后,app的更新将不再像之前的系统版本一样能够直接下载安装包之后直接安装(以前安装未知来源应用的时候一般
- 引言什么?兔了个兔?吐了还要吐?首先今天,我们自己用android程序实现一个兔年的新年贺卡。下面就是见证美好的时刻,上效果。好,我们来使用
- 正则表达式 是一种匹配输入文本的模式。.Net 框架提供了允许这种匹配的正则表达式引擎。模式由一个或多个字符、运算符和结构组成。接下来通过本
- 本文实例总结了C#实现启用与禁用本地网络的方式。分享给大家供大家参考,具体如下:1) 使用Hnetcfg.dll使用Add Referenc
- 1 使用Office自带的库前提是本机须安装office才能运行,且不同的office版本之间可能会有兼容问题,从Nuget下载 Micro
- 在开始之前,我先卖个关子提一个问题:假设我们有一个Movie类,这个类有三个成员变量分别是starred(是否收藏), title(电影名称
- 前言RecyclerView是我们常用的列表控件,一般来说当Item的数据改变的时候我们需要刷新当前的Item 。如何刷新 RV 的列表?基
- 破解流程破解Android程序流程:反编译—>分析–>修改–>回编译–>签名,这些都是在命令行中操作,当然也有集成了
- 在早期的Java版本中,如果需要对指定目录下的文件进行遍历,则需要用递归的方法来实现,这种方法有点复杂,而且灵活性也不高。而使用Java7中
- 本章主要建立在已经安装好Erlang以及RabbitMQ的基础上,接下来,简单介绍一下使用一、Direct直接模式 通过routingKey