900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > Android自定义组合控件

Android自定义组合控件

时间:2023-05-23 08:48:23

相关推荐

Android自定义组合控件

目标:实现textview和ImageButton组合,可以通过Xml设置自定义控件的属性。

1.控件布局:以Linearlayout为根布局,一个TextView,一个ImageButton。

Xml代码 1<?xmlversion="1.0"encoding="utf-8"?>

2<LinearLayoutxmlns:Android="/apk/res/android"

3android:layout_width="fill_parent"android:layout_height="fill_parent"

4android:gravity="center_vertical">

5<TextViewandroid:layout_height="wrap_content"android:id="@+id/text1"

6android:layout_width="wrap_content"></TextView>

7<ImageButtonandroid:layout_width="wrap_content"

8android:layout_height="wrap_content"android:id="@+id/btn1"></ImageButton>

9</LinearLayout>

2.自定义控件代码,从LinearLayout继承:

Java代码 publicclassImageBtnWithTextextendsLinearLayout{

}

publicImageBtnWithText(Contextcontext){

this(context,null);

}

publicImageBtnWithText(Contextcontext,AttributeSetattrs){

super(context,attrs);

LayoutInflater.from(context).inflate(R.layout.imagebtn_with_text,this,true);

}

}

在构造函数中将Xml中定义的布局解析出来。

3.在主界面布局xml中使用自定义控件:

Xml代码 <com.demo.widget2.ImageBtnWithText

android:id="@+id/widget"

android:layout_width="fill_parent"

android:layout_height="fill_parent"/>

即使用完整的自定义控件类路径:com.demo.widget2.ImageBtnWithText定义一个元素。

运行可以看到控件已经能够被加载到界面上。

4.给按钮设置图片和文本

如果图片是固定不变的,那么直接在控件布局中设置ImageButton的src属性即可。

4.1通过Java代码设置,在控件代码中提供函数接口:

Java代码 publicvoidsetButtonImageResource(intresId){

mBtn.setImageResource(resId);

}

publicvoidsetTextViewText(Stringtext){

mTv.setText(text);

}

然后再在主界面的onCreate()通过函数调用设置即可。

4.2通过Xml设置属性

4.2.1首先定义Xml可以设置的属性集合,在values下创建attrs.xml,文件名可随意,一般都叫attrs.xml

Xml代码 <?xmlversion="1.0"encoding="utf-8"?>

<resources>

<declare-styleablename="ImageBtnWithText">

<attrname="android:text"/>

<attrname="android:src"/>

</declare-styleable>

</resources>

属性集合名字:ImageBtnWithText,自己可根据实际来定义;

集合中包含的属性列表,每行一个属性。

4.2.2修改自定义控件实现代码,以获取xml中定义的属性

Java代码 TypedArraya=context.obtainStyledAttributes(attrs,R.styleable.ImageBtnWithText);

CharSequencetext=a.getText(R.styleable.ImageBtnWithText_android_text);

if(text!=null)mTv.setText(text);

Drawabledrawable=a.getDrawable(R.styleable.ImageBtnWithText_android_src);

if(drawable!=null)mBtn.setImageDrawable(drawable);

a.recycle();

首先通过context.obtainStyledAttributes获得所有属性数组;

然后通过TypedArray类的getXXXX()系列接口获得相应的值。

4.2.3在主界面布局中设置自定义控件的属

android:text="ABC" android:src="@drawable/icon

4.3自定义名称属性:

在4.2中使用的属性名是Android系统命名空间的,都以android开头,比如android:text等。

实际开发中会自定义一些属性名,这些属性名仍然定义在4.2.1提到的attrs.xml中:

4.3.1定义属性名

Xml代码 <attrname="appendText"format="string"/>

和直接使用系统的attr不同的是要增加一个format属性,说明此属性是什么格式的。format可选项可参见注1

4.3.2使用自定义属性

Xml代码 <?xmlversion="1.0"encoding="utf-8"?>

<LinearLayoutxmlns:android="/apk/res/android"

xmlns:myspace="/apk/res/com.demo.customwidget"

android:orientation="vertical"android:layout_width="fill_parent"

android:layout_height="fill_parent">

<com.demo.widget2.ImageBtnWithText

android:text="ABC"android:src="@drawable/icon"android:id="@+id/widget"

android:layout_width="fill_parent"android:layout_gravity="center"

android:layout_height="fill_parent"myspace:appendText="123456">

</com.demo.widget2.ImageBtnWithText>

</LinearLayout>

直接在主布局文件中使用此属性appendText="abc"是不会设置生效的,而是要在主布局xml中定义一个xml命名空间:

xmlns:myspace="/apk/res/com.demo.customwidget"

命名空间的名字可以自己随便定义,此处为myspace,即xmlns:myspace;

后面的地址则有限制,其开始必须为:"/apk/res/",后面则是包名com.demo.customwidget,

