日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android自定义XML属性以及遇到的命名空间的问题

發布時間:2025/4/14 Android 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android自定义XML属性以及遇到的命名空间的问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉載請注明出處:http://www.cnblogs.com/kross/p/3458068.html

?

最近在做一些UI,很蠢很蠢的重復寫了很多代碼,比如一個自定義的UI Tab,由一個ImageView和一個TextView構成,如果不自定義屬性的話,就需要單獨new出幾個Tab,然后分別給它們設置Drawable和Text。如果能使用XML屬性的話,就直接在XML文件中就可以給Tab設置好Drawable和Text。Java中就可以少些幾行代碼。

?

網上看了好多例子,大部分內容都是大同小異,(可能是因為各種轉載的原因吧)。有很多細節都沒有提及到。自己也是琢磨了半天才弄通。

自定義XML屬性,就是可以方便的給自己定義的控件,添加自定義的屬性,能快捷的給控件賦狀態,賦屬性。

關于自定義控件,請參考我的這篇博客:《探究Android中通過繼承ViewGroup自定義控件的原理》http://www.cnblogs.com/kross/p/3378395.html

?

自定義控件需要如下幾步:

1.自定義控件

2.自定義屬性

3.在布局文件中使用自定義控件和自定義屬性

?

自定義控件,就直接寫一個現在主流的Tab控件,上面一個圖片,下面一行Text組成的控件,通過繼承LinearLayout來實現。代碼如下:

/res/layout/tab.xml

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="vertical" ><ImageViewandroid:id="@+id/imageview_tab_icon"android:layout_width="match_parent"android:layout_height="48dp"android:src="@drawable/ic_launcher"/><TextViewandroid:id="@+id/textview_tab_text"android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center"android:text="KKKKKKKK"/> </LinearLayout>

/src/view/MyTab.java  //注意這里的包名是view

package view;import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet; import android.util.Log; import android.view.LayoutInflater; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView;import com.kross.customattr.R;public class MyTab extends LinearLayout {private static final String TAG = "MyTab";private ImageView iv = null;private TextView tv = null;public MyTab(Context context, AttributeSet attrs) {super(context, attrs);LayoutInflater.from(context).inflate(R.layout.tab, this, true);iv = (ImageView)this.findViewById(R.id.imageview_tab_icon);tv = (TextView)this.findViewById(R.id.textview_tab_text);iv.setImageResource(R.drawable.home);tv.setText("aaaaa");} }

OK,這樣自定義控件就完成了,需要注意的是,看好這個MyTab的包名是view。

?

接下來,我們要自定義XML屬性

/res/values目錄下建一個attr.xml文件。里面寫如下代碼:

<?xml version="1.0" encoding="utf-8"?> <resources><declare-styleable name="MyTab"><attr name="tab_icon" format="reference"/><attr name="tab_name" format="reference"/></declare-styleable> </resources>

這里需要注意的是:

declare-styleable的name要和自定義的類名一樣,(剛剛我們建了一個MyTab類,這里也必須是MyTab)

里面的attr name就是屬性的名字了,跟layout_width一樣,format有好幾種不同的值:string , integer , dimension , reference , color , enum.

當format是enum,枚舉類型的時候,里面的要寫成這個樣子:

<attr name="testEnum"> <enum name="fill_parent" value="-1"/> <enum name="wrap_content" value="-2"/> </attr>

自定義屬性完成后,可以看看R.java文件的變化。

?

然后,我們需要給MyTab類中添加一些處理自定義屬性的代碼,代碼更新為如下:

?

package view;import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet; import android.view.LayoutInflater; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView;import com.kross.customattr.R;public class MyTab extends LinearLayout {private static final String TAG = "MyTab";private ImageView iv = null;private TextView tv = null;public MyTab(Context context, AttributeSet attrs) {super(context, attrs);LayoutInflater.from(context).inflate(R.layout.tab, this, true);iv = (ImageView)this.findViewById(R.id.imageview_tab_icon);tv = (TextView)this.findViewById(R.id.textview_tab_text);iv.setImageResource(R.drawable.home);tv.setText("aaaaa");TypedArray attrArray = context.obtainStyledAttributes(attrs, R.styleable.MyTab);int count = attrArray.getIndexCount();for (int i = 0; i < count; i++) {int attrName = attrArray.getIndex(i);switch (attrName) {case R.styleable.MyTab_tab_icon:iv.setImageResource(attrArray.getResourceId(R.styleable.MyTab_tab_icon, R.drawable.ic_launcher));break;case R.styleable.MyTab_tab_name:tv.setText(attrArray.getString(R.styleable.MyTab_tab_name));break;}}attrArray.recycle();} }

?

最后一步,我們就是在布局文件中使用它

看如下代碼:

<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"tools:context=".MainActivity" ><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/hello_world" /><view.MyTabandroid:layout_width="match_parent"android:layout_height="wrap_content"tab_icon="@drawable/ic_launcher"/> </LinearLayout>

這樣寫是不起作用的,網上很多地方都說,要加上命名空間注意LinearLayout里面新增的命名空間

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:kross="http://schemas.android.com/apk/res/view"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity" ><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/hello_world" /><view.MyTabandroid:layout_width="match_parent"android:layout_height="wrap_content"kross:tab_icon="@drawable/ic_launcher"/> </LinearLayout>

給LinearLayout加上命名空間,并給tab_icon屬性前也加上命名空間,但eclipse就報錯了:error: No resource identifier found for attribute 'tab_icon' in package 'view'

?

在下研究了半天,終于發現問題所在,這個命名空間必須要和manifest文件中的package屬性是一樣的值,這也就意味著:自定義控件的類必須要放到項目自動創建的包里面,比如我這個例子,manifest文件中package的值是com.kross.customattr,MainActivity所在的位置就是com.kross.customattr,我們需要把MyTab類,放到com.kross.customattr中,然后吧activity_main.xml里面的命名空間改成如下就OK了:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:kross="http://schemas.android.com/apk/res/com.kross.customattr"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity" ><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/hello_world" /><com.kross.customattr.MyTabandroid:layout_width="match_parent"android:layout_height="wrap_content"kross:tab_icon="@drawable/ic_launcher"/> </LinearLayout>

?

這樣就可以運行了,但把自定義控件放到activity一起會覺得很蛋疼,貌似這是一個bug,請參考這里http://code.google.com/p/android/issues/detail?id=9656。

貌似2010年就提出了,但現在也沒有修復。

?

轉載請注明出處:http://www.cnblogs.com/kross/p/3458068.html

轉載于:https://www.cnblogs.com/kross/p/3458068.html

總結

以上是生活随笔為你收集整理的Android自定义XML属性以及遇到的命名空间的问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。