Android开发之UI常用属性
介绍控件和布局中的一些属性和片段
属性篇
1.属性android:visibility
(所有控件中都具有的属性,在progressbar中较常用)
可选值有三种:visible、invisible、gone
invisible表示控件不可见,但它仍然占据着原来的位置和大小
gone表示控件不可见&控件不占用屏幕空间
还可以在代码中设置控件的可见性:
setVisibility(View.VISIBLE);传入View.VISIBLE、View.INVISIBLE或View.GONE三种值
- 关于android中调用某个样式或者属性时应该用@还是用?的问题,例如:
style="?android:attr/progressBarStyleHorizontal"
关于用@还是用?的问题,具体解释请点这里
2.dp和sp、dip、px、pt之间的换算问题
- dp(密度无关的像素),一种基于屏幕密度的抽象单位,2英寸3英寸的320像素480像素中,屏幕密度为320/2=160dip。即在每英寸160点的显示器上,1dp=1px。
(密度为160时,1dp=1px;密度为320时,1dp=2px) - sp(与刻度无关的像素,指定文字大小):与dp类似,但是可以根据用户的字体大小首选项进行缩放。
- dip 与dp相同
- px 分辨率
- pt(磅),1/72英寸。
一般Android设置长宽多用dip,设置字体多用sp,在屏幕密度为160时,说明每英寸有160个px,即160px=1in。又因为此时有1sp=1dip=1px(在屏幕密度160的特定条件下),所以有160sp=1in,再加上1pt=1/72in,即72pt=1in,所以72pt=160sp,化简得1pt≈2.22sp(是一道换算题哦(/▽\))
PS:分辨率与密度的概念:分辨率指相对于软件来说的显示像素,以px为单位;密度表示每英寸有多少个像素,density=240->用hdpi标签的资源,density=160->mdpi,density=120->ldpi
3. 点9图
左和上绘制的线代表拉伸区域,右和下绘制的线代表内容被放置区域
4.碎片(Fragment)
属于UI片段
让程序更加合理地利用大屏幕的空间
像这样:
Amazing!!!
Fragment的用法
导包问题
创建Fragment类所继承的包使用support-v4,因为它可以让碎片在所有Android系统版本中保持功能一致性;
而且不需要将该包的依赖添加到build.gradle,因为build.gradle中添加的appcompat-v7库会将support-v4库一起引入进来。Activity布局文件中引入fragment时
需要在xml文件中的标签中添加name属性用来指定Fragment的类,如下:
- 动态添加碎片的用法
关键步骤:
R.id.right_layout
表示界面中的一块布局区域的id,如FrameLayout
布局的id。
具体步骤为:
- 创建待添加的碎片实例
- 获取FragmentManager,在活动中可直接通过
getSupportFragmentManager()
方法得到 - 开启一个事务,通过调用
beginTransaction()
方法开启 - 向容器内添加或替换碎片
- 提交事务,调用
commit()
方法来完成
这里有个大坑:
需要让每个自定义的Fragment
类继承自android.support.v4.app.Fragment
类。
切记!! android.support.v4.app.Fragment
与android.app.Fragment
不要混用。
MainActivity类要继承FragmentActivity
类或者AppCompatActivity
类,不然在第二步的getSupportFragmentManager()
方法找不到,会报Cannot resolve method 'getSupportFragmentManager()'错误。
如果使用的是AppCompatActivity
类,则需要将theme改成Theme.AppCompat或其派生类,否则会报以下错误:
You need to use a Theme.AppCompat theme (or descendant) with this activity.
- 在碎片中模拟返回栈(按下返回键不是直接退出程序,而是返回上一个fragment中)
其中的参数是用于描述返回栈状态的名字
- 碎片和活动之间进行通信
- 在碎片中获取活动的实例:
MainActivity activity=(MainActivity)getActivity();
- 在活动中获取碎片的实例:
RightFragment rightFragment=(RightFragment)getFragmentManager().findFragmentById(R.id.right_fragment);
- 碎片和碎片之间互相调用:
先在碎片中调用相关联的活动,在用这个活动去调用碎片
- fragment的生命周期
运行状态:可见&&关联的活动在运行
暂停状态:活动进入暂停状态时
停止状态:活动进入停止状态||通过调用FragmentTransaction
的remove()
、replace()
方法从活动中移除&&事务提交之前用了addToBackStack()
方法
销毁状态:活动被销毁时||通过调用FragmentTransaction
的remove()
、replace()
方法从活动中移除&&事务提交之前没有用用addToBackStack()
方法
- 其它回调:
onAttach()
---碎片和活动建立关联
onCreateView()
---为碎片创建视图(加载布局)时调用
onActivityCreated()
---与之关联的活动已创建完毕时
onDestroyView()
---碎片关联的视图被移除时
onDetach()
--碎片和活动解除关联时
上一个糊糊的图:(✿◡‿◡)
- 动态加载布局的技巧
- 使用限定符
Qualifier:在运行时,根据屏幕大小判断是使用单页模式还是双页模式
使用步骤:
- 在layout目录下的main_activity.xml中只写一个
,在res目录下再写一个layout-large目录,写两个
,代表双页模式,“large”就是限定符,屏幕被认为是large的设备就会自动加载layout-large文件夹下的布局,而小屏幕的设备还是会加载layout文件夹下的布局。
- 碎片的屏幕适配
判断单页和双页:
在onActivityCreated()方法中判断:
getActivity().findViewById(R.id....)!=null
判断能否找到对应id的View,来设置是单页模式还是双页模式,能找到则说明在xml文件中定义了该View,这时可以刷新对应的fragment中的内容:
RightFragment fragment=(RightFragment)getFragmentManager().findFragmentById(R.id....);
fragment.refresh(String stra,String strb);
如果找不到则可以开启单独的Activity来显示内容:
SecondActivity.actionStart(getActivity(),str1,str2...);
actionStart是SecondActivity中的一个静态方法,在该方法中打开另一个Activity的话,需要将MainActivity的Context用参数的方式传递过去,而且还需要为SecondActivity添加flag,使SecondActivity放到另一个独立的任务栈中,具体关于flag的笔记将写在《Android开发艺术探索》笔记中。
fragment相关的代码点这里
5. android:layout_weight属性
android:layout_width="0dp"
android:layout_weight="1"
如果多个同级控件一起定义了这两个属性,而父布局是android:layout_width="match_parent"或android:layout_width="wrap_content"时,两个控件在水平方向上平分宽度,原理是系统按照该属性指定的值(上面的例子是“1”)在水平方向上所有控件的layout_weight值的比例划分宽度,值越大,划分宽度越大。
如果是如下情况:
表明Button的宽度仍然按照wrap_content来计算,而EditText会占满屏幕所有的剩余空间。
6. gravity和layout_gravity属性
android:gravity用于设置View中内容相对于View组件的对齐方式;
android:layout_gravity用于设置View组件相对于Container的对齐方式。
说的再直白点,就是android:gravity只对该组件内的东西有效,android:layout_gravity只对组件自身有效。
android:layout_gravity 只在 LinearLayout 和 FrameLayout 中有效
在LinearLayout中:
android:orientation=vertical (垂直) 时,只有水平方向的left,right,center_horizontal
是生效的。
android:orientation=horizontal (水平) 时,只有垂直方向的top,bottom,center_vertical
是生效的。
在FrameLayout布局中:
任意android:layout_gravity属性都有效
到这里UI的属性和片段介绍就记完了,后续对这部分有所领悟还会继续添加内容(^^ゞ