在现实开发中会经常使用开源库来实现项目需求,这些开源库有些是jar包,有些是作为library工程来使用,两者的区别是library工程使用了res的资源,打包成jar包来使用时,会出现资源找不到的错误,只能以library工程的形式提供使用。
下面通过写一个自己的自定义控件的形式来分别举例这两种方法:
1.jar包形式,新建一个android工程叫CustomViewDemo,包名为com.innskyy.customview, 新建CustomView.java,代码如下
public class CustomView extends View {
private Paint paint;
private Rect bounds;
private String text = "android";
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
bounds = new Rect();
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
paint.setColor(Color.BLACK);
canvas.drawRect(0, 0, 200, 100, paint);
paint.setColor(Color.WHITE);
paint.setTextSize(30);
paint.getTextBounds(text, 0, text.length(), bounds);
canvas.drawText(text, 50, 50, paint);
}
}
编译之后,右键工程Export->JAVA->JAR file,next之后 左边去除勾选res文件夹,右边全部去除勾选,然后选择JAR file的保存路径,finish之后在指定的路径下就会生成JAR包。
在要使用CustomView的工程中,复制jar包到libs文件夹下,在布局文件中使用:
<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:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
<com.innskyy.customview.CustomView
android:id="@+id/custom_view"
android:layout_width="200dp"
android:layout_height="200dp" />
</LinearLayout>
java代码中同样通过findViewById(R.id.custom_view)方法来找到此控件对象。
2. library工程形式,修改CustomViewDemo工程中CustomView.java的代码如下:
public class CustomView extends LinearLayout {
private ImageView imageView;
private TextView textView;
boolean flag = true;
public CustomView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.mybutton, this);
imageView = (ImageView) findViewById(R.id.imageView1);
textView = (TextView) findViewById(R.id.textView1);
textView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (flag) {
textView.setText("取消");
flag = false;
} else {
textView.setText("确定");
flag = true;
}
}
});
}
/**
* 设置图片资源
*/
public void setImageResource(int resId) {
imageView.setImageResource(resId);
}
/**
* 设置显示的文字
*/
public void setTextViewText(String text) {
textView.setText(text);
}
}
mybutton.xml 代码如下
<RelativeLayout 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">
<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:paddingLeft="20dp"
android:src="@drawable/button" />
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="@id/imageView1"
android:layout_marginLeft="10dp"
android:text="确定"
android:textColor="#000000" />
</RelativeLayout>
drawable中button资源随便找一个代替,编译完成后,工程右键Properties->Android右侧 Is Library 前面勾选上,然后Apply, OK 之后,CustomViewDemo就作为一个Library工程存在。
在要使用CustomView的工程中,工程右键Properties->Android右侧 Add 选择CustomViewDemo,然后Apply, OK 之后, 在布局文件如下使用:
<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:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
<com.innskyy.customview.CustomView
android:id="@+id/custom_view"
android:layout_width="200dp"
android:layout_height="200dp" />
</LinearLayout>
同样,java代码中同样通过findViewById(R.id.custom_view)方法来找到此控件对象。
以上为自定义控件作为外接形式使用的两种方式,那此处需要注意的是,当把第二个例子的CustomVIewDemo也使用第一种方式来导出JAR包,那么使用时会出现找不到资源的错误,类似android.content.res.Resources%24NotFoundException,这是由于在CustomView的构造方法中
inflater.inflate(R.layout.mybutton, this);
这一句找不到mybutton对应的R资源,因为mybutton对应的R资源在CustomViewDemo工程中保存,在使用CustomView这个控件的新工程中找不到,所以会报错,总结起来还是文章开头的那句话,引用了资源文件的自定义控件要通过Library工程的方式提供给其他工程使用。