編輯:關於Android編程
Android應用--簡、美音樂播放器增加音量控制
2013年6月26日簡、美音樂播放器繼續完善中、、
題外話:上一篇博客是在6月11號發的,那篇博客似乎有點問題,可能是因為代碼結構有點亂的原因,很難把握整體。整個應用的開發,周期太長了,有時候因為一些雜事未能抽出時間來繼續開發,有時候又沒有心情去做,所以一直拖。如果真正的開發讓我拖那麼久的話,早就成了死亡之旅項目了。作為一定獨立開發者我是不合格的,還沒有一個成熟的作品出來,一直想能做出個拿得出手的應用放上應用商店讓所有人都能用到,但有心而力不從。不知道做什麼是一個原因,個人水平也有限,雜事繁多時間安排不當。各種借口。不過,小巫會做一個獨特的應用作為自己的畢業設計的,至於怎麼獨特還沒有特別的思路。可能到時也會把自己的畢業設計作品整理成博客,讓學習Android的朋友們參考參考。感謝網友們的一直支持。
有網友說要看Mp3Info類,在這裡也就貼出來
[java]
package com.wwj.sb.domain;
/**
* 2013/5/7 mp3實體類
*
* @author wwj
*
*/
public class Mp3Info{
private long id; // 歌曲ID
private String title; // 歌曲名稱
private String album; // 專輯
private String artist; // 歌手名稱
private long duration; // 歌曲時長
private long size; // 歌曲大小
private String url; // 歌曲路徑
private String lrcTitle; // 歌詞名稱
private String lrcSize; // 歌詞大小
public Mp3Info() {
super();
}
/**
*
* @param id
* @param title
* @param album
* @param artist
* @param duration
* @param size
* @param lrcTitle
* @param lrcSize
* @param url
*/
public Mp3Info(int id, String title, String album, String artist,
int duration, int size, String lrcTitle, String lrcSize,
String url) {
super();
this.id = id;
this.title = title;
this.album = album;
this.artist = artist;
this.duration = duration;
this.size = size;
this.lrcTitle = lrcTitle;
this.lrcSize = lrcSize;
this.url = url;
}
@Override
public String toString() {
return "Mp3Info [id=" + id + ", title=" + title + ", album=" + album
+ ", artist=" + artist + ", duration=" + duration + ", size="
+ size + ", url=" + url + ", lrcTitle=" + lrcTitle
+ ", lrcSize=" + lrcSize + "]";
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAlbum() {
return album;
}
public void setAlbum(String album) {
this.album = album;
}
public String getArtist() {
return artist;
}
public void setArtist(String artist) {
this.artist = artist;
}
public long getDuration() {
return duration;
}
public void setDuration(long duration) {
this.duration = duration;
}
public long getSize() {
return size;
}
public void setSize(long size) {
this.size = size;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getLrcTitle() {
return lrcTitle;
}
public void setLrcTitle(String lrcTitle) {
this.lrcTitle = lrcTitle;
}
public String getLrcSize() {
return lrcSize;
}
public void setLrcSize(String lrcSize) {
this.lrcSize = lrcSize;
}
}
package com.wwj.sb.domain;
/**
* 2013/5/7 mp3實體類
*
* @author wwj
*
*/
public class Mp3Info{
private long id; // 歌曲ID
private String title; // 歌曲名稱
private String album; // 專輯
private String artist; // 歌手名稱
private long duration; // 歌曲時長
private long size; // 歌曲大小
private String url; // 歌曲路徑
private String lrcTitle; // 歌詞名稱
private String lrcSize; // 歌詞大小
public Mp3Info() {
super();
}
/**
*
* @param id
* @param title
* @param album
* @param artist
* @param duration
* @param size
* @param lrcTitle
* @param lrcSize
* @param url
*/
public Mp3Info(int id, String title, String album, String artist,
int duration, int size, String lrcTitle, String lrcSize,
String url) {
super();
this.id = id;
this.title = title;
this.album = album;
this.artist = artist;
this.duration = duration;
this.size = size;
this.lrcTitle = lrcTitle;
this.lrcSize = lrcSize;
this.url = url;
}
@Override
public String toString() {
return "Mp3Info [id=" + id + ", title=" + title + ", album=" + album
+ ", artist=" + artist + ", duration=" + duration + ", size="
+ size + ", url=" + url + ", lrcTitle=" + lrcTitle
+ ", lrcSize=" + lrcSize + "]";
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAlbum() {
return album;
}
public void setAlbum(String album) {
this.album = album;
}
public String getArtist() {
return artist;
}
public void setArtist(String artist) {
this.artist = artist;
}
public long getDuration() {
return duration;
}
public void setDuration(long duration) {
this.duration = duration;
}
public long getSize() {
return size;
}
public void setSize(long size) {
this.size = size;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getLrcTitle() {
return lrcTitle;
}
public void setLrcTitle(String lrcTitle) {
this.lrcTitle = lrcTitle;
}
public String getLrcSize() {
return lrcSize;
}
public void setLrcSize(String lrcSize) {
this.lrcSize = lrcSize;
}
}
這篇博客要增加的功能是控制音量,其實已經非常簡單了,不過這裡用到了動畫還是可以用來講講的。
運行效果截圖:
點擊左下角的那個音頻按鈕就可以顯示出控制音量的面板,滑動拖動條就可以控制音量了。
控制音量面板的布局代碼:
[html]
<RelativeLayout
android:id="@+id/ll_player_voice"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/header_layout"
android:background="@drawable/player_progresslayout_bg"
android:visibility="gone" >
<ImageView
android:id="@+id/iv_player_min_voice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:background="@drawable/volume_min_icon" />
<ImageView
android:id="@+id/iv_player_max_voice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="@drawable/volume_max_icon" />
<SeekBar
android:id="@+id/sb_player_voice"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toLeftOf="@id/iv_player_max_voice"
android:layout_toRightOf="@id/iv_player_min_voice"
android:background="@drawable/voice_seekbar_bg"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:progressDrawable="@drawable/voice_seekbar_progress"
android:thumb="@drawable/voice_seekbar_thumb" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/ll_player_voice"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/header_layout"
android:background="@drawable/player_progresslayout_bg"
android:visibility="gone" >
<ImageView
android:id="@+id/iv_player_min_voice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:background="@drawable/volume_min_icon" />
<ImageView
android:id="@+id/iv_player_max_voice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="@drawable/volume_max_icon" />
<SeekBar
android:id="@+id/sb_player_voice"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toLeftOf="@id/iv_player_max_voice"
android:layout_toRightOf="@id/iv_player_min_voice"
android:background="@drawable/voice_seekbar_bg"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:progressDrawable="@drawable/voice_seekbar_progress"
android:thumb="@drawable/voice_seekbar_thumb" />
</RelativeLayout>
/drawable/voice_seekbar_progress.xml
這個用來顯示進度條,用到了圖層資源
[html]
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background"
android:drawable="@drawable/voice_seekbar_bg">
</item>
<item android:id="@android:id/progress">
<clip android:drawable="@drawable/voice_seekbar_one" />
</item>
</layer-list>
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background"
android:drawable="@drawable/voice_seekbar_bg">
</item>
<item android:id="@android:id/progress">
<clip android:drawable="@drawable/voice_seekbar_one" />
</item>
</layer-list>
/drawable、voice_seekbar_thumb.xml
拖動條滑塊的選擇器
[html]
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/voice_thumb_press" />
<item android:drawable="@drawable/voice_thumb_normal" />
</selector>
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/voice_thumb_press" />
<item android:drawable="@drawable/voice_thumb_normal" />
</selector>
寫到這裡,我想到了可能令開發者頭痛的應該是沒有合適的素材,其實這些素材並不一定要自己去做,況且也不一定能做到美觀,也沒那麼多時間。所以我們可以就地取材,這時候反編譯的技術就有用了,下載一些你認為你需要用到的素材的應用的APK文件,進行反編譯,就可以得到大量的素材。把這些素材用到你的應用就行啦。反正小巫一直都是這麼做的,小巫沒辦法自己去做。
接著:定義相應的變量
[java]
private AudioManager am; //音頻管理引用,提供對音頻的控制
RelativeLayout ll_player_voice; //音量控制面板布局
int currentVolume; //當前音量
int maxVolume; //最大音量
ImageButton ibtn_player_voice; //顯示音量控制面板的按鈕
SeekBar sb_player_voice; //控制音量大小
// 音量面板顯示和隱藏動畫
private Animation showVoicePanelAnimation;
private Animation hiddenVoicePanelAnimation;
private AudioManager am; //音頻管理引用,提供對音頻的控制
RelativeLayout ll_player_voice; //音量控制面板布局
int currentVolume; //當前音量
int maxVolume; //最大音量
ImageButton ibtn_player_voice; //顯示音量控制面板的按鈕
SeekBar sb_player_voice; //控制音量大小
// 音量面板顯示和隱藏動畫
private Animation showVoicePanelAnimation;
private Animation hiddenVoicePanelAnimation;
獲取對象
[java]
showVoicePanelAnimation = AnimationUtils.loadAnimation(PlayerActivity.this, R.anim.push_up_in);
hiddenVoicePanelAnimation = AnimationUtils.loadAnimation(PlayerActivity.this, R.anim.push_up_out);
//獲得系統音頻管理服務對象
am = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
currentVolume = am.getStreamVolume(AudioManager.STREAM_MUSIC);
maxVolume = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
sb_player_voice.setMax(maxVolume);
showVoicePanelAnimation = AnimationUtils.loadAnimation(PlayerActivity.this, R.anim.push_up_in);
hiddenVoicePanelAnimation = AnimationUtils.loadAnimation(PlayerActivity.this, R.anim.push_up_out);
//獲得系統音頻管理服務對象
am = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
currentVolume = am.getStreamVolume(AudioManager.STREAM_MUSIC);
maxVolume = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
sb_player_voice.setMax(maxVolume);
動畫文件
puch_up_in.xml
[html]
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator">
<alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="200"/>
<translate android:fromYDelta="-100%" android:toYDelta="0" android:duration="200"/>
</set>
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator">
<alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="200"/>
<translate android:fromYDelta="-100%" android:toYDelta="0" android:duration="200"/>
</set>
push_up_out.xml
[html]
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator">
<alpha android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="200"/>
<translate android:fromYDelta="0" android:toYDelta="-100%" android:duration="200"/>
</set>
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator">
<alpha android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="200"/>
<translate android:fromYDelta="0" android:toYDelta="-100%" android:duration="200"/>
</set>
找到控件
[java]
ibtn_player_voice = (ImageButton) findViewById(R.id.ibtn_player_voice);
ll_player_voice = (RelativeLayout) findViewById(R.id.ll_player_voice);
sb_player_voice = (SeekBar) findViewById(R.id.sb_player_voice);
ibtn_player_voice = (ImageButton) findViewById(R.id.ibtn_player_voice);
ll_player_voice = (RelativeLayout) findViewById(R.id.ll_player_voice);
sb_player_voice = (SeekBar) findViewById(R.id.sb_player_voice);
設置監聽器
[java]
ibtn_player_voice.setOnClickListener(ViewOnClickListener);
sb_player_voice.setOnSeekBarChangeListener(new SeekBarChangeListener());
ibtn_player_voice.setOnClickListener(ViewOnClickListener);
sb_player_voice.setOnSeekBarChangeListener(new SeekBarChangeListener());
ibtn_player_voice用來控制動畫顯示面板
[java]
case R.id.ibtn_player_voice: //控制音量
voicePanelAnimation();
break;
case R.id.ibtn_player_voice: //控制音量
voicePanelAnimation();
break;
[java]
//控制顯示音量控制面板的動畫
public void voicePanelAnimation() {
if(ll_player_voice.getVisibility() == View.GONE) {
ll_player_voice.startAnimation(showVoicePanelAnimation);
ll_player_voice.setVisibility(View.VISIBLE);
}
else{
ll_player_voice.startAnimation(hiddenVoicePanelAnimation);
ll_player_voice.setVisibility(View.GONE);
}
}
//控制顯示音量控制面板的動畫
public void voicePanelAnimation() {
if(ll_player_voice.getVisibility() == View.GONE) {
ll_player_voice.startAnimation(showVoicePanelAnimation);
ll_player_voice.setVisibility(View.VISIBLE);
}
else{
ll_player_voice.startAnimation(hiddenVoicePanelAnimation);
ll_player_voice.setVisibility(View.GONE);
}
}
sb_player_voice用來控制音量大小
[java]
/**
* 實現監聽Seekbar的類
*
* @author wwj
*
*/
private class SeekBarChangeListener implements OnSeekBarChangeListener {
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
switch(seekBar.getId()) {
case R.id.audioTrack:
if (fromUser) {
audioTrackChange(progress); // 用戶控制進度的改變
}
break;
case R.id.sb_player_voice:
// 設置音量
am.setStreamVolume(AudioManager.STREAM_MUSIC, progress, 0);
break;
}
}
/**
* 實現監聽Seekbar的類
*
* @author wwj
*
*/
private class SeekBarChangeListener implements OnSeekBarChangeListener {
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
switch(seekBar.getId()) {
case R.id.audioTrack:
if (fromUser) {
audioTrackChange(progress); // 用戶控制進度的改變
}
break;
case R.id.sb_player_voice:
// 設置音量
am.setStreamVolume(AudioManager.STREAM_MUSIC, progress, 0);
break;
}
}
Git上看到的一個蠻清爽的一個Dialog介紹給大家。實現效果個人感覺做的還是滿Q彈的如何使用? compile 'com.github.michae
注冊很多app或者網絡賬戶的時候,經常需要手機獲取驗證碼,來完成注冊,那時年少,只是覺得手機獲取驗證碼這件事兒很好玩,並沒有關心太多,她是如何實現的,以及她背後的故事到底
支付寶有上線一項繳費服務新功能——ETC繳費功能,用戶可以通過支付寶對武漢地區的ETC進行繳費,這個功能暫時面對武漢市的廣大司機朋友
很多的Android入門程序猿來說對於Android自定義View,可能都是比較恐懼的,但是這又是高手進階的必經之路,所有准備在自定義View上面花一些功夫,多寫一些文章
問題背景:app在上傳圖片時,同時傳遞參數,支持傳遞多個圖片。本文中的環