標籤:android style blog http color 使用 io for 檔案
一、
二、主要技術點
1.自訂View
2.自訂屬性
三、自訂控制項的步驟
1.自訂類繼承自View或View的子類;
2.重寫構造方法
(1)MyView(Context); // 在代碼中new 對象時調用此方法
(2)MyView(Context,AttributeSet); // 在XML布局檔案中聲明此View,建立對象時,由系統自動調用
(3)MyView(Context,AttributeSet,int); // 與方法2用法一樣,只是多了一個參數:預設樣式
3.重寫相關方法,實現我們的需求,一般要重寫的方法:
(1)onMeasure(int,int); // 系統測量控制項大小時調用該方法
(2)onLayout(boolean,int,int,int,int); // 系統為該view 指定位置時調用此方法,子view的位置,自身只有建議權,決定權在父view的手中。一般不需要重寫。
(3)onDraw(Canvas); // 為本view繪製內容時,調用該方法。
四、為新控制項添加自訂屬性的步驟:
1.在attrs.xml檔案中聲明屬性,有屬性名稱(name)和格式(format)。如
<?xml version="1.0" encoding="utf-8"?><resources> <!-- 聲明屬性集的名稱 --> <declare-styleable name="MyToggleBtn"> <!-- 聲名一個屬性 name是my_background 類型為 參考型別 引用資源ID --> <attr name="my_background" format="reference" /> <!-- 聲名一個屬性 name是my_slide_btn 類型為 參考型別 引用資源ID --> <attr name="my_slide_btn" format="reference" /> <!-- 聲名一個屬性 name是curr_state 類型為 boolean 類型 --> <attr name="curr_state" format="boolean" /> </declare-styleable></resources>
2.在布局檔案中使用新屬性,使用之前必須先聲明命名空間,如xmlns:gnnuit="http://schemas.android.com/apk/res/com.gnnuit.togglebutton",其中“http://schemas.android.com/apk/res/”為Android固定的格式,“com.gnnuit.togglebutton”為應用程式的包名,與AndroidManifest.xml聲明的包名一樣。
<com.gnnuit.togglebutton.MyToggleButton android:layout_width="wrap_content" android:layout_height="wrap_content" gnnuit:curr_state="true" gnnuit:my_background="@drawable/switch_background" gnnuit:my_slide_btn="@drawable/slide_button" />
3.在自訂View的構造方法中,通過解析AttributeSet對象,獲得所需要的屬性值。
四。核心代碼
package com.gnnuit.togglebutton;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Paint;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;public class MyToggleButton extends View implements android.view.View.OnClickListener { private Bitmap backgroundBitmap;// 背景圖片 private Bitmap slideButtonBitmap;// 滑動按鈕圖片 private Paint paint; private boolean currentState = false;// 目前狀態 private float left_slide;// 滑動按鈕的左邊界位置 private float startX, lastX;// 記錄滑動按鈕滑動時的開始和結束位置 private boolean isSlide = false;// 記錄是否移動滑動按鈕 private float dist; /** * 在布局檔案中聲明此View,建立時由系統自動調用該構造方法 * * @param context * @param attrs */ public MyToggleButton(Context context, AttributeSet attrs) { super(context, attrs); // 擷取自訂屬性 currentState = attrs.getAttributeBooleanValue("http://schemas.android.com/apk/res/com.gnnuit.togglebutton", "curr_state", false); int backgroundResourceId = attrs.getAttributeResourceValue("http://schemas.android.com/apk/res/com.gnnuit.togglebutton", "my_background", -1); if (backgroundResourceId == -1) { throw new RuntimeException("請設定背景圖片"); } backgroundBitmap = BitmapFactory.decodeResource(getResources(), backgroundResourceId); int slideBtnResourceId = attrs.getAttributeResourceValue("http://schemas.android.com/apk/res/com.gnnuit.togglebutton", "my_slide_btn", -1); if (slideBtnResourceId == -1) { throw new RuntimeException("請設定背景圖片"); } slideButtonBitmap = BitmapFactory.decodeResource(getResources(), slideBtnResourceId); if (currentState) { left_slide = backgroundBitmap.getWidth() - slideButtonBitmap.getWidth(); } initView();// 初始化 } /** * 初始化 */ private void initView() { // 初始化圖片 // backgroundBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.switch_background); // slideButtonBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.slide_button); // 初始化畫筆 paint = new Paint(); paint.setAntiAlias(true);// 設定消除鋸齒 // 設定點擊事件 setOnClickListener(this); } @Override /** * 測量尺寸的回調方法 */ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(backgroundBitmap.getWidth(), backgroundBitmap.getHeight());// 設定控制項的寬和高,單位是像素 } @Override /** * 繪製當前View的內容 */ protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawBitmap(backgroundBitmap, 0, 0, paint); canvas.drawBitmap(slideButtonBitmap, left_slide, 0, paint); } @Override public void onClick(View v) { if (!isSlide) { currentState = !currentState; flushState();// 重新整理介面 } } /** * 重新整理目前狀態 */ private void flushState() { if (currentState) { left_slide = backgroundBitmap.getWidth() - slideButtonBitmap.getWidth(); } else { left_slide = 0; } invalidate(); } @Override public boolean onTouchEvent(MotionEvent event) { super.onTouchEvent(event); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: isSlide = false; startX = lastX = event.getX(); break; case MotionEvent.ACTION_MOVE: lastX = event.getX(); dist = lastX - startX; if (Math.abs(dist) > 5) { isSlide = true; left_slide += dist; flushShow(); startX = event.getX(); } break; case MotionEvent.ACTION_UP: if (isSlide) { if (left_slide > (backgroundBitmap.getWidth() - slideButtonBitmap.getWidth()) / 2) { left_slide = backgroundBitmap.getWidth() - slideButtonBitmap.getWidth(); currentState = true; } else { left_slide = 0; currentState = false; } flushShow(); } break; } return true; } /** * 重新整理當前View */ private void flushShow() { int maxLeftSlide = backgroundBitmap.getWidth() - slideButtonBitmap.getWidth(); // left_slide的範圍為0=<left_slide<=maxLeftSlide if (left_slide > maxLeftSlide) { left_slide = maxLeftSlide; currentState = true; } else if (left_slide < 0) { left_slide = 0; currentState = false; } invalidate(); }}
Android自訂滑動開關按鈕