編輯:關於Android編程
創建對話框構建器對象,類似工廠模式
AlertDialog.Builder builder = new Builder(this);
設置標題和正文
builder.setTitle("警告");
builder.setMessage("若練此功,必先自宮");
設置確定和取消按鈕
builder.setPositiveButton("現在自宮", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, "恭喜你自宮成功,現在程序退出", 0).show();
}
});
builder.setNegativeButton("下次再說", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, "若不自宮,一定不成功", 0).show();
}
});
使用構建器創建出對話框對象
AlertDialog ad = builder.create();
ad.show();
創建對話框對象
AlertDialog.Builder builder = new Builder(this);
builder.setTitle("選擇你的性別");
定義單選選項
final String[] items = new String[]{
"男", "女", "其他"
};
// -1表示默認選擇
builder.setSingleChoiceItems(items, -1, new OnClickListener() {
// which表示點擊的是哪一個選項
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, "您選擇了" + items[which], 0).show();
// 對話框消失
dialog.dismiss();
}
});
builder.show();
定義多選的選項,因為可以多選,所以需要一個boolean數組來記錄哪些選項被選了
AlertDialog.Builder builder = new Builder(this);
builder.setTitle("請選擇你認為最帥的人");
final String[] items = new String[]{
"趙帥哥",
"趙師哥",
"趙老師",
"侃哥"
};
// true表示對應位置的選項被選了
final boolean[] checkedItems = new boolean[]{
true,
false,
false,
false,
};
builder.setMultiChoiceItems(items, checkedItems, new OnMultiChoiceClickListener() {
// 點擊某個選項,如果該選項之前沒被選擇,那麼此時isChecked的值為true
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
checkedItems[which] = isChecked;
}
});
builder.setPositiveButton("確定", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
StringBuffer sb = new StringBuffer();
for(int i = 0;i < items.length; i++){
sb.append(checkedItems[i] ? items[i] + " " : "");
}
Toast.makeText(MainActivity.this, sb.toString(), 0).show();
}
});
builder.show();
獲取屏幕寬高
Display dp = getWindowManager().getDefaultDisplay();
int screenWidth = dp.getWidth();
int screenHeight = dp.getHeight();
獲取圖片寬高
Options opts = new Options();
// 請求圖片屬性但不申請內存
opts.inJustDecodeBounds = true;
BitmapFactory.decodeFile("sdcard/dog.jpg", opts);
int imageWidth = opts.outWidth;
int imageHeight = opts.outHeight;
圖片的寬高除以屏幕寬高,算出寬和高的縮放比例,取較大值作為圖片的縮放比例
int scale = 1;
int scaleX = imageWidth / screenWidth;
int scaleY = imageHeight / screenHeight;
if(scaleX >= scaleY && scaleX > 1){
scale = scaleX;
}
else if(scaleY > scaleX && scaleY > 1){
scale = scaleY;
}
按縮放比例加載圖片
// 設置縮放比例
opts.inSampleSize = scale;
// 為圖片申請內存
opts.inJustDecodeBounds = false;
Bitmap bm = BitmapFactory.decodeFile("sdcard/dog.jpg", opts);
iv.setImageBitmap(bm);
直接加載的bitmap對象是只讀的,無法修改,要修改圖片只能在內存中創建出一個一模一樣的bitmap副本,然後修改副本
// 加載原圖
Bitmap srcBm = BitmapFactory.decodeFile("sdcard/photo3.jpg");
iv_src.setImageBitmap(srcBm);
// 創建與原圖大小一致的空白bitmap
Bitmap copyBm = Bitmap.createBitmap(srcBm.getWidth(), srcBm.getHeight(), srcBm.getConfig());
// 定義畫筆
Paint paint = new Paint();
// 把紙鋪在畫版上
Canvas canvas = new Canvas(copyBm);
// 把srcBm的內容繪制在copyBm上
canvas.drawBitmap(srcBm, new Matrix(), paint);
iv_copy.setImageBitmap(copyBm);
首先定義一個矩陣對象
Matrix mt = new Matrix();
縮放效果
// x軸縮放1倍,y軸縮放0.5倍
mt.setScale(1, 0.5f);
旋轉效果
// 以圖片寬高的一半中心點為軸點,順時旋轉30度
mt.setRotate(30, copyBm.getWidth() / 2, copyBm.getHeight() / 2);
平移
// x軸坐標+10,y軸坐標+20
mt.setTranslate(10, 20);
鏡面
// 把X坐標都變成負數
mt.setScale(-1, 1);
// 圖片整體向右移
mt.postTranslate(copyBm.getWidth(), 0);
倒影
// 把Y坐標都變成負數
mt.setScale(1, -1);
// 圖片整體向下移
mt.postTranslate(0, copyBm.getHeight());
功能:記錄用戶觸摸事件的XY坐標,繪制直線
給ImageView設置觸摸偵聽,得到用戶的觸摸事件,並獲知用戶觸摸ImageView的坐標
iv.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
// 觸摸屏幕
case MotionEvent.ACTION_DOWN:
// 得到觸摸屏幕時手指的坐標
startX = (int) event.getX();
startY = (int) event.getY();
break;
// 在屏幕上滑動
case MotionEvent.ACTION_MOVE:
// 用戶滑動手指,坐標不斷的改變,獲取最新坐標
int newX = (int) event.getX();
int newY = (int) event.getY();
// 用上次onTouch方法得到的坐標和本次得到的坐標繪制直線
canvas.drawLine(startX, startY, newX, newY, paint);
iv.setImageBitmap(copyBm);
startX = newX;
startY = newY;
break;
}
return true;
}
});
刷子效果,加粗畫筆
paint.setStrokeWidth(8);
調色板,改變畫筆顏色
paint.setColor(Color.GREEN);
保存圖片至SD卡
FileOutputStream fos = null;
try {
fos = new FileOutputStream(new File("sdcard/dazuo.png"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// 保存圖片
copyBm.compress(CompressFormat.PNG, 100, fos);
系統每次收到SD卡就緒廣播時,都會去遍歷sd卡的所有文件和文件夾,把遍歷到的所有多媒體文件都在MediaStore數據庫保存一個索引,這個索引包含多媒體文件的文件名、路徑、大小 圖庫每次打開時,並不會去遍歷sd卡獲取圖片,而是通過內容提供者從MediaStore數據庫中獲取圖片的信息,然後讀取該圖片
系統開機或者點擊加載sd卡按鈕時,系統會發送sd卡就緒廣播,我們也可以手動發送就緒廣播
Intent intent = new Intent();
intent.setAction(Intent.ACTION_MEDIA_MOUNTED);
intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory()));
sendBroadcast(intent);
原理:把穿內衣和穿外衣的照片重疊顯示,內衣照在下面,用戶滑動屏幕時,觸摸的是外衣照,把手指經過的像素都置為透明,內衣照就顯示出來了
給屏幕設置移動監聽,把指定的像素設置為透明
iv.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
int newX = (int) event.getX();
int newY = (int) event.getY();
// 把指定的像素變成透明
copyBm.setPixel(newX, newY, Color.TRANSPARENT);
iv.setImageBitmap(copyBm);
break;
}
return true;
}
});
每次只設置一個像素點太慢,以觸摸的像素為圓心,半徑為5畫圓,圓內的像素全部置為透明
for (int i = -5; i < 6; i++) {
for (int j = -5; j < 6; j++) {
if(Math.sqrt(i * i + j * j) <= 5)
copyBm.setPixel(newX + i, newY + j, Color.TRANSPARENT);
}
}
服務裡定義play、stop、pause、continuePlay等方法
// 播放
private void play() {
player.reset();
try {
player.setDataSource("sdcard/bzj.mp3");
player.prepare();
} catch (Exception e) {
e.printStackTrace();
}
player.start();
}
// 暫停
private void pause() {
player.pause();
}
// 停止播放
private void stop() {
player.stop();
}
// 繼續播放
private void continuePlay() {
player.start();
}
把這幾個方法抽取成一個接口MusicInterface 定義一個中間人類,繼承Binder,實現MusicInterface
先start啟動MusicService,再bind
Intent intent = new Intent(this, MusicService.class);
startService(intent);
bindService(intent, conn, BIND_AUTO_CREATE);
獲取當前的播放時間和當前音頻的最長時間
int currentPosition = player.getCurrentPosition();
int duration = player.getDuration();
播放進度需要不停的獲取,不停的刷新進度條,使用計時器每500毫秒獲取一次播放進度
發消息至Handler,把播放進度放進Message對象中,在Handler中更新SeekBar的進度
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
int currentPosition = player.getCurrentPosition();
int duration = player.getDuration();
Message msg = Message.obtain();
// 把播放進度存入Message中
Bundle data = new Bundle();
data.putInt("currentPosition", currentPosition);
data.putInt("duration", duration);
msg.setData(data);
MainActivity.handler.sendMessage(msg);
}
}, 5, 500);
在Activity中定義Handler
static Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
// 取出消息攜帶的數據
Bundle data = msg.getData();
int currentPosition = data.getInt("currentPosition");
int duration = data.getInt("duration");
// 設置播放進度
sb.setMax(duration);
sb.setProgress(currentPosition);
};
};
設置拖動監聽,拖動後把進度條設置到拖動停止的位置
// 給sb設置一個拖動偵聽
sb.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
//停止拖動時調用
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
int progress = seekBar.getProgress();
mi.seekTo(progress);
}
// 開始拖動時調用
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
// 拖動的時候不斷調用
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
}
});
播放視頻也是用MediaPlayer,不過跟音頻不同,要設置顯示在哪個SurfaceView
SurfaceView sv = (SurfaceView) findViewById(R.id.sv);
SurfaceHolder sh = sv.getHolder();
MediaPlayer player = new MediaPlayer();
player.reset();
try {
player.setDataSource("sdcard/2.3gp");
player.setDisplay(sh);
player.prepare();
} catch (Exception e) {
e.printStackTrace();
}
player.start();
SurfaceView是重量級組件,可見時才會創建
給SurfaceHolder設置CallBack,類似於偵聽,可以知道SurfaceView的狀態
sh.addCallback(new Callback() {
// SurfaceView銷毀時調用
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
// SurfaceView創建時調用
@Override
public void surfaceCreated(SurfaceHolder holder) {
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
});
SurfaceView一旦不可見,就會被銷毀,一旦可見,就會被創建,銷毀時停止播放,再次創建時再開始播放
啟動系統提供的拍照程序
// 隱式啟動系統提供的拍照Activity
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// 設置照片的保存路徑
File file = new File(Environment.getExternalStorageDirectory(), "haha.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
startActivityForResult(intent, 0);
啟動系統提供的攝像程序
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
File file = new File(Environment.getExternalStorageDirectory(), "haha.3gp");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
// 設置保存視頻文件的質量
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
startActivityForResult(intent, 0);
需求:Activity(fragment)跳轉的時候當前界面裂開,上下各自拉出手機屏幕,之後跳轉到相對應的Activity.整體效果圖如下思路:1,在當前Activity
這篇博客我們來介紹一下策略模式(Strategy Pattern,或者叫 Policy Pattern),也是行為型模式之一。通常在軟件開發中,我們為了一個功能可能會設計
Systemproperties類在android.os下,但這個類是隱藏的,上層程序開發無法直接使用,用Java的反射機制就可以了。Java代碼中創建與修改androi
之前學習過了MediaPlayer用於播放手機音樂,但是在手機中很多的提示音並不是使用MediaPlayer來播放的比如短信鈴聲,通知鈴聲,android中使用Sound