文档章节

android 如何打包自定义控件

江湖三弟
 江湖三弟
发布于 2014/01/14 18:32
字数 991
阅读 5122
收藏 49

    设计自定义的控件对android开发人员来说,是家常便饭了,但是多次做项目的经验证明了一个道理,自定义的控件,可以在其他项目中,多次使用,所以接下来我们来介绍2种常用的打包方式,并讨论他们的利于病。

我们可以假设想要自定义一个改变文字显示的button(纯属假设,这样简单的功能其实也用不着自定义)

首先写好布局文件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="100dp"
        android:layout_height="100dp"
        android:paddingBottom="5dip"
        android:paddingLeft="40dip"
        android:layout_centerVertical="true"
        android:paddingTop="5dip"
        android:src="@drawable/button" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="8dip"
        android:layout_centerVertical="true"
        android:text="确定"
        android:layout_toRightOf="@id/imageView1"
        android:textColor="#000000" />

</RelativeLayout>



再完成控制类MyProgressBar.java


package com.swastika.mywidget;

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MyProgressBar extends LinearLayout {

	private ImageView imageView;
	private TextView  textView;
	boolean flag = true;
	
	public MyProgressBar(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
	}
	public MyProgressBar(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);  
    }  

    
}



这样只要引入控件com.swastika.mywidget.MyProgressBar,便可以实现功能了。下面就要介绍打包方式了。


方式一:将项目打包成jar包

    1右击项目,选择export,选择java中的jar如图

                                     图 01

      勾选出自定义控件相关文件,如图02

                                     图02

选好后选择finish就完成了导出,

在使用的时候,将要jar包放到新的项目中的libs文件中(一般会自动引入,如果没有自动引入可以右击该包然后选择Build path,再选择add to build path就可以了),

                 图 03

在新项目布局文件中加入自定义控件;

布局文件main.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"
    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.swastika.mywidget.MyProgressBar 
        android:id="@+id/imgBtn0"  
        android:layout_width="wrap_content"   
        android:layout_height="wrap_content"  
        />

</RelativeLayout>



不过运行的时候会发生错误java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.androidtest/com.example.androidtest.MainActivity}: android.view.InflateException: Binary XML file line #16: Error inflating class com.swastika.mywidget.MyProgressBar,


原因是jar打包后放在drawable中的图片资源无法找到了,,,解决的方式就是将图片等资源文件放在assets文件夹中,再在java代码中映射出来找到资源,这就增加的工作负担,所以通常在使用自定义控件的时候不用这种方式,而是采用下面将要介绍的第二种方式,

优势:jar打包方式,可以用在不使用图片资源的项目中,封装算法等特别方便,便于其他人使用,

劣势:失去了索引,无法使用drawable中的图片资源,封装后的代码修改起来麻烦


方式二:项目作为一个library

    在设计自定义控件的时候,在新建时可以选择将项目作为library(如图04),也可以之后进行设置

                                            图 04

右击项目。选择android,再勾选出Is Library即可(如图05);

                                          图 05

这样便可以使用drawable中的图片资源了,不过需要特别注意的是,自定义控件中的图片名称与新项目中的图片资源不能重名,需要自己检查一下(自定义控件中的默认图标ic_launcher.png需要删除掉,不然会报错,经试验xml文件可以重名)

优势:可以使用drawable中的图片资源了,现在google官网上介绍的就是这种方式,简单方便。


© 著作权归作者所有

江湖三弟
粉丝 32
博文 70
码字总数 31259
作品 0
苏州
高级程序员
私信 提问
加载中

评论(3)

cuiran
cuiran
写的挺好,收藏着。
hellokitty_honey
hellokitty_honey
不错,学习了,
jimney
jimney
学习
android 打包自己的自定义组件成JAR包

在项目开发过程中,我们难免会用到自己去制作自定义的VIEW控件,之后我们别的项目如果需要的话就直接将其复制到对应的项目中使用,虽说这么做是一个解决问题的方法,但毕竟不是很好。 原因是...

刘遇安
2013/04/19
285
3
Android 自定义组合控件小结

引言 接触Android UI开发的这段时间以来,对自定义组合控件有了一定的了解,为此小结一下,本文小结内容主要讨论的是如何使用Android SDK提供的布局和控件组成一个功能完整组合控件并将其封装...

程序袁_绪龙
2014/09/24
316
0
如何自定义LinearLayout

最近通过看别人代码和网上搜索,发现现在自定义LinearLayout的方式有两种。第一种是在扩展的LinearLayout构造函数中使用Inflater加载一个布局,并从中提取出相关的UI组件进行封装,形成一个独...

Kingguary
2012/06/25
5.1K
0
Android RadioButton实现Tab问题

我是一名Java程序猿,最近想学习Android应用开发,于是下载了OSC的Android版本客户端源码。然后参照客户端的功能,自己动手实践。先参照实现了用RadioButton实现的底部Tab栏,以及头部自定义...

熊猫大侠到此一游
2013/05/22
2.8K
1
android--------自定义控件 之 基本实现篇

前面简单的讲述了Android中自定义控件中的几个方法,今天通过代码来实现一个简单的案例 自定义一个扇形图 自定义控件示例: 这里先介绍继承View的方式为例 在布局中如何使用 我用了两种模式,...

切切歆语
2018/05/02
47
0

没有更多内容

加载失败,请刷新页面

加载更多

Eureka应用注册与集群数据同步源码解析

在之前的EurekaClient自动装配及启动流程解析一文中我们提到过,在构造DiscoveryClient类时,会把自身注册到服务端,本文就来分析一下这个注册流程 客户端发起注册 boolean register() t...

Java学习录
11分钟前
1
0
Java描述设计模式(15):责任链模式

本文源码:GitHub·点这里 || GitEE·点这里 一、生活场景描述 1、请假审批流程 公司常见的请假审批流程:请假天数 当 day<=3 天,项目经理审批当 3<day<=5 天,部门经理审批当 day>5 天...

知了一笑
22分钟前
3
0
总结:数组与链表

1、内存申请:数组在内存上是连续的空间;链表,内存地址上可以是不连续的。 2、查询速度:数组可以随机访问,链表必须顺序访问,即从首个元素开始遍历,逐个查找,所以数组查询很快。 3、写入...

浮躁的码农
30分钟前
3
0
HashMap源码分析

read

V丶zxw
48分钟前
5
0
Python字符串或JSON字符串转字典dict、列表list

有3种方法 1、使用ast模块 >>> import ast>>> s = '["test",1]'>>> ast.literal_eval(s)['test',1]>>> s = '{"test":1}'>>> ast.literal_eval(s){'test': 1} 2、eval函数,这个......

编程老陆
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部