編輯:關於Android編程
由於Android並未提供滑動開關之類的組件,所以我們需要自己去實現一個自定義的視圖組件來實現滑動開關效果。
這裡有一個示例代碼,它包括三個類:開關組件視圖、狀態監聽接口、MainActivity
我們先來看看整個demo的效果圖:
我們先來看看視圖組件的完整代碼,代碼都已經注釋:
package com.bear.swtichbuttondemo; import java.util.ArrayList; 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; /** * 自定義滑動開關 */ public class MySwitchButton extends View implements OnTouchListener { private Bitmap switchOnBkg; // 開關開啟時的背景 private Bitmap switchOffBkg; // 開關關閉時的背景 private Bitmap slipSwitchButton; // 滑動開關的圖片 private boolean isSlipping = false; // 是否正在滑動 private boolean isSwitchOn = false; // 當前開關的狀態,true表示開啟,flase表示關閉 private float previousX; // 手指按下時的水平坐標x private float currentX; // 當前的水平坐標X private ArrayListonSwitchListenerList; // 開關監聽器列表 public MySwitchButton(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { this.setOnTouchListener(this); // 設置觸摸監聽器 onSwitchListenerList = new ArrayList (); } public void setImageResource(int switchBkg, int slipBtn) { switchOnBkg = BitmapFactory.decodeResource(this.getResources(), switchBkg); switchOffBkg = BitmapFactory.decodeResource(this.getResources(), switchBkg); slipSwitchButton = BitmapFactory.decodeResource(this.getResources(), slipBtn); } public void setSwitchState(boolean switchState) { this.isSwitchOn = switchState; this.invalidate(); } public boolean getSwitchState() { return this.isSwitchOn; } public void setOnSwitchStateListener(OnSwitchListener listener){ onSwitchListenerList.add(listener); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Matrix matrix = new Matrix(); Paint paint = new Paint(); float leftSlipBtnX; // 滑動按鈕的左邊坐標 //畫開關的背景圖片 canvas.drawBitmap(switchOnBkg, matrix, paint); if (isSlipping) { // 如果正在滑動 if (currentX > switchOnBkg.getWidth()) { leftSlipBtnX = switchOnBkg.getWidth() - slipSwitchButton.getWidth(); } else { leftSlipBtnX = currentX - slipSwitchButton.getWidth(); } } else { //如果沒有滑動 if (isSwitchOn) { leftSlipBtnX = switchOnBkg.getWidth() - slipSwitchButton.getWidth(); } else { leftSlipBtnX = 0; } } //如果手指滑出了開關的范圍,應當這樣處理 if (leftSlipBtnX < 0) { leftSlipBtnX = 0; } else if (leftSlipBtnX > switchOnBkg.getWidth() - slipSwitchButton.getWidth()) { leftSlipBtnX = switchOnBkg.getWidth() - slipSwitchButton.getWidth(); } //在畫布上畫開關圖片 canvas.drawBitmap(slipSwitchButton, leftSlipBtnX, 0, paint); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); setMeasuredDimension(switchOnBkg.getWidth(), switchOnBkg.getHeight()); } @Override public boolean onTouch(View v, MotionEvent event) { //獲取觸摸動作類型 int action = event.getAction(); switch (action) { case MotionEvent.ACTION_MOVE: //如果現在處於手指一動狀態 currentX = event.getX(); break; case MotionEvent.ACTION_DOWN: //如果現在手指剛剛按上屏幕狀態 isSlipping = true; break; case MotionEvent.ACTION_UP: //如果現在手指剛剛離開屏幕狀態 isSlipping = false; boolean previousState = isSwitchOn; if (event.getX() > (switchOnBkg.getWidth() / 2)) { isSwitchOn = true; } else { isSwitchOn = false; } //調用接口回調方法,將開關狀態通知給監聽對象 if(previousState != isSwitchOn){ if(onSwitchListenerList.size() > 0){ for(OnSwitchListener listener : onSwitchListenerList){ listener.onSwitched(isSwitchOn); } } } break; default: break; } this.invalidate(); return true; } }
package com.bear.swtichbuttondemo; public interface OnSwitchListener { public abstract void onSwitched(boolean isSwitchOn); }
package com.bear.swtichbuttondemo; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; public class MainActivity extends Activity { private MySwitchButton mySwitchButton; private Button myBtn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); setupViews(); } private void setupViews() { mySwitchButton = (MySwitchButton) findViewById(R.id.my_switch_button); //傳圖片給自定義組件 mySwitchButton.setImageResource(R.drawable.switch_bkg_switch, R.drawable.switch_btn_slip); myBtn = (Button) findViewById(R.id.button); //設置開關狀態監聽 mySwitchButton.setOnSwitchStateListener(new OnSwitchListener() { @Override public void onSwitched(boolean isSwitchOn) { if (isSwitchOn) { Toast.makeText(MainActivity.this, 開關開啟, Toast.LENGTH_SHORT).show(); } else { Toast.makeText(MainActivity.this, 開關關閉, Toast.LENGTH_SHORT).show(); } } }); myBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { boolean isOn = mySwitchButton.getSwitchState(); mySwitchButton.setSwitchState(!isOn); } }); } }
機型適配的作用在於使Android應用程序適用於不同的國家語言、型號、尺寸和SDK版本等手機環境中,其主要功能和界面風格保持不變。手機適配主要包括三個方面:語言適配、屏幕
備注:Scale應該比Translate先添加到Set裡面 Interpolator 時間插值類,定義動畫變換的速度。能夠實現alpha/scale/trans
如果我們在文件浏覽器中點擊一個文件,然後點擊它,會彈出一個列表給你選擇 如果使自己的應用也出現在這個列表上,必須在menifest的這個act
引子作為程序員,借鑒可能是工作中所必須碰到的事情,程序員的世界裡,更多的不是從無到有,而是從有到優。那麼當我們在做一些需求或者架構調整時,可能需要參考別的成熟公司的做法,