Android AutoLayout 使用记录
来源:互联网 发布:sql数据库文件修复 编辑:程序博客网 时间:2024/06/07 18:18
一、概述
最近学习使用Android AutoLayout解决适配问题,想要单纯使用这个库将适配很轻松的做好,还是有些问题需要注意的,个人就探索过程中遇到的问题进行记录,希望对后来者有所参考。
本库的地址:https://github.com/hongyangAndroid/AndroidAutoLayout
对于适配,我希望的效果是这样的:拿到设计图,meta信息中填入设计图的尺寸,然后不需要额外计算,布局直接抄设计图上的尺寸,不产生任何多余的资源文件,完成各种分辨率的适配。
二、直观的体验
通常带有标注的设计图如下:
如果没有提供这样的设计图,可以自己去测量,测量的方法有很多,这里不赘述了。
对于 新增旅客
布局文件可以这么写
<RelativeLayoutandroid:layout_width="match_parent"android:layout_height="86px"android:layout_marginTop="26px"android:background="#ffffffff"><ImageView android:id="@+id/id_tv_add" android:layout_width="34px" android:layout_height="34px" android:layout_gravity="center_vertical" android:layout_marginLeft="276px" android:layout_marginTop="26px" android:src="@mipmap/add" /><TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="26px" android:layout_toRightOf="@id/id_tv_add" android:text="新增旅客" android:textColor="#1fb6c4" android:textSize="32px" /></RelativeLayout>
对于Item的布局文件,可以这么写:
<RelativeLayout android:layout_width="match_parent" android:layout_height="108px" android:layout_marginTop="26px" android:background="#ffffffff" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="22px" android:layout_marginTop="16px" android:text="王大炮 WANG.DAPAO" android:textColor="#333" android:textSize="28px" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginBottom="16px" android:layout_marginLeft="22px" android:text="护照:G50786449" android:textColor="#999" android:textSize="26px" /></RelativeLayout>
说明:这里的px并不代表1像素,在内部会进行百分比化处理。按照百分比的规则,完美实现了适配,这样的好处是:
再也不用拿着设计稿去想这控件的宽高到底取多少dp
再也不用去为多个屏幕去写多个dimens
再也不用去计算百分比了(如果使用百分比控件完成适配)
再也不用去跟UI MM去解释什么是dp了
三、用法
(1)将AutoLayout引入
dependencies { compile project(':autolayout')}
也可以直接
dependencies { compile 'com.zhy:autolayout:1.4.3'}
(2)注册设计图尺寸
在项目的AndroidManifest中注明设计稿
的尺寸。
<meta-data android:name="design_width" android:value="768"></meta-data><meta-data android:name="design_height" android:value="1280"></meta-data>
(3)开启适配
有两种方式开启适配
1)将Activity继承AutoLayoutActivity
2)手动替换Layout布局文件中的
LinearLayout -> AutoLinearLayout
RelativeLayout -> AutoRelativeLayout
FrameLayout -> AutoFrameLayout
四、注意事项
(1)如何开启PreView
写布局文件的时候,如果不能实时的预览效果,那么体验真的是非常的不好,也在很大程度上降低开发效率,所以下面说明如何用好,用对PreView(针对该库)。
首先,要记得设计稿的尺寸,比如 768 * 1280
然后,在PreView面板,选择分辨率一致的设备:
然后就可以看到最为精确的
预览了。
(2)TextView的高度问题
关于TextView这个控件,可能和设计稿上会有一些出入,并非是此库的原因,而是与生俱来的特性。
设计稿一般只会标识一个字体的大小,比如你设置textSize=”20px”,实际上TextView所占据的高度肯定大于20px,字的上下都会有一定的间隙,所以一定要灵活去写字体的高度,比如对于text上下的margin可以选择尽可能小一点。或者选择别的约束条件去定位(比如上例,选择了marginBottom)
比如:
<TextView textSize="32px" layout_height="wrap_contnt" />
运行后肯定不是32px的高度,文字的上下方都会有一定的空隙。如果将高度写死,也会发现文字显示不全。
恩,所以呢,灵活应对这个问题,对于存在字体标识很精确的值,你可以选择:对于TextView与其他控件的上下边距呢,尽可能的稍微写小一点。
其实我上面的例子,几乎都是TextView,所有我在编写Item里面的时候,也有意缩小了一下marginTop值等。不过,对于其他控件是不存在这样的问题的。
ps:因为TextView的上述问题:所以对于居中,虽然可以使用本库通过编写margin_left,margin_top等很轻松的完成居中。但是为了精确起见,还是建议使用gravity,centerInXXX等属性完成。
(3)指定设置的值参考宽度或者高度
由于该库的特点,布局文件中宽高上的1px是不相等的,于是如果需要宽高保持一致的情况,布局中使用属性:
app:layout_auto_basewidth="height"
,代表height上编写的像素值参考宽度。
app:layout_auto_baseheight="width"
,代表width上编写的像素值参考高度。
如果需要指定多个值参考宽度即:
app:layout_auto_basewidth="height|padding"
用|隔开,类似gravity的用法,取值为:
width,heightmargin,marginLeft,marginTop,marginRight,marginBottompadding,paddingLeft,paddingTop,paddingRight,paddingBottomtextSize.
(4)将状态栏区域作为内容区域
如果某个Activity需要将状态栏区域作为实际的内容区域时,那么可用高度会变大,你所要做的只有一件事:让这个Activity实现UseStatusBar接口(仅仅作为标识左右,不需要实现任何方法),当然你肯定要自己开启windowTranslucentStatus或者设置FLAG_TRANSLUCENT_STATUS。
注意:仅仅是改变状态栏颜色,并不需要实现此接口,因为并没有实际上增加可用高度。
五、其他
目前支持属性
layout_widthlayout_heightlayout_margin(left,top,right,bottom)pading(left,top,right,bottom)textSizemaxWidth, minWidth, maxHeight, minHeight不会影响系统所有的其他属性,以及不会影响dp,sp的使用
性能的提升
通过本库的方式去编写代码,可以在很大程序上使用margin,也就是说,对于View的位置非常好控制,从而能够减少非常多的嵌套,甚至任何一个复杂的界面做到无嵌套。
以及,几乎不需要去使用RelativeLayout的规则了,比如rightOf,完全可以由marginLeft完成,其他的rule同理。
对于LinearLayout的weight,几乎也不需要使用了,比如屏幕宽度720px,想要四个控件横向均分,完全可以写layout_width=”180px”
相信通过上述的介绍,本库适配的做法可以说是目前见过的最方便的适配方案,最大化的减轻了适配的负担,甚至比不适配时编写UI都方便。目前本库,已经尝试用于项目中,尽可能去发现一些潜在的问题。
六、潜在的问题
(1)默认使用的高度是设备的可用高度,也就是不包括状态栏和底部的操作栏的,如果希望拿设备的物理高度进行百分比化,可以在Application的onCreate方法中进行设置:
public class UseDeviceSizeApplication extends Application{ @Override public void onCreate() { super.onCreate(); AutoLayoutConifg.getInstance().useDeviceSize(); }}
(2)对于其他继承系统的FrameLayout、LinearLayout、RelativeLayout的控件,比如CardView
,如果希望在其内部直接支持“px”百分比化,可以自己扩展,扩展方式为下面的代码,也可参考issue#21
package com.zhy.sample.view;import android.content.Context;import android.support.v7.widget.CardView;import android.util.AttributeSet;import com.zhy.autolayout.AutoFrameLayout;import com.zhy.autolayout.utils.AutoLayoutHelper;/** * Created by zhy on 15/12/8. */public class AutoCardView extends CardView{ private final AutoLayoutHelper mHelper = new AutoLayoutHelper(this); public AutoCardView(Context context) { super(context); } public AutoCardView(Context context, AttributeSet attrs) { super(context, attrs); } public AutoCardView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public AutoFrameLayout.LayoutParams generateLayoutParams(AttributeSet attrs) { return new AutoFrameLayout.LayoutParams(getContext(), attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (!isInEditMode()) { mHelper.adjustChildren(); } super.onMeasure(widthMeasureSpec, heightMeasureSpec); }}
(3)ListView、RecyclerView类的Item的适配(recyclerview 加载 RadioButton)
对于ListView这类控件的item,默认根局部写“px”进行适配是无效的,以为外层非AutoXXXLayout,而是ListView。但是,一行代码就可以支持了:
@Overridepublic View getView(int position, View convertView, ViewGroup parent){ ViewHolder holder = null; if (convertView == null) { holder = new ViewHolder(); convertView = LayoutInflater.from(mContext).inflate(R.layout.list_item, parent, false); convertView.setTag(holder); //对于listview,注意添加这一行,即可在item上使用高度 AutoUtils.autoSize(convertView); } else { holder = (ViewHolder) convertView.getTag(); } return convertView;}
注意AutoUtils.autoSize(convertView);
这行代码的位置即可。
同类方法还有:
AutoUtils.autoPadding(convertView);
等。
对于RecyclerView
public ViewHolder(View itemView){ super(itemView); AutoUtils.autoSize(itemView);}//...@Overridepublic ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){ View convertView = LayoutInflater.from(mContext).inflate(R.layout.recyclerview_item, parent, false); return new ViewHolder(convertView);}
一定要记得LayoutInflater.from(mContext).inflate
使用三个参数的方法!
(4)导入后出现org/gradle/api/publication/maven/internal/DefaultMavenFactory
最简单的方式,通过compile 'com.zhy:autolayout:x.x.x'
进行依赖使用,如果一定要以module引用,参考该issue#74
(5)RadioGroup,Toolbar等控件中的子View无法完成适配
解决方法跟(2)一样,需要自己扩展。不过这个很多使用者贡献了他们的扩展类可以直接使用, 参考autolayout-widget, 如果没有发现你需要的容器类,那么你就真的需要自行扩展了,ps:需要用到哪个copy就好了,不要直接引用autolayout-widget,因为其引用了大量的库,可能很多 库你是用不到的。例如:RadioGroup 无法适配
(6)暂时没找到横屏适配的方法,从github上提问有人说是采用传统的方法,横屏拉出来单独适配。。。。
(7)java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
这个问题是因为默认AutoLayoutActivity会继承自AppCompatActivity,所以默认需要设置 Theme.AppCompat的theme;
如果你使用的依旧是FragmentActivity等,且不考虑使用AppCompatActivity, 你可以选择自己编写一个MyAutoLayoutActivity extends 目前你使用的Activity基类,例如 MyAutoLayoutActivity extends FragmentActivity,然后将该库中AutoLayoutActivity中的逻辑 拷贝进去即可,以后你就继承你的MyAutoLayoutActivity就好了。
ps:还是建议尽快更新SDK版本使用AppCompatActivity,截止文档编写日期,SDK最新版本为1.4.3。
- Android AutoLayout 使用记录
- Android AutoLayout 使用
- autolayout使用中的一些坑记录
- Android中AutoLayout的使用
- android适配autolayout的使用心得体会
- Android AutoLayout
- AutoLayout使用
- Android Autolayout适配
- Android AutoLayout 学习笔记
- android autolayout适配
- AutoLayout android studio
- android autolayout框架
- Android layout系列-autolayout
- 编码使用autoLayout
- ScrollViwe 使用autolayout
- Xcode AutoLayout 使用方向
- Autolayout使用详细介绍
- UITableViewCell使用Autolayout
- Wookmark——瀑布流布局
- on方法绑定事件
- Mybatis 中的一个错误
- JS判断字符串长度(中文2字符,英文1字符),可调整
- Linux(CentOS)中常用软件安装,使用及异常——XManager, 中文支持,JDK
- Android AutoLayout 使用记录
- Ext下拉 ComboBox多选拓展代码(超好用)
- Android Studio 将moudle打包成jar
- UNIX网络编程--非阻塞connect的实现
- Android中封装View提供接口供点击事件回调的方法及使用
- 常见正则表达式匹配
- servlet安全问题
- Leetcode - Move Zeroes
- 3.12(反转单结点)