Android开发中的布局界面一般都使用xml来定义,既方便有直观。但是这样做也有弊端。
其中之一是这样的方式比较消耗资源,另一个原因是我们有时候为了满足我们的需求不能使用xml布局。
例如:
我们将在一个工具包中添加一个Dialog。不过看到那个默认的Dialog,不自觉的就想起了芙蓉和凤姐。如果是在自己的项目使用dialog,我们可以使用xml为Dialog开发一个漂亮的布局,然后给她一个漂亮的背景,这都很容易。但是在jar包中就没那么容易了。
jar包中的xml布局是无法被解析到的。一般的jar包我们只需要将src下的.java打包就可以满足需求了,但是上面这个需要添加Dialog的jar包,除了.java外可能还需要一个9patch图片做背景,需要一个布局做界面。关于9patch我们放在最后说,先说这个布局。
解决方案:
还是上面的Dialog的布局,其实用到这个布局的Dialog方法就是setContentView(int resourceId)。这个方法还有一个重载的方法setContentView(Viewview),我们的解决方案正式基于这个方法展开的。
我们可以通过java代码来开发一个view,效果和xml不分上下。以一个具体的例子来说:
我们想要用java代码实现下面的这个布局文件
<?xml version="1.0"encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="500dp" android:layout_height="309dp" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="50dp" android:gravity="center_horizontal" android:text="标题 " android:textColor="#FFFFFF" android:textSize="25dp" /> <ImageView android:layout_width="fill_parent" android:layout_height="3dp" android:layout_marginTop="10dp" android:background="#D3D3D3" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="130dp" android:gravity="center" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#FF0000" android:textSize="30dp"/> </LinearLayout> </LinearLayout>
首先,从外到里分析这个布局:
最外层:父LinearLayout
第二层: TextView ImageView 和 子LinearLayout
子LinearLayout还有一个子布局:TextView
以上就是要用java 代码生成的全部view了,间杂一些设置这些view的属性的方法,就OK了。
具体代码如下:
// 创建父LinearLayout LinearLayout ll_parent = new LinearLayout(context); ll_paren.setLayoutParams(new LinearLayout.LayoutParams(500,309)); ll_paren.setOrientation(LinearLayout.VERTICAL); // 创建标题TextView TextViewtv_title = newTextView(context); LinearLayout.LayoutParamsllp_tv_title = newLinearLayout.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT,50); tv_title.setGravity(Gravity.CENTER); tv_title.setTextColor(Color.WHITE); tv_title.setTextSize(25); tv_title.setText("请刷卡"); // 创建ImageView ImageViewiv_devideLine = newImageView(context); LinearLayout.LayoutParamsim_parames = newLinearLayout.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT,3); im_parames.topMargin = 10; // Color.rgb(r,g,b); 让颜色丰富了。 iv_devideLine.setBackgroundColor(Color.rgb(210,210, 210)); iv_devideLine.setLayoutParams(im_parames); // 创建子LinerLayout LinearLayoutll_child = newLinearLayout(context); LinearLayout.LayoutParamsll_child_parames = new LinearLayout.LayoutParams( 400,200); ll_child_parames.gravity = Gravity.CENTER; // 创建倒计时TextView TextViewtv_child = newTextView(context); LinearLayout.LayoutParamstv_count_parames = new LinearLayout.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT); tv_child _parames.gravity= Gravity.CENTER; tv_child.setLayoutParams(tv_count_parames); tv_child.setGravity(Gravity.CENTER); tv_child.setTextColor(Color.WHITE); tv_child.setTextSize(30); //还能给组件设置id tv_child.setId(0x7732ef); // 组合布局 // 1、倒计时插入子线性布局 ll_child.addView(tv_count, tv_count_parames); // 2、合成总布局 ll_paren.addView(tv_title,llp_tv_title); ll_paren.addView(iv_devideLine,im_parames); ll_paren.addView(ll_child,ll_child_parames); 只要有xml布局文件,就能够弄出一个完全用代码表示的view来。因为归根结底,最后执行的都是java代码。不同的组件和布局可能略微不同,不过相信应该不会有太大区别。 下面,说一句关于9patch。这个图片打包时放在资产目录下,用的时候需要取出来,转成9patch。不废话,看代码。 try { // 从资产目录取出图片 Bitmapbitmap = BitmapFactory.decodeStream(context.getAssets().open( "fengjie_go_away.9.png")); // 处理图片生成系统使用的9patch数据。 byte[] bs =bitmap.getNinePatchChunk(); // 生成一个Drawable的9patch子类对象,然后可以view.setBackgroundDrawable()设置成背景了。 NinePatchDrawable patchy = new NinePatchDrawable(bitmap, bs, new Rect(), null); }catch(IOException e) { e.printStackTrace(); }
还有一个小问题。
有些9patch图片在这里getNinePatchChunk()后返回null。这是因为我们没有对图片做二进制处理。
在sdk/platform-tools这个目录下,有一个aapt工具,在cmd中使用命令cd将工作空间切换到sdk/platform-tools,然后使用命令:“aapt.exe c -v -S 需要处理的项目完整路径 -C 处理完成后保存到的路径 ”
这样,处理完成后项目中的9patch图片就可以放到jar包并正常使用了。