編輯:關於Android編程
我們經常會看到很多優秀的app上面都有一些很漂亮的控件,用戶體驗非常好,比如togglebutton就是一個很好的例子,IOS系統下面那個精致的togglebutton如今在android下面也可以實現了,而且還可以自定義它的顏色文字背景圖,做出各種漂亮的開關按鍵出來。這裡就用到了android裡面一個比較常用的技術——自定義控件。
先來看下我們實現的自定義的togglebutton效果圖:

自定義控件的步驟:
1、首先,定義一個類繼承View 或者View的子類,這個取決於要定義的控件的類型,本例中,繼承自View。
2、繼承了View後 就需要重寫構造函數,有三個方法,分別是
public MyView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// TODO Auto-generated constructor stub
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
這三個方法,根據不同的情況來使用,如果自定義的控件需要設置xml屬性那麼就要用到第三個構造函數,如果需要設置xml屬性並且定義樣式,那麼就需要實現第二個構造函數,使用其第三個參數defStyleAttr,如果沒有以上兩點要求,那麼直接重寫第一個構造函數即可。
這這個demo中,我們實現第一個構造函數即可
public ToggleButton(Context context, AttributeSet attrs) {
super(context, attrs);
initBitmap();//初始化bitmap
}
重寫構造函數後,接下來就要根據不同控件的要求來選擇是否重寫onDraw和onMeasure方法了。
如果自定義控件的大小是需要自定義的,比如本例中的togglebutton,那麼首先需要重寫onMeasure方法,測算出自定義控件的寬和高。
很明顯,我們這個togglebutton的寬和高是很容易得出來的,高度就是這個控件背景圖的寬和高

所以onMeasure方法重寫如下,得到自定義控件的寬和高
/**
* 初始化開關圖片
*/
private void initBitmap() {
background = BitmapFactory.decodeResource(getResources(),
R.drawable.switch_background);
slideBackground = BitmapFactory.decodeResource(getResources(),
R.drawable.slide_button_background);
}
/**
* 設置當前控件的寬和高
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// 設置開關的寬和高
setMeasuredDimension(background.getWidth(), background.getHeight());
}
重寫onDraw方法,我們可以得到一個參數canvas
void onDraw(Canvas canvas)有了這個canvas對象,就可以很方面的繪制出控件的樣子
先繪制控件的背景,因為togglebutton,其實就是一個button在一個背景圖上面來回滑動產生不同的效果,所以我們先繪制它的背景。
canvas.drawBitmap(background, 0, 0, null);繪制完背景後,就要繪制小滑塊了。小滑塊有兩種狀態,一種是在滑動,另一種是靜止狀態,這兩種狀態我們需要分別進行處理。
當小滑塊在滑動的時候,背景圖是不會變的,而且它滑動到某個時刻的樣子也很明確,滑動了多少距離就繪制它在某距離的狀態,但是有一種情況需要進行處理,那就是滑塊滑出邊界的情況,如果是從左邊滑出邊界,那麼就應該將它離左邊的距離置為0,也就是不讓它繼續滑動,同理右邊也要進行相應的處理。
滑動過程代碼如下:
if(isSliding) { // 正在滑動中
int left = currentX - slideBackground.getWidth() / 2;
if(left < 0) { // 當前超出了左邊界, 賦值為0
left = 0;
} else if(left > (background.getWidth() - slideBackground.getWidth())) {
// 當前超出了右邊界, 賦值為: 背景的寬度 - 滑動塊的寬度
left = background.getWidth() - slideBackground.getWidth();
}
canvas.drawBitmap(slideBackground, left, 0, null);
}
靜止狀態的話,很容易,根據不同的狀態將滑塊放置到控件的左邊和右邊即可
if(currentState) {
// 繪制開的狀態
canvas.drawBitmap(slideBackground, 0, 0, null);
} else {
// 繪制關的狀態
int left = background.getWidth() - slideBackground.getWidth();
canvas.drawBitmap(slideBackground, left, 0, null);
}
滑動事件的處理,捕獲用戶的操作,為它設置一個自定義的狀態改變監聽器
/**
* 捕獲用戶操作的事件
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
currentX = (int) event.getX();
isSliding = true;
break;
case MotionEvent.ACTION_MOVE:
currentX = (int) event.getX();
break;
case MotionEvent.ACTION_UP:
isSliding = false;
currentX = (int) event.getX();
int center = background.getWidth() / 2;
// 當前最新的狀態
boolean state = currentX < center;
// 如果兩個狀態不一樣並且監聽事件不為null
if (currentState != state && mOnToggleStateChangeListener != null) {
// 調用用戶的回調事件
mOnToggleStateChangeListener.onToggleStateChange(state);
}
currentState = state;
break;
default:
break;
}
invalidate(); // 此方法被調用會使onDraw方法重繪
return true;
}
這裡自定義了一個狀態改變監聽器,用來監聽togglebutton的狀態改變,然後回調方法,進行相應的處理。
public interface OnToggleStateChangeListener {
void onToggleStateChange(boolean state);
}
最後,為這個控件提供三個方法,設置狀態為開或關的方法,還有一個設置監聽事件的方法
/**
* 設置開關的狀態
*
* @param state
*/
public void setToggleState(boolean state) {
currentState = state;
}
public boolean getToogleState() {
return currentState;
}
public void setOnToggleStateChangeListener(
OnToggleStateChangeListener listener) {
mOnToggleStateChangeListener = listener;
}
到這裡,整個自定義togglebutton的過程就算完了。接下來我們就可以在程序中使用自己定義的控件了。
在xml文件中,用全路徑名使用自定義控件,然後在java代碼中就可以獲取到這個自定義控件的對象 和相關的方法了
總結一下其實就是幾個步驟:
1、繼承View或者它的子類,根據不同的情況重寫不同的構造函數(必須)
2、重寫onMeasure方法,測量控件的大小(非必須)
3、重寫onDraw方法,繪制控件(非必須)
4、為控件設置一些自定義方法和監聽器(非必須)
5、在xml中使用,或者直接在java代碼中使用
如何搭配最新的安卓開發環境
本章只是寫了如何配置JDK,以及adt-bundle的配置。對於以前的adt-bundle的版本,會自帶CPU/ABI系統鏡像,經過本文所描述的兩個步驟後可以直接創建AV
一個簡單但又讓人容易忽略的BUG
在我用Android開發一個數獨游戲的時候,需要添加相關的截屏功能(也就是將玩數獨的界面截下來) 代碼如下: try{ Bitmap map = Bitmap.
android沉浸式狀態欄、變色狀態欄、透明狀態欄、修改狀態欄顏色及透明
首先我要區分清楚沉浸式狀態欄與變色狀態欄。沉浸式狀態欄指的是,狀態欄隱藏,在手指做了相關操作後,狀態欄顯示出來,例如視頻播放器,在播放視頻時是隱藏狀態欄的,但是點擊屏幕的
蘑菇ROM助手如何system.img文件進行合並或分割
蘑菇ROM助手可以對system.img文件進行合並或分割,下面就讓我給大家講講如何操作。一、操作前准備1、下載安裝ROM助手2、准備好刷機包二、打開ROM