第一部分:attrs.xml
<!-- 這裏我們要創建自定義view的屬性 -->
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="relation">
<enum name="icon_left" value="0"/>
<enum name="icon_right" value="1"/>
<enum name="icon_above" value="2"/>
<enum name="icon_below" value="3"/>
</attr>
下面這裏講一下skip這個東西,顧名思義是跳過什麼東西,如果在裏面設置了一些內容,在解析xml文件的時候就會跳過一些設置的內容(純粹自己理解,如果有人知道<span style="font-family: Arial, Helvetica, sans-serif;">請告訴下,謝謝!)。是按照.Net中有個System.Xml.Skip()理解的。</span>
<skip />
<!-- 在這裏創建需要的幾種屬性,並且指明屬性需要的幾種值。
其中屬性relation是固定好的四種枚舉值;另外這裏還有一個
注意的點是name="IconText"這個命名空間前綴 -->
<declare-styleable name="IconText">
<attr name="relation"/>
<attr name="icon" format="reference"/>
<attr name="text" format="string"/>
<attr name="text_size" format="dimension"/>
<attr name="text_color" format="integer"/>
<attr name="space" format="dimension"/>
</declare-styleable>
</resources>
第二部分:IconTextView.java
創建好自定義view屬性後,我們就需要去創建自定義view類,並且處理該view類
佈局後的初始化操作。下面這個view包含一個TextView和一個ImageView。
public class IconTextView extends LinearLayout {
private final static String TAG = "IconTextView";
private final int ICON_LEFT = 0;
private final int ICON_RIGHT = 1;
private final int ICON_ABOVE = 2;
private final int ICON_BELOW = 3;
private TextView mTextView;
private ImageView mImageView;
private int mRelation = ICON_LEFT;
private String mText = "";
private int mIconId;
private float mTextSize;
private int mSpace;
//當我們在xml文件中佈局該view的時候,會調用構造函數做初始化。
public IconTextView(Context context, AttributeSet attrs) {
super(context, attrs);
//獲取xml文件中的名字爲IconText的所有屬性
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.IconText);
mRelation = a.getInt(R.styleable.IconText_relation, ICON_LEFT);
Log.d(TAG,"mRelation = " + mRelation);
mText = a.getString(R.styleable.IconText_text);
Log.d(TAG,"mText = " + mText);
mTextSize = a.getDimensionPixelSize(R.styleable.IconText_text_size, 12);
Log.d(TAG, "mTextSize = " + mTextSize);
mSpace = a.getDimensionPixelSize(R.styleable.IconText_space, 5);
Log.d(TAG, "mSpace = " + mSpace);
mIconId = a.getResourceId(R.styleable.IconText_icon, R.drawable.ic_launcher);
Log.d(TAG, "mIconId = " + mIconId);
a.recycle();
//屬性完成後,把這些屬性設置進TextView和ImageView
mTextView = new TextView(context);
mTextView.setText(mText);
mTextView.setTextSize(mTextSize);
mImageView = new ImageView(context);
mImageView.setImageResource(mIconId);
//根據mRelation的值,設置整個view的佈局排列以及ImageView的邊距。
int left = 0, top = 0, right = 0, bottom = 0;
int orientation = HORIZONTAL;
int textViewIndex = 0;
switch (mRelation) {
case ICON_ABOVE:
orientation = VERTICAL;
bottom = mSpace;
textViewIndex = 1;
break;
case ICON_BELOW:
orientation = VERTICAL;
top = mSpace;
break;
case ICON_LEFT:
right = mSpace;
textViewIndex = 1;
break;
case ICON_RIGHT:
left = mSpace;
break;
}
this.setOrientation(orientation);
this.addView(mImageView);//把子ImageView加入自定View
mImageView.setPadding(left, top, right, bottom);
this.addView(mTextView, textViewIndex);//把子TextView加入自定View
}
}
第三部分:activity_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"
tools:context=".MainActivity" >
在佈局中使用自定義的view,然後系統就會調用第二部分的代碼去解析下面的屬性,初始化IconTextView
<com.example.selfviewdemo.IconTextView
android:id="@+id/icontext_01"
xmlns:android="http://schemas.android.com/apk/res/android"
下面這句是自定義View的命名空間,icontext對應attrs.xml中的IconText,然後把android的包名改成自己的包名就好了
xmlns:icontext="http://schemas.android.com/apk/res/com.example.selfviewdemo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
icontext:relation="icon_right"
icontext:text="@string/icon_text"
icontext:text_size="12sp"/>
</RelativeLayout>
第四部分:MainActivity.java
在這裏直接setContentView,你就能看到自定義的view啦!
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}