此处的包名与AndroidManifest.xml中< manifest>节点的属性package="com.demo.customwidget"一致,不是自定义控件Java代码所在的包,当然简单的程序自定义控件Java代码也一般在此包内。

注1:format可选项

"reference" //引用

"color" //颜色

"boolean" //布尔值

"dimension" //尺寸值

"float" //浮点值

"integer" //整型值

"string" //字符串

"fraction" //百分数,比如200%

枚举值,格式如下:

< attr name="orientation">

< enum name="horizontal" value="0" />

< enum name="vertical" value="1" />

< /attr>

xml中使用时:

android:orientation = "vertical"

标志位,位或运算,格式如下:

< attr name="windowSoftInputMode">

< flag name = "stateUnspecified" value = "0" />

< flag name = "stateUnchanged" value = "1" />

< flag name = "stateHidden" value = "2" />

< flag name = "stateAlwaysHidden" value = "3" />

< flag name = "stateVisible" value = "4" />

< flag name = "stateAlwaysVisible" value = "5" />

< flag name = "adjustUnspecified" value = "0x00" />

< flag name = "adjustResize" value = "0x10" />

< flag name = "adjustPan" value = "0x20" />

< flag name = "adjustNothing" value = "0x30" />

< /attr>

xml中使用时:

android:windowSoftInputMode = "stateUnspecified | stateUnchanged|stateHidden">

另外属性定义时可以指定多种类型值,比如:

< attr name = "background" format = "reference|color" />

xml中使用时:

android:background = "@drawable/图片ID|#00FF00"

最后来个完整实例:

Java代码 importandroid.content.Context;

importandroid.content.res.TypedArray;

importandroid.util.AttributeSet;

importandroid.view.LayoutInflater;

importandroid.view.View;

importandroid.widget.ImageButton;

importandroid.widget.LinearLayout;

importandroid.widget.ProgressBar;

publicclassMeterextendsLinearLayout{

privateintmax=100;

privateintincrAmount=1;

privateintdecrAmount=-1;

privateProgressBarbar=null;

publicMeter(finalContextctxt,AttributeSetattrs){

super(ctxt,attrs);

this.setOrientation(HORIZONTAL);

TypedArraya=ctxt.obtainStyledAttributes(attrs,R.styleable.Meter);

//获取里面属性用"名字_属性"连接起来

max=a.getInt(R.styleable.Meter_max,100);

incrAmount=a.getInt(R.styleable.Meter_incr,1);

decrAmount=-1*a.getInt(R.styleable.Meter_decr,1);

a.recycle();

}

//当View中所有的子控件均被映射成xml后触发

@Override

protectedvoidonFinishInflate(){

super.onFinishInflate();

//((Activity)getContext()).getLayoutInflater().inflate(R.layout.meter,this);

LayoutInflater.from(getContext()).inflate(R.layout.meter,this);

bar=(ProgressBar)findViewById(R.id.bar);

bar.setMax(max);

ImageButtonbtn=(ImageButton)findViewById(R.id.incr);

btn.setOnClickListener(newView.OnClickListener(){

publicvoidonClick(Viewv){

bar.incrementProgressBy(incrAmount);

}

});

btn=(ImageButton)findViewById(R.id.decr);

btn.setOnClickListener(newView.OnClickListener(){

publicvoidonClick(Viewv){

bar.incrementProgressBy(decrAmount);

}

});

//this.addView(view);//不需要add,默认已经add了

}

}

attrs.xml:

Xml代码 <?xmlversion="1.0"encoding="utf-8"?>

<resources>

<declare-styleablename="Meter">

<attrname="max"format="integer"/>

<attrname="incr"format="integer"/>

<attrname="decr"format="integer"/>

</declare-styleable>

</resources>

meter.xml文件:

Xml代码 <?xmlversion="1.0"encoding="utf-8"?>

<LinearLayoutxmlns:android="/apk/res/android"

android:orientation="horizontal"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

>

<ImageButtonandroid:id="@+id/decr"

android:layout_height="wrap_content"

android:layout_width="wrap_content"

android:scaleType="fitCenter"

android:src="@drawable/arrow_down"

/>

<ProgressBarandroid:id="@+id/bar"

style="?android:attr/progressBarStyleHorizontal"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_weight="1"

android:layout_gravity="center_vertical"

/>

<ImageButtonandroid:id="@+id/incr"

android:layout_height="wrap_content"

android:layout_width="wrap_content"

android:scaleType="fitCenter"

android:src="@drawable/arrow_up"

/>

</LinearLayout>

使用:

Java代码 @Override

publicvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

}

main.xml:

Xml代码 <?xmlversion="1.0"encoding="utf-8"?>

<LinearLayoutxmlns:android="/apk/res/android"

xmlns:app="/apk/res/com.ql.app"

android:orientation="horizontal"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

>

<com.ql.app.Meter

android:id="@+id/meter"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

app:max="100"

app:incr="5"

app:decr="5"

/>

</LinearLayout>

Trackback:/blog/1040917

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。