Android原理——动态代码布局
2015-03-03 10:45
295 查看
动态代码布局
如何添加代码布局代码布局注意的问题
代码布局和XML布局的性能比较
如何添加代码布局
for example —— 简单布局LinearLayoutLinearLayout llayout = new LinearLayout(mContext); llayout.setOrientation(LinearLayout.VERTICAL); LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT ); llayout.setLayoutParams(layoutParams); Button btn = new Button(mContext); btn.setText("This is Button"); btn.setPadding(8, 8, 8, 8); btn.setLayoutParams(lp); llayout.addView(btn); //这是在Activity的onCreate()中设置布局 setContentView(llayout); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(mContext, "This is dynamic activity", Toast.LENGTH_LONG).show(); } });
another example —— 复杂布局RelativeLayout
难点:子控件的相对位置关系的处理
//父控件 RelativeLayout myLayout = new RelativeLayout(this); myLayout.setBackgroundColor(Color.BLUE); //两个子控件 Button myButton = new Button(this); EditText myEditText = new EditText(this); //重点:生成对应的ID myButton.setId(generateViewId()); myEditText.setId(generateViewId()); //子控件位置 RelativeLayout.LayoutParams buttonParams = new RelativeLayout.LayoutParams( RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); buttonParams.addRule(RelativeLayout.CENTER_HORIZONTAL); buttonParams.addRule(RelativeLayout.CENTER_VERTICAL); RelativeLayout.LayoutParams textParams = new RelativeLayout.LayoutParams( RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); textParams.addRule(RelativeLayout.CENTER_HORIZONTAL); textParams.setMargins(0, 0, 0, 80); //重点在这里 textParams.addRule(RelativeLayout.ABOVE, myButton.getId()); //添加布局 myLayout.addView(myButton, buttonParams); myLayout.addView(myEditText, textParams); setContentView(myLayout);
重点要说的是
generateViewId(),这个可以专门放到工具类里:
/** * An {@code int} value that may be updated atomically. */ private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1); /** * 动态生成View ID * API LEVEL 17 以上View.generateViewId()生成 * API LEVEL 17 以下需要手动生成 */ public static int generateViewId() { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) { for (; ; ) { final int result = sNextGeneratedId.get(); // aapt-generated IDs have the high byte nonzero; clamp to the range under that. int newValue = result + 1; if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0. if (sNextGeneratedId.compareAndSet(result, newValue)) { return result; } } } else { return View.generateViewId(); } }
代码布局注意的问题
控件不能重复使用// 第一次添加
mLinearLayout.addView(mTextView, mLayoutParams);
// 第二次添加
mLinearLayout.addView(mTextView, mLayoutParams);
//我们重复添加了两次mTextView。这个是不允许的,在父类布局中,只能有唯一的对象,不能重复。
不同Activity中 Id 相同是否会报错
直接设置ID
setId(1)是不行的
生成ID须使用
View.generateViewId()
我的意见是建立静态工具类来生成ID
关于ID的int相同是否会出错的问题,目前还没有验证
一些常用的代码
textView.setTextColor(0xffff0000);
layout.setBackgroundColor(0x00000000);
setOrientation(LinearLayout.VERTICAL);
setGravity(Gravity.CENTER_VERTICAL)
setPadding(10, 5, 5, 5);
setMargin(8, 0, 0, 0);
lp.gravity = Gravity.CENTER_VERTICAL;
lp.topMargin = 5;
lp.addRule(RelativeLayout.CENTER_VERTICAL);
lp.addRule(RelativeLayout.RIGHT_OF, ID_IMAGE_HEAD);
代码布局和XML布局的性能比较
测试一个简单的例子使用代码布局如下:
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mContext = this; LinearLayout llayout = new LinearLayout(mContext); llayout.setOrientation(LinearLayout.VERTICAL); LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT ); llayout.setLayoutParams(layoutParams); TextView tv = new TextView(mContext); LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); lp.setMargins(8, 8, 8, 8); tv.setLayoutParams(lp); tv.setText("This is TextView"); tv.setPadding(8, 8, 8, 8); llayout.addView(tv); Button btn = new Button(mContext); btn.setText("This is Button"); btn.setPadding(8, 8, 8, 8); btn.setLayoutParams(lp); setContentView(llayout); }
三次测量平均值: (23+28 + 20)/3 = 23.67ms
使用相同XML布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:text="This is TextView" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="8px" android:padding="8px"/> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="This is Button" android:padding="8px"/> </LinearLayout>
三次测量平均值: (20 + 26 + 24)/3 = 23.33ms
结论:尽管样本单一,数量也很少,但是说明 代码布局 和 XML布局 加载时间基本相同,性能基本相同。
不足:更复杂的界面,暂时未测试。
想法:代码布局是必要的,如果总结代码布局为模版和库,利用泛型和反射的,在界面的复用和自动化上,将比XML更方便扩展。
相关文章推荐
- android动态布局:用java代码实现LinearLayout以及TextView
- android代码中动态设置布局中控件的属性
- android—代码动态布局笔记
- Android 动态布局 (代码布局)
- Android基础:代码中实现界面动态布局
- Android 利用layoutParams代码动态布局空间位置
- android在java代码中动态添加组件及相关布局方法(LayoutParams)
- 在android中利用多线程实现对控件的更新(动态修改文本框中的值)。简述原理并上传代码。
- android,利用layoutParams代码动态布局空间位置
- 【译】用Fragment创建动态的界面布局(附Android示例代码)
- Anko:Android 代码动态布局的新方案
- Android中不使用布局文件,java代码动态创建布局及控件
- android代码中动态设置布局中控件的属性
- 【转】用Fragment创建动态的界面布局(附Android示例代码) - 小吉吉
- Android 代码动态加载布局
- android:代码中动态添加子布局
- Android 中使用代码动态网格布局
- 在android中利用多线程实现对控件的更新(动态修改文本框中的值)。简述原理并上传代码。 .
- 在Android代码中实现动态布局
- Android 动态布局 (代码布局)