android—代码动态布局笔记

来源:互联网 发布:淘宝月赚3000多很难吗 编辑:程序博客网 时间:2024/06/15 05:30

       在android项目中,大多数界面布局都是通过.xml文件布局的,少部分情况,或者一些特殊项目的需求会使用到代码动态布局。写这篇博客的目的主要是为了记录自己在项目中经常使用动态布局,偶尔会遇到一些版本适配和布局差异的问题。以此记录,在下次遇到的时候方便查阅。从使用角度来分析,动态布局是要比常规的静态布局(.xml)更为复杂一些,而且限制也比较多。首次接触,可以先写出静态布局,再根据API转化成动态布局。

      下面我们先来看一个比较简单的静态布局和动态布局的对照比较:

效果图:


静态布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="@android:color/darker_gray"    android:orientation="vertical" >    <ImageView        android:layout_width="90dp"        android:layout_height="90dp"        android:layout_gravity="left"        android:src="@drawable/v" />    <EditText        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_marginTop="5dp"        android:hint="static layout!" />    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="horizontal" >        <Button            android:id="@+id/bt1"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:text="delete all" />        <Button            android:id="@+id/bt2"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:text="search answer" />    </LinearLayout></LinearLayout>

动态布局代码:

public class DynamicView extends LinearLayout {public DynamicView(Context context) {this(context, null);}public DynamicView(Context context, AttributeSet attrs) {super(context, attrs);this.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));this.setOrientation(LinearLayout.VERTICAL);this.setBackgroundColor(Color.GRAY);// photoImageView imageView = new ImageView(context);imageView.setBackgroundResource(R.drawable.v);LinearLayout.LayoutParams imageViewParams = new LinearLayout.LayoutParams(dip2px(context, 90),dip2px(context, 90));imageViewParams.gravity = Gravity.LEFT;this.addView(imageView, imageViewParams);// inputEditText editText = new EditText(context);editText.setHint("static layout!");LinearLayout.LayoutParams editTextParams = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT);editTextParams.topMargin = dip2px(context, 5);this.addView(editText, editTextParams);LinearLayout linearLayout = new LinearLayout(context);linearLayout.setOrientation(LinearLayout.HORIZONTAL);LinearLayout.LayoutParams linearLayoutParams = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT);// but1Button button1 = new Button(context);button1.setText("delete all");LinearLayout.LayoutParams button1Params = new LinearLayout.LayoutParams(dip2px(context, 0),LayoutParams.WRAP_CONTENT);button1Params.weight = 1;linearLayout.addView(button1, button1Params);// but2Button button2 = new Button(context);button2.setText("search answer");LinearLayout.LayoutParams button2Params = new LinearLayout.LayoutParams(dip2px(context, 0),LayoutParams.WRAP_CONTENT);button2Params.weight = 1;linearLayout.addView(button2, button2Params);this.addView(linearLayout, linearLayoutParams);}/** * 根据手机的分辨率从 dp 的单位 转成为 px(像素) */public static int dip2px(Context context, float dpValue) {final float scale = context.getResources().getDisplayMetrics().density;return (int) (dpValue * scale + 0.5f);}}
       如上,我们大概可以简单的对比出两种布局的一些实现差异。整个流程下来,静态布局确实简单了很多。动态布局则需要对布局控件api的一些基本属性有所认知,更重要的是要考虑,它的一个层次规范。从另外一个角度来说,静态布局我们可以在书写过程中,可以随时查看他的展示而做出调整,动态布局就不行,只能是通过运行结果,来做调整,整个过程也变得更为麻烦。

接下来,是我在动态布局中遇到的一些问题,在此罗列,希望在下次碰到的时候,可以直接搬过去用。

1,layout.setGravity(Gravity.CENTER)和layoutParams.gravity = Gravity.CENTER;的区别;

       动态布局中,LinearLayout的使用比较多,其中控制控件方向主要通过这两个属性。两者的区别在于layout.setGravity(Gravity.CENTER)控制得是子控件相对于父控件的位置,配合layout.setOrientation(LinearLayout.VERTICAL或HORIZONTAL);的使用,来控制子控件的对齐关系。layoutParams.gravity = Gravity.CENTER;控制得是自身相对于父布局的一个位置,与父布局关联(如果父控件控制了子控件居中,那么孩子自己控制位置属性只能是在父亲前提之下控制自己的位置)。其实这两个属性就相当于静态布局中的android:gravity="center";和android:layout_gravity="center";

2,RelativeLayout控件的部分属性使用;

        RelativeLayout控制位置与LinearLayout不同,基本上主要有相对于整个布局的一些属性,例如居中于父布局,在父布局的左边等等之类的。这部分属性的使用RelativeLayout控件中需要使用relativeLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);来控制。

3,布局技巧

      动态布局其实很不利于开发者开发,代码太过繁杂。而且如果需要动态更新界面并不想常规设置那么简单(比如用代码写一个圆,在不同情况下更换颜色),有些情况下是没办法直接更换背景的。这时候的处理方式就是 ,一开始就把不同颜色的布局加进来,而需要的时候需要控制好控件的隐藏和显示。不过这也会带来一些过度渲染的问题。也需要控制绘制的量。

4,Android低版本适配问题:(FrameLayout不能转化为AbsListView)

       发生这个情况的分析,可能是Google5.0以后的api会自动转化(没看过源码),在Android4.4.2以下版本中不会,需要主动将布局控件转为ABSListView。具体原因是这样的;Framelayout和AbsListView都是ViewGroup的子控件,处于同一等级。而GridView和ListView是AbsListView的子控件,等级小于FrameLayout,所以不可以直接转化。我的GridView添加的item因为继承的是FrameLayout,所以要把它转为AbsListView,如此才能够使用。

以上所有内容,就是我初次学习动态布局所接触的api和所碰到的问题。其实现在的大多数开发都不用到这总布局模式,这里也是给自己做个记录,仅供参考。首次写博客,有很多不足之处,请多多指教。

0 0
原创粉丝点击