android自定義滑動启動和關閉按鈕
转自:http://rritw.com/a/bianchengyuyan/C__/20120920/227159.html
在很多時候我們看到在iphone手機應用中都有滑動開启和關閉這個功能,在android40以下的版本中且沒有這個功能,但是android手機在使用的多是4.0以下的系統,所以为了滿足需求,我們自己設計自定的滑動開启和關閉按鈕。
第一步:創建一個打開關閉的狀態接口函數OnChangedListener主要創建一個打開關閉狀態的抽象方法OnChanged(boolean CheckState),本接口主要是用於空間跟activity之間的狀態回調,代碼如下:
第二步:創建SlipButton類繼承View類(基本上android的空間都是繼承這個類的,所以如果我們想自己設計出好看或者有特別用途的空間都可以繼承這個類然後根據需求設計和實現重寫相關方法)實現OnTouchListener接口實現手勢觸控和滑動的控制,本類的實現在代碼中有詳細的描述,代碼如下:
第三步:設計xml文件(控件的使用也可以直接在activity中直接實例化的如:SlipButton mSlipButton=new SlipButton(this)),在xml中使用如下:
第四步:編寫MainActivity實現OnChangedListener接口,以便於監聽打開和關閉時需要處理的事情。代碼如下:
第五步:運行效果如圖:
在很多時候我們看到在iphone手機應用中都有滑動開启和關閉這個功能,在android40以下的版本中且沒有這個功能,但是android手機在使用的多是4.0以下的系統,所以为了滿足需求,我們自己設計自定的滑動開启和關閉按鈕。
第一步:創建一個打開關閉的狀態接口函數OnChangedListener主要創建一個打開關閉狀態的抽象方法OnChanged(boolean CheckState),本接口主要是用於空間跟activity之間的狀態回調,代碼如下:
public interface OnChangedListener { abstract void OnChanged(boolean CheckState); }
第二步:創建SlipButton類繼承View類(基本上android的空間都是繼承這個類的,所以如果我們想自己設計出好看或者有特別用途的空間都可以繼承這個類然後根據需求設計和實現重寫相關方法)實現OnTouchListener接口實現手勢觸控和滑動的控制,本類的實現在代碼中有詳細的描述,代碼如下:
import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Rect; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import com.example.slidebutton.R; public class SlipButton extends View implements OnTouchListener { private boolean NowChoose = false;// 記錄當前按鈕是否打開,true为打,flase为關 private boolean OnSlip = false;// 記錄用戶是否在滑動的變量 private float DownX, NowX;// 按下時的x,當前的x, private Rect Btn_On, Btn_Off;// 打開和關閉狀態下,遊標的Rect private boolean isChgLsnOn = false; private OnChangedListener ChgLsn; private Bitmap bg_on, bg_off, slip_btn; //此構造函數在直接new控件時調用 public SlipButton(Context context) { super(context); // TODO Auto-generated constructor stub init(); } public boolean isChecked(){ return NowChoose; } public void setChecked(boolean check){ NowChoose = check; invalidate(); } //此構造函數在xml中使用控件時調用 public SlipButton(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub init(); } private void init() {// 初始資源 // 載入圖片資源 bg_on = BitmapFactory.decodeResource(getResources(), R.drawable.images_on); bg_off = BitmapFactory.decodeResource(getResources(), R.drawable.images_off); slip_btn = BitmapFactory.decodeResource(getResources(), R.drawable.split_button); // 獲得�?��的Rect數據 Btn_On = new Rect(0, 0, slip_btn.getWidth(), slip_btn.getHeight()); Btn_Off = new Rect(bg_off.getWidth() - slip_btn.getWidth(), 0, bg_off.getWidth(), slip_btn.getHeight()); setOnTouchListener(this);// 設置觸控監聽,也可以直接复寫OnTouchEvent } protected void onDraw(Canvas canvas) {// 繪圖函數 // TODO Auto-generated method stub super.onDraw(canvas); Matrix matrix = new Matrix(); Paint paint = new Paint(); float x; { if ((NowX < (bg_on.getWidth() / 2))&&!NowChoose)// 滑動到前半段與後半段的背景時在此做判是否關閉或打開 { canvas.drawBitmap(bg_off, matrix, paint);// 畫出關閉時的背景 } else{ canvas.drawBitmap(bg_on, matrix, paint);// 畫出打開時的背景 } if (OnSlip)// 是否是在滑動狀 { if (NowX >= bg_on.getWidth())// 是否劃出指定範圍,不能讓遊標跑到繪制控件範圍外?必須做這個判? x = bg_on.getWidth() - slip_btn.getWidth() / 2;// 減去遊標1/2的長度 else x = NowX - slip_btn.getWidth() / 2; } else {// 非滑動狀 if (NowChoose)// 根據現在的開關狀態設置畫遊標的位 x = Btn_Off.left; else x = Btn_On.left; } if (x < 0)// 對遊標位置進行異常判 x = 0; else if (x > bg_on.getWidth() - slip_btn.getWidth()) x = bg_on.getWidth() - slip_btn.getWidth(); canvas.drawBitmap(slip_btn, x, 0, paint);// 畫出遊標. } } public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub switch (event.getAction())// 根據動作來執行代 { case MotionEvent.ACTION_MOVE:// 滑動 NowX = event.getX(); break; case MotionEvent.ACTION_DOWN:// 按下 if (event.getX() > bg_on.getWidth() || event.getY() > bg_on.getHeight()) return false; OnSlip = true; DownX = event.getX(); NowX = DownX; break; case MotionEvent.ACTION_UP:// 松開 OnSlip = false; boolean LastChoose = NowChoose; if (event.getX() >= (bg_on.getWidth() / 2)) NowChoose = true; else NowChoose = false; if (isChgLsnOn && (LastChoose != NowChoose))// 如果設置了監聽器,就調用其方法.. ChgLsn.OnChanged(NowChoose); break; default: } invalidate();// 重畫控件 return true; } public void SetOnChangedListener(OnChangedListener l) {// 設置監聽?當狀態修改的時? isChgLsnOn = true; ChgLsn = l; }
第三步:設計xml文件(控件的使用也可以直接在activity中直接實例化的如:SlipButton mSlipButton=new SlipButton(this)),在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" > <RelativeLayout android:id="@+id/setlayout" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@drawable/ic_preference_one_normal" android:gravity="center" > <TextView android:id="@+id/d_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:gravity="center_vertical" android:paddingBottom="10dip" android:paddingTop="10dip" android:singleLine="true" android:text="免打擾" android:textColor="#000000" /> <!--使用SlipButton的方法這裏必須是類的包名加.類名 --> <com.example.widget.SlipButton android:id="@+id/on" android:layout_width="60dip" android:layout_height="25dip" android:layout_alignParentRight="true" android:layout_marginBottom="8dip" android:layout_marginTop="8dip" /> </RelativeLayout> </RelativeLayout>
第四步:編寫MainActivity實現OnChangedListener接口,以便於監聽打開和關閉時需要處理的事情。代碼如下:
import android.app.Activity; import android.os.Bundle; import android.widget.Toast; import com.example.widget.OnChangedListener; import com.example.widget.SlipButton; public class MainActivity extends Activity implements OnChangedListener { private SlipButton mSlipButton; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mSlipButton = (SlipButton) this.findViewById(R.id.on); mSlipButton.SetOnChangedListener(this);//設置事件監聽 } //這裏为開或者關時自己所需要做的動作或實現的內容處理 public void OnChanged(boolean CheckState) { if (CheckState) { Toast.makeText(this, "打開了", Toast.LENGTH_LONG).show(); } else { Toast.makeText(this, "關閉了", Toast.LENGTH_LONG).show(); } } }
第五步:運行效果如圖: