目標(biāo):實(shí)現(xiàn)textview和ImageButton組合,可以通過Xml設(shè)置自定義控件的屬性。
1.控件布局:以Linearlayout為根布局,一個(gè)TextView,一個(gè)ImageButton。
2.自定義控件代碼,從LinearLayout繼承:
在構(gòu)造函數(shù)中將Xml中定義的布局解析出來。
3.在主界面布局xml中使用自定義控件:
即使用完整的自定義控件類路徑:com.demo.widget2.ImageBtnWithText定義一個(gè)元素。
運(yùn)行可以看到控件已經(jīng)能夠被加載到界面上。
4.給按鈕設(shè)置圖片和文本
如果圖片是固定不變的,那么直接在控件布局中設(shè)置ImageButton的src屬性即可。
4.1通過Java代碼設(shè)置,在控件代碼中提供函數(shù)接口:
然后再在主界面的onCreate()通過函數(shù)調(diào)用設(shè)置即可。
4.2通過Xml設(shè)置屬性
4.2.1首先定義Xml可以設(shè)置的屬性集合,在values下創(chuàng)建attrs.xml,文件名可隨意,一般都叫attrs.xml
屬性集合名字:ImageBtnWithText,自己可根據(jù)實(shí)際來定義;
集合中包含的屬性列表,每行一個(gè)屬性。
4.2.2修改自定義控件實(shí)現(xiàn)代碼,以獲取xml中定義的屬性
首先通過context.obtainStyledAttributes獲得所有屬性數(shù)組;
然后通過TypedArray類的getXXXX()系列接口獲得相應(yīng)的值。
4.2.3在主界面布局中設(shè)置自定義控件的屬
android:text="ABC" android:src="@drawable/icon
4.3自定義名稱屬性:
在4.2中使用的屬性名是Android系統(tǒng)命名空間的,都以android開頭,比如android:text等。
實(shí)際開發(fā)中會(huì)自定義一些屬性名,這些屬性名仍然定義在4.2.1提到的attrs.xml中:
4.3.1定義屬性名
和直接使用系統(tǒng)的attr不同的是要增加一個(gè)format屬性,說明此屬性是什么格式的。format可選項(xiàng)可參見注1
4.3.2使用自定義屬性
直接在主布局文件中使用此屬性appendText="abc"是不會(huì)設(shè)置生效的,而是要在主布局xml中定義一個(gè)xml命名空間:
xmlns:myspace="http://schemas.android.com/apk/res/com.demo.customwidget"
命名空間的名字可以自己隨便定義,此處為myspace,即xmlns:myspace;
后面的地址則有限制,其開始必須為:"http://schemas.android.com/apk/res/",后面則是包名com.demo.customwidget,
此處的包名與AndroidManifest.xml中< manifest>節(jié)點(diǎn)的屬性package="com.demo.customwidget"一致,不是自定義控件Java代碼所在的包,當(dāng)然簡(jiǎn)單的程序自定義控件Java代碼也一般在此包內(nèi)。
注1:format可選項(xiàng)
"reference" //引用
"color" //顏色
"boolean" //布爾值
"dimension" //尺寸值
"float" //浮點(diǎn)值
"integer" //整型值
"string" //字符串
"fraction" //百分?jǐn)?shù),比如200%
枚舉值,格式如下:
< attr name="orientation">
< enum name="horizontal" value="0" />
< enum name="vertical" value="1" />
< /attr>
xml中使用時(shí):
android:orientation = "vertical"
標(biāo)志位,位或運(yùn)算,格式如下:
< 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中使用時(shí):
android:windowSoftInputMode = "stateUnspecified | stateUnchanged | stateHidden">
另外屬性定義時(shí)可以指定多種類型值,比如:
< attr name = "background" format = "reference|color" />
xml中使用時(shí):
android:background = "@drawable/圖片ID|#00FF00"
最后來個(gè)完整實(shí)例:
attrs.xml:
meter.xml文件:
使用:
main.xml:
1.控件布局:以Linearlayout為根布局,一個(gè)TextView,一個(gè)ImageButton。
< ?xml version="1.0" encoding="utf-8"?>
< LinearLayout xmlns:Android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:gravity="center_vertical">
< TextView android:layout_height="wrap_content" android:id="@+id/text1"
android:layout_width="wrap_content">< /TextView>
< ImageButton android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/btn1">< /ImageButton>
< /LinearLayout>
2.自定義控件代碼,從LinearLayout繼承:
public class ImageBtnWithText extends LinearLayout {
}
public ImageBtnWithText(Context context) {
this(context, null);
}
public ImageBtnWithText(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater.from(context).inflate(R.layout.imagebtn_with_text, this, true);
}
}
在構(gòu)造函數(shù)中將Xml中定義的布局解析出來。
3.在主界面布局xml中使用自定義控件:
< com.demo.widget2.ImageBtnWithText
android:id="@+id/widget"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
即使用完整的自定義控件類路徑:com.demo.widget2.ImageBtnWithText定義一個(gè)元素。
運(yùn)行可以看到控件已經(jīng)能夠被加載到界面上。
4.給按鈕設(shè)置圖片和文本
如果圖片是固定不變的,那么直接在控件布局中設(shè)置ImageButton的src屬性即可。
4.1通過Java代碼設(shè)置,在控件代碼中提供函數(shù)接口:
public void setButtonImageResource(int resId) {
mBtn.setImageResource(resId);
}
public void setTextViewText(String text) {
mTv.setText(text);
}
然后再在主界面的onCreate()通過函數(shù)調(diào)用設(shè)置即可。
4.2通過Xml設(shè)置屬性
4.2.1首先定義Xml可以設(shè)置的屬性集合,在values下創(chuàng)建attrs.xml,文件名可隨意,一般都叫attrs.xml
< ?xml version="1.0" encoding="utf-8"?>
< resources>
< declare-styleable name="ImageBtnWithText">
< attr name="android:text"/>
< attr name="android:src"/>
< /declare-styleable>
< /resources>
屬性集合名字:ImageBtnWithText,自己可根據(jù)實(shí)際來定義;
集合中包含的屬性列表,每行一個(gè)屬性。
4.2.2修改自定義控件實(shí)現(xiàn)代碼,以獲取xml中定義的屬性
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ImageBtnWithText);
CharSequence text = a.getText(R.styleable.ImageBtnWithText_android_text);
if(text != null) mTv.setText(text);
Drawable drawable = a.getDrawable(R.styleable.ImageBtnWithText_android_src);
if(drawable != null) mBtn.setImageDrawable(drawable);
a.recycle()
首先通過context.obtainStyledAttributes獲得所有屬性數(shù)組;
然后通過TypedArray類的getXXXX()系列接口獲得相應(yīng)的值。
4.2.3在主界面布局中設(shè)置自定義控件的屬
android:text="ABC" android:src="@drawable/icon
4.3自定義名稱屬性:
在4.2中使用的屬性名是Android系統(tǒng)命名空間的,都以android開頭,比如android:text等。
實(shí)際開發(fā)中會(huì)自定義一些屬性名,這些屬性名仍然定義在4.2.1提到的attrs.xml中:
4.3.1定義屬性名
< attr name="appendText" format="string"/>
和直接使用系統(tǒng)的attr不同的是要增加一個(gè)format屬性,說明此屬性是什么格式的。format可選項(xiàng)可參見注1
4.3.2使用自定義屬性
< ?xml version="1.0" encoding="utf-8"?>
< LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:myspace="http://schemas.android.com/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"是不會(huì)設(shè)置生效的,而是要在主布局xml中定義一個(gè)xml命名空間:
xmlns:myspace="http://schemas.android.com/apk/res/com.demo.customwidget"
命名空間的名字可以自己隨便定義,此處為myspace,即xmlns:myspace;
后面的地址則有限制,其開始必須為:"http://schemas.android.com/apk/res/",后面則是包名com.demo.customwidget,
此處的包名與AndroidManifest.xml中< manifest>節(jié)點(diǎn)的屬性package="com.demo.customwidget"一致,不是自定義控件Java代碼所在的包,當(dāng)然簡(jiǎn)單的程序自定義控件Java代碼也一般在此包內(nèi)。
注1:format可選項(xiàng)
"reference" //引用
"color" //顏色
"boolean" //布爾值
"dimension" //尺寸值
"float" //浮點(diǎn)值
"integer" //整型值
"string" //字符串
"fraction" //百分?jǐn)?shù),比如200%
枚舉值,格式如下:
< attr name="orientation">
< enum name="horizontal" value="0" />
< enum name="vertical" value="1" />
< /attr>
xml中使用時(shí):
android:orientation = "vertical"
標(biāo)志位,位或運(yùn)算,格式如下:
< 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中使用時(shí):
android:windowSoftInputMode = "stateUnspecified | stateUnchanged | stateHidden">
另外屬性定義時(shí)可以指定多種類型值,比如:
< attr name = "background" format = "reference|color" />
xml中使用時(shí):
android:background = "@drawable/圖片ID|#00FF00"
最后來個(gè)完整實(shí)例:
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
public class Meter extends LinearLayout {
private int max=100;
private int incrAmount=1;
private int decrAmount=-1;
private ProgressBar bar=null;
public Meter(final Context ctxt, AttributeSet attrs) {
super(ctxt, attrs);
this.setOrientation(HORIZONTAL);
TypedArray a=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();
}
//當(dāng)View中所有的子控件 均被映射成xml后觸發(fā)
@Override
protected void onFinishInflate() {
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);
ImageButton btn=(ImageButton)findViewById(R.id.incr);
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
bar.incrementProgressBy(incrAmount);
}
});
btn=(ImageButton)findViewById(R.id.decr);
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
bar.incrementProgressBy(decrAmount);
}
});
// this.addView(view);//不需要add,默認(rèn)已經(jīng)add了
}
}
attrs.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="Meter">
<attr name="max" format="integer" />
<attr name="incr" format="integer" />
<attr name="decr" format="integer" />
</declare-styleable>
</resources>
meter.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<ImageButton android:id="@+id/decr"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:scaleType="fitCenter"
android:src="@drawable/arrow_down"
/>
<ProgressBar android: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"
/>
<ImageButton android:id="@+id/incr"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:scaleType="fitCenter"
android:src="@drawable/arrow_up"
/>
</LinearLayout>
使用:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/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>
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元

