続き。string.xmlから。
<string name="no_title">no title</string>
追加。次、main.xml。レイアウトの一番上に
<Spinner
android:id="@+id/spinner"
android:layout_width="fill_parent"
android:layout_height="30dp"
android:background="@color/red">
</Spinner>
後、TextViewに
android:text="@string/no_title"
追加。なんとなく。次、Activity。
フィールド
private static final String FILE_SEP = File.separator; 削除。
musicListをmusicFileListに変更。名前だけ。
編集→検索/置換で。ただし、すべて置換はやめたほうがいい。
private ArrayList<String> musicDirList;
private MusicListAdapter listAdapter;
private String musicDirName;
private Spinner spinner;
↑4つ追加。そんで、onCreateを
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
//DirListMakerの生成
DirListMaker dlm = new DirListMaker();
//spinnerに渡すリストの作成
ArrayList<String> dirList = new ArrayList<String>();
dirList.add(SD_PATH);
musicDirList = dlm.dirListMaker(dirList, "mp3");
//spinnerの取得とArrayAdapterの生成及びセット
spinner = (Spinner)findViewById(R.id.spinner);
ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, musicDirList);
spinnerAdapter.setDropDownViewResource(
android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(spinnerAdapter);
spinner.setOnItemSelectedListener(this);
//musicFileListの生成
musicFileList = new ArrayList<String>();
//リストビューの取得と諸々のこと
listView = (ListView)findViewById(R.id.listView);
listView.setItemsCanFocus(false);
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
//クリックされた事を検知。selectedとの違いは分かってません。
listView.setOnItemClickListener(this);
//musicPlayerの引数に渡すので先に取得
titleView = (TextView)findViewById(R.id.titleView);
//musicPlayerの生成とmusicNumの取得
musicPlayer = new MusicPlayer(titleView);
pauseFlag = false; //一時停止解除
changeMusicFlag = false;//曲変更のお知らせ。
//listAdapterの生成
listAdapter = new MusicListAdapter(this,
R.layout.rowdata, musicFileList, listView);
//musicList変更用
flm = new FileListMaker();
}
こんな↑感じ。それから、
//これも@Override出来ない。なんか残念。spinnerのイベント処理
public void onItemSelected(AdapterView<?> parent,
View view, int position, long id) {
//選択されたアイテムの取得。
musicDirName = musicDirList.get(position);
//リストの詰め替え準備
musicFileList.clear();
//リストの詰め替え
flm.fileListMaker(musicDirName, "mp3", musicFileList);
//listViewの変更
listView.setAdapter(listAdapter);
//色々通知。
musicPlayer.setMusicDir(musicDirName);
musicPlayer.setMusicList(musicFileList);
musicPlayer.setListView(listView);
}
確かこれだけ。後は、MusicPlayer。
フィールドの
private static final String SD_PATH = //SDのパス
Environment.getExternalStorageDirectory().getPath();
削除。そんで、コンストラクタを変更してセッター追加。
public MusicPlayer(TextView tv) {
super();
titleView = tv;
musicNum = 0;
super.setOnCompletionListener(this);
}
public void setMusicList(ArrayList<String> array) {
musicList = array;
}
public void setListView(ListView lv) {
listView = lv;
}
public void setMusicDir(String name) {
musicDirName = name;
}
それから、
listView.setSelection(musicNum - 1);
に変更。これは、なんとなく。見た目の問題。で、最後が
super.setDataSource(musicDirName
+ FILE_SEP + musicList.get(musicNum));
に変更。これは、結構重要。やらないと音楽が聴けません。
以上。だと思います。
なんか、段々それなりになってきた様な気がしないでもない。
でもねー。やっぱりねー。前に作ったのと同じ問題発生中。
強制終了になることはない。と思いたい。
ディレクトリAの5曲目を再生中に、ディレクトリBに変えると
Aの6曲目ではなく、Bの6曲目がかかります。
ちなみにBに6曲目がないと・・・。
1曲目に戻ります。そんだけ。
まあ、ぼちぼち修正します。
次は、ディレクトリをまたいでの連続再生。
問題を解消しないままに。たぶん。
追記
public void onNothingSelected(AdapterView<?> arg0) {
// TODO 自動生成されたメソッド・スタブ
}
これ、忘れてました。追加しろと言われたので、言われるままに。
2010-11-30
mediaplayerを作ってみる(8)-1
今回はspinner。予定どおり。
参考はこことここ、そしてここ。
何か、嫌がらせの様だ。別にそんな気はないですが。
(8)-1では、3つ目のここを参考にして作ったclass + αを。
まあ、参考というかちょっと変えただけですが。そんなんばっか。
まあ、とりあえず。
SD内の音楽ファイルの入ったディレクトリを、
ArrayListに詰め込みます。音楽ファイル以外にも使えます。たぶん。
いやきっと。参考にしたとこを考えると。載せときます。
package net.asasvata.listmaker;
import java.io.File;
import java.util.ArrayList;
public class DirListMaker {
private final String FILE_SEP = File.separator;
//ファイル1種類用
public ArrayList<String> dirListMaker(ArrayList<String> list, String ext) {
//ArrayListの生成
ArrayList<String> array = new ArrayList<String>();
int m = 0; int n = 0;
while (list.size() > m) {
File subDir = new File(list.get(m));
String[] subFileName = subDir.list();
n = 0;
while (subFileName.length > n) {
File subFile = new File(subDir.getPath() + FILE_SEP + subFileName[n]);
if (subFile.isDirectory()) {
list.add(subDir.getPath() + FILE_SEP + subFileName[n]);
} else if (subFile.isFile() && subFile.getName().endsWith(ext)) {
if (!array.contains(list.get(m))) {
array.add(list.get(m));
}
}
n++;
}
m++;
}
return array;
}
//ファイル2種類用
public ArrayList<String> dirListMaker(ArrayList<String> list, String ext1, String ext2) {
ArrayList<String> array = new ArrayList<String>();
int m = 0; int n = 0;
while (list.size() > m) {
File subDir = new File(list.get(m));
String[] subFileName = subDir.list();
n = 0;
while (subFileName.length > n) {
File subFile = new File(subDir.getPath() + FILE_SEP + subFileName[n]);
if (subFile.isDirectory()) {
list.add(subDir.getPath() + FILE_SEP + subFileName[n]);
} else if (subFile.isFile() &&
(subFile.getName().endsWith(ext1) || subFile.getName().endsWith(ext2))) {
if (!array.contains(list.get(m))) {
array.add(list.get(m));
}
}
n++;
}
m++;
}
return array;
}
}
パッケージも分けました。なんとなく。javaっぽいかと。
ファイル2種類用も作りました。元ネタと同じ書き方なので。
動くと思います。確認してませんが。
違うのはファイルをリストに詰めるのではなく、ディレクトリを詰めること。
まあ、そんだけしか変えてません。
後、もう一個。ついでに作りました。
package net.asasvata.listmaker;
import java.io.File;
import java.util.ArrayList;
public class FileListMaker {
private final String FILE_SEP = File.separator;
//ファイル1種類用
public void fileListMaker(String name, String ext, ArrayList<String> list) {
File musicFile = new File(name);
String[] musicFileList = musicFile.list();
for (String fileName : musicFileList) {
File file = new File(name + FILE_SEP + fileName);
if (file.isFile() && fileName.endsWith(ext)) {
list.add(fileName);
}
}
}
//ファイル2種類用
public void fileListMaker(String name, String ext1, String ext2, ArrayList<String> list) {
File musicFile = new File(name);
String[] musicFileList = musicFile.list();
for (String fileName : musicFileList) {
File file = new File(name + FILE_SEP + fileName);
if (file.isFile() && (fileName.endsWith(ext1) || fileName.endsWith(ext2))) {
list.add(fileName);
}
}
}
}
まあ、なんですなdirListMakerで作ったディレクトリリストに入ってる
ファイルを別のリストに詰め込む。そんな感じ。spinnerを介して。
で、こいつらを使ったコードを(8)-2に載せときます。
参考はこことここ、そしてここ。
何か、嫌がらせの様だ。別にそんな気はないですが。
(8)-1では、3つ目のここを参考にして作ったclass + αを。
まあ、参考というかちょっと変えただけですが。そんなんばっか。
まあ、とりあえず。
SD内の音楽ファイルの入ったディレクトリを、
ArrayListに詰め込みます。音楽ファイル以外にも使えます。たぶん。
いやきっと。参考にしたとこを考えると。載せときます。
package net.asasvata.listmaker;
import java.io.File;
import java.util.ArrayList;
public class DirListMaker {
private final String FILE_SEP = File.separator;
//ファイル1種類用
public ArrayList<String> dirListMaker(ArrayList<String> list, String ext) {
//ArrayListの生成
ArrayList<String> array = new ArrayList<String>();
int m = 0; int n = 0;
while (list.size() > m) {
File subDir = new File(list.get(m));
String[] subFileName = subDir.list();
n = 0;
while (subFileName.length > n) {
File subFile = new File(subDir.getPath() + FILE_SEP + subFileName[n]);
if (subFile.isDirectory()) {
list.add(subDir.getPath() + FILE_SEP + subFileName[n]);
} else if (subFile.isFile() && subFile.getName().endsWith(ext)) {
if (!array.contains(list.get(m))) {
array.add(list.get(m));
}
}
n++;
}
m++;
}
return array;
}
//ファイル2種類用
public ArrayList<String> dirListMaker(ArrayList<String> list, String ext1, String ext2) {
ArrayList<String> array = new ArrayList<String>();
int m = 0; int n = 0;
while (list.size() > m) {
File subDir = new File(list.get(m));
String[] subFileName = subDir.list();
n = 0;
while (subFileName.length > n) {
File subFile = new File(subDir.getPath() + FILE_SEP + subFileName[n]);
if (subFile.isDirectory()) {
list.add(subDir.getPath() + FILE_SEP + subFileName[n]);
} else if (subFile.isFile() &&
(subFile.getName().endsWith(ext1) || subFile.getName().endsWith(ext2))) {
if (!array.contains(list.get(m))) {
array.add(list.get(m));
}
}
n++;
}
m++;
}
return array;
}
}
パッケージも分けました。なんとなく。javaっぽいかと。
ファイル2種類用も作りました。元ネタと同じ書き方なので。
動くと思います。確認してませんが。
違うのはファイルをリストに詰めるのではなく、ディレクトリを詰めること。
まあ、そんだけしか変えてません。
後、もう一個。ついでに作りました。
package net.asasvata.listmaker;
import java.io.File;
import java.util.ArrayList;
public class FileListMaker {
private final String FILE_SEP = File.separator;
//ファイル1種類用
public void fileListMaker(String name, String ext, ArrayList<String> list) {
File musicFile = new File(name);
String[] musicFileList = musicFile.list();
for (String fileName : musicFileList) {
File file = new File(name + FILE_SEP + fileName);
if (file.isFile() && fileName.endsWith(ext)) {
list.add(fileName);
}
}
}
//ファイル2種類用
public void fileListMaker(String name, String ext1, String ext2, ArrayList<String> list) {
File musicFile = new File(name);
String[] musicFileList = musicFile.list();
for (String fileName : musicFileList) {
File file = new File(name + FILE_SEP + fileName);
if (file.isFile() && (fileName.endsWith(ext1) || fileName.endsWith(ext2))) {
list.add(fileName);
}
}
}
}
まあ、なんですなdirListMakerで作ったディレクトリリストに入ってる
ファイルを別のリストに詰め込む。そんな感じ。spinnerを介して。
で、こいつらを使ったコードを(8)-2に載せときます。
mediaplayerを作ってみる(7)
(5)のしたの方に書いたのをもう一度載せときます。
参考と言うかまんまなのはここ。
Android Manifestのactivityのとこを、
<activity android:name=".SDMediaPlayerActivity"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:configChanges="orientation|keyboardHidden">
こんな感じに、下2行追加しておくと、縦画面固定で
横にしても音楽が、かかりっぱなしの暴走をしなくなります。
横画面を切り替えたい方は、頑張ってください。僕は縦固定で。
を追加。で、playMusicの中、setTitleの下あたりに
listView.clearChoices();
listView.setItemChecked(musicNum, true);
listView.setSelection(musicNum);
を追加。なんかこれがいいみたい。色々試した結果。
僕のイメージには、あってる。今のところ。
そいから、Activity。フィールドに
private int musicNum_listClicked;
なんか変な名前。まあ、ね。
で、onCreateの中を、
listView = (ListView)findViewById(R.id.listView);//ここは、前と同じ。上書き。
listView.setItemsCanFocus(false);
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
//MusicListAdapterの生成
MusicListAdapter listAdapter =
new MusicListAdapter(this, R.layout.rowdata, musicList, listView);
んな感じ。それから、onItemClickの中を
listPosition = position;//ここは、前と同じ。上書き。
musicNum_listClicked = musicPlayer.getMusicNum();
changeMusicFlag = true;
に変更。setTitleは削除。
で、onClickStartを
public void onClickStart(View view) {
if (!musicPlayer.isPlaying()){
//停止中にlistViewで曲変更した場合
if (changeMusicFlag) {
musicPlayer.setMusicNum(listPosition);
musicPlayer.playMusic();
changeMusicFlag = false;
}
if (pauseFlag) { //一時停止中なら
musicPlayer.start();
pauseFlag = false;
} else {
musicPlayer.playMusic();
changeMusicFlag = false;
}
}
//再生中で曲選択が変わってたら。つまり、listViewで選択した場合です。
if (changeMusicFlag && musicNum_listClicked
changeMusicFlag = false;に。
間違ってました。
動きとしては、
停止中
・listViewをクリックするとグレーになる。
・listViewをクリックしただけではタイトルは変わらない。
・再生するとタイトルも変わる。
・進む、戻るはタイトルが変わる。listViewの色は変わらない。
・listViewクリックと進む、戻るは最後の選択が有効。
再生中
・listViewの動きは停止中と同じ。連続再生で次の曲にいくまで有効。
・進む、戻るは曲・タイトル・listViewすべて変わる。
多分。そんな感じ。要確認。
次は、spinner。名前が好きなので。使います。予定ですが。
参考と言うかまんまなのはここ。
Android Manifestのactivityのとこを、
<activity android:name=".SDMediaPlayerActivity"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:configChanges="orientation|keyboardHidden">
こんな感じに、下2行追加しておくと、縦画面固定で
横にしても音楽が、かかりっぱなしの暴走をしなくなります。
横画面を切り替えたい方は、頑張ってください。僕は縦固定で。
後、MediaPlayerでサポートされてるファイル形式はここ。
今回の変更は前回の修正と、まあ、色々と。
とりあえず、参考にしたのはこことここ。この書き方良くないですかね。
まあ、変える気はありませんが。今のとこ。
rowdata.xml
<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/checkedTextView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:paddingLeft="10dip"
android:gravity="center"
android:textColor="@color/green">
</CheckedTextView>
CheckedTextView。まんまです。
で、 MusicListAdapter classを作成
package net.asasvata.sdmediaplayer;
import java.util.ArrayList;
import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckedTextView;
import android.widget.ListView;
//import android.widget.TextView;
public class MusicListAdapter extends ArrayAdapter<String> {
private LayoutInflater inflater;
private int layoutId;
private ListView listView;
public MusicListAdapter(Context context, int layoutId, ArrayList<String> objects, ListView listView) {
super(context, 0, objects);
this.inflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.layoutId = layoutId;
this.listView = listView;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(layoutId, parent, false);
}
//String data = getItem(position);
((CheckedTextView)convertView).setText((position + 1) + ": " +
listView.getItemAtPosition(position).toString());
if(position == listView.getCheckedItemPosition())
((CheckedTextView)convertView).setBackgroundColor(Color.DKGRAY);
else
((CheckedTextView)convertView).setBackgroundColor(Color.TRANSPARENT);
return convertView;
}
}
表示内容以外はそのままです。有難い。中身は、よく分かりませんが。
次は、MusicPlayer。フィールドに
private ListView listView;
を追加。それから、コンストラクタの引数に
ListView lv
を追加。コンストラクタの中に
listView = lv;
今回の変更は前回の修正と、まあ、色々と。
とりあえず、参考にしたのはこことここ。この書き方良くないですかね。
まあ、変える気はありませんが。今のとこ。
rowdata.xml
<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/checkedTextView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:paddingLeft="10dip"
android:gravity="center"
android:textColor="@color/green">
</CheckedTextView>
CheckedTextView。まんまです。
で、 MusicListAdapter classを作成
package net.asasvata.sdmediaplayer;
import java.util.ArrayList;
import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckedTextView;
import android.widget.ListView;
//import android.widget.TextView;
public class MusicListAdapter extends ArrayAdapter<String> {
private LayoutInflater inflater;
private int layoutId;
private ListView listView;
public MusicListAdapter(Context context, int layoutId, ArrayList<String> objects, ListView listView) {
super(context, 0, objects);
this.inflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.layoutId = layoutId;
this.listView = listView;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(layoutId, parent, false);
}
//String data = getItem(position);
((CheckedTextView)convertView).setText((position + 1) + ": " +
listView.getItemAtPosition(position).toString());
if(position == listView.getCheckedItemPosition())
((CheckedTextView)convertView).setBackgroundColor(Color.DKGRAY);
else
((CheckedTextView)convertView).setBackgroundColor(Color.TRANSPARENT);
return convertView;
}
}
表示内容以外はそのままです。有難い。中身は、よく分かりませんが。
次は、MusicPlayer。フィールドに
private ListView listView;
を追加。それから、コンストラクタの引数に
ListView lv
を追加。コンストラクタの中に
listView = lv;
を追加。で、playMusicの中、setTitleの下あたりに
listView.clearChoices();
listView.setItemChecked(musicNum, true);
listView.setSelection(musicNum);
を追加。なんかこれがいいみたい。色々試した結果。
僕のイメージには、あってる。今のところ。
そいから、Activity。フィールドに
private int musicNum_listClicked;
なんか変な名前。まあ、ね。
で、onCreateの中を、
listView = (ListView)findViewById(R.id.listView);//ここは、前と同じ。上書き。
listView.setItemsCanFocus(false);
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
//MusicListAdapterの生成
MusicListAdapter listAdapter =
new MusicListAdapter(this, R.layout.rowdata, musicList, listView);
んな感じ。それから、onItemClickの中を
listPosition = position;//ここは、前と同じ。上書き。
musicNum_listClicked = musicPlayer.getMusicNum();
changeMusicFlag = true;
に変更。setTitleは削除。
で、onClickStartを
public void onClickStart(View view) {
if (!musicPlayer.isPlaying()){
//停止中にlistViewで曲変更した場合
if (changeMusicFlag) {
musicPlayer.setMusicNum(listPosition);
musicPlayer.playMusic();
changeMusicFlag = false;
}
if (pauseFlag) { //一時停止中なら
musicPlayer.start();
pauseFlag = false;
} else {
musicPlayer.playMusic();
changeMusicFlag = false;
}
}
//再生中で曲選択が変わってたら。つまり、listViewで選択した場合です。
if (changeMusicFlag && musicNum_listClicked
== musicPlayer.getMusicNum()) {
musicPlayer.setMusicNum(listPosition);
musicPlayer.playMusic();
changeMusicFlag = false;
} else {
changeMusicFlag = false;
}
}
どこを変えたか分かりにくいので。
musicNum_listClicked == musicPlayer.getMusicNum()
musicPlayer.setMusicNum(listPosition);
musicPlayer.playMusic();
changeMusicFlag = false;
} else {
changeMusicFlag = false;
}
}
どこを変えたか分かりにくいので。
musicNum_listClicked == musicPlayer.getMusicNum()
これ↑は、 連続再生で次に進んでなかったらと言うことです。
後、setTitle()の中の、
changeMusicFlag = ture;をchangeMusicFlag = false;に。
間違ってました。
動きとしては、
停止中
・listViewをクリックするとグレーになる。
・listViewをクリックしただけではタイトルは変わらない。
・再生するとタイトルも変わる。
・進む、戻るはタイトルが変わる。listViewの色は変わらない。
・listViewクリックと進む、戻るは最後の選択が有効。
再生中
・listViewの動きは停止中と同じ。連続再生で次の曲にいくまで有効。
・進む、戻るは曲・タイトル・listViewすべて変わる。
多分。そんな感じ。要確認。
次は、spinner。名前が好きなので。使います。予定ですが。
2010-11-28
mediaplayerを作ってみる(6)-2
続き。(6)-1からの。Activityを。
package net.asasvata.sdmediaplayer;
import java.io.File;
import java.util.ArrayList;
import android.app.Activity;
import android.graphics.Typeface;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
public class SDMediaPlayerActivity extends Activity
implements AdapterView.OnItemClickListener {
//フィールド
private static final String SD_PATH = //SDのパス
Environment.getExternalStorageDirectory().getPath();
private static final String FILE_SEP = File.separator;//pathの区切り文字
private ArrayList<String> musicList;
private MusicPlayer musicPlayer;
private boolean pauseFlag;//一時停止の判定用
private boolean changeMusicFlag;//musicNumの変更判定用
private int listPosition;//listViewが、クリックされた時の位置を保持
private ListView listView;//ディレクトリ内の曲のリスト表示
private TextView titleView;//現在選択されている曲の表示
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
//musicListの生成と曲の追加
musicList = new ArrayList<String>();
File musicFile = new File(SD_PATH + FILE_SEP + "deepfm");
String[] musicFileList = musicFile.list();
for(String fileName : musicFileList) {
File f = new File(SD_PATH + FILE_SEP + "deepfm"
+ FILE_SEP + fileName);
if(f.isFile() && fileName.endsWith("mp3"))
musicList.add(fileName);
}
listView = (ListView)findViewById(R.id.listView);
//ArrayAdapterの生成
ArrayAdapter<String> listAdapter =
new ArrayAdapter<String>(this, R.layout.rowdata, musicList);
//listViewにlistAdapterをセット。
listView.setAdapter(listAdapter);
//クリックされた事を検知。selectedとの違いは分かってません。
listView.setOnItemClickListener(this);
//musicPlayerの引数に渡すので先に取得
titleView = (TextView)findViewById(R.id.titleView);
//musicPlayerの生成とmusicNumの取得
musicPlayer = new MusicPlayer(musicList, titleView);
//タイトルのセット。flagの初期化も。
setTitle();
}
//とりあえず。
@Override
public void onStop() {
super.onStop();
musicPlayer.stop();
}
//なぜかOverride出来ない。listViewがクリックされた時の処理。
//@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//曲の選択をするだけ。再生はしない。とりあえず。
listPosition = position;
setTitle(position);
}
//ボタンが押されたときの処理。レイアウトの右から順に。
//戻る
public void onClickBack(View view) {
int n = musicPlayer.getMusicNum() - 1;//とりあえず減らす
if (n < 0) {
n = musicList.size() - 1;//最後の曲を指定
musicPlayer.setMusicNum(n);
if (musicPlayer.isPlaying()) musicPlayer.playMusic();
else setTitle();
} else {
musicPlayer.setMusicNum(n);
if (musicPlayer.isPlaying()) musicPlayer.playMusic();
else setTitle();
}
}
//進む
public void onClickNext(View view) {
int n = musicPlayer.getMusicNum() + 1;//とりあえず増やす。
if (n < musicList.size()) {
musicPlayer.setMusicNum(n);
if (musicPlayer.isPlaying()) musicPlayer.playMusic();
else setTitle();
} else {
n = 0;//1曲目を指定
musicPlayer.setMusicNum(n);
if (musicPlayer.isPlaying()) musicPlayer.playMusic();
else setTitle();
}
}
//再生
public void onClickStart(View view) {
if (!musicPlayer.isPlaying()){
//停止中にlistViewで曲変更した場合
if (musicPlayer.getMusicNum() != listPosition) {
musicPlayer.setMusicNum(listPosition);
musicPlayer.playMusic();
changeMusicFlag = false;
}
if (pauseFlag) { //一時停止中なら
musicPlayer.start();
pauseFlag = false;
} else {
musicPlayer.playMusic();
changeMusicFlag = false;
}
}
if (changeMusicFlag) { //再生中で曲選択が変わってたら。
//つまり、listViewで選択した場合です。
musicPlayer.setMusicNum(listPosition);
musicPlayer.playMusic();
changeMusicFlag = false;
}
}
//一時停止
public void onClickPause(View view) {
if (musicPlayer.isPlaying()) {
musicPlayer.pause();
pauseFlag = true; //ここのみtrueに。
}
}
//停止
public void onClickStop(View view) {
if(musicPlayer.isPlaying()) musicPlayer.stop();
else pauseFlag = false; //一時停止解除
}
//skip。これは、そのまま。
public void onClickSkip(View view) {
if(musicPlayer.isPlaying()) musicPlayer.skipMusic();
}
//タイトルをセット。
public void setTitle() {
pauseFlag = false; //一時停止解除
changeMusicFlag = true;//曲変更のお知らせ。
int n = musicPlayer.getMusicNum();
titleView.setText((n + 1) + ": " + musicList.get(n));
}
//タイトルをセット。listViewがクリックされた時用
public void setTitle(int num) {
pauseFlag = false;
changeMusicFlag = true;
titleView.setText((num + 1) + ": " + musicList.get(num));
}
}
こんな感じ↓。
まあ、アレのイメージです。
前のよりボタンを増やしすぎて、だんだんワケが分からなくなってきた。
進むとか戻るはいるのか。listViewをタッチして再生した方がいいか。
動きが変なとこもあるかも。まあ、だいたいで。
次は、また大きく変わるかも。変わらないかも。
package net.asasvata.sdmediaplayer;
import java.io.File;
import java.util.ArrayList;
import android.app.Activity;
import android.graphics.Typeface;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
public class SDMediaPlayerActivity extends Activity
implements AdapterView.OnItemClickListener {
//フィールド
private static final String SD_PATH = //SDのパス
Environment.getExternalStorageDirectory().getPath();
private static final String FILE_SEP = File.separator;//pathの区切り文字
private ArrayList<String> musicList;
private MusicPlayer musicPlayer;
private boolean pauseFlag;//一時停止の判定用
private boolean changeMusicFlag;//musicNumの変更判定用
private int listPosition;//listViewが、クリックされた時の位置を保持
private ListView listView;//ディレクトリ内の曲のリスト表示
private TextView titleView;//現在選択されている曲の表示
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
//musicListの生成と曲の追加
musicList = new ArrayList<String>();
File musicFile = new File(SD_PATH + FILE_SEP + "deepfm");
String[] musicFileList = musicFile.list();
for(String fileName : musicFileList) {
File f = new File(SD_PATH + FILE_SEP + "deepfm"
+ FILE_SEP + fileName);
if(f.isFile() && fileName.endsWith("mp3"))
musicList.add(fileName);
}
listView = (ListView)findViewById(R.id.listView);
//ArrayAdapterの生成
ArrayAdapter<String> listAdapter =
new ArrayAdapter<String>(this, R.layout.rowdata, musicList);
//listViewにlistAdapterをセット。
listView.setAdapter(listAdapter);
//クリックされた事を検知。selectedとの違いは分かってません。
listView.setOnItemClickListener(this);
//musicPlayerの引数に渡すので先に取得
titleView = (TextView)findViewById(R.id.titleView);
//musicPlayerの生成とmusicNumの取得
musicPlayer = new MusicPlayer(musicList, titleView);
//タイトルのセット。flagの初期化も。
setTitle();
}
//とりあえず。
@Override
public void onStop() {
super.onStop();
musicPlayer.stop();
}
//なぜかOverride出来ない。listViewがクリックされた時の処理。
//@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//曲の選択をするだけ。再生はしない。とりあえず。
listPosition = position;
setTitle(position);
}
//ボタンが押されたときの処理。レイアウトの右から順に。
//戻る
public void onClickBack(View view) {
int n = musicPlayer.getMusicNum() - 1;//とりあえず減らす
if (n < 0) {
n = musicList.size() - 1;//最後の曲を指定
musicPlayer.setMusicNum(n);
if (musicPlayer.isPlaying()) musicPlayer.playMusic();
else setTitle();
} else {
musicPlayer.setMusicNum(n);
if (musicPlayer.isPlaying()) musicPlayer.playMusic();
else setTitle();
}
}
//進む
public void onClickNext(View view) {
int n = musicPlayer.getMusicNum() + 1;//とりあえず増やす。
if (n < musicList.size()) {
musicPlayer.setMusicNum(n);
if (musicPlayer.isPlaying()) musicPlayer.playMusic();
else setTitle();
} else {
n = 0;//1曲目を指定
musicPlayer.setMusicNum(n);
if (musicPlayer.isPlaying()) musicPlayer.playMusic();
else setTitle();
}
}
//再生
public void onClickStart(View view) {
if (!musicPlayer.isPlaying()){
//停止中にlistViewで曲変更した場合
if (musicPlayer.getMusicNum() != listPosition) {
musicPlayer.setMusicNum(listPosition);
musicPlayer.playMusic();
changeMusicFlag = false;
}
if (pauseFlag) { //一時停止中なら
musicPlayer.start();
pauseFlag = false;
} else {
musicPlayer.playMusic();
changeMusicFlag = false;
}
}
if (changeMusicFlag) { //再生中で曲選択が変わってたら。
//つまり、listViewで選択した場合です。
musicPlayer.setMusicNum(listPosition);
musicPlayer.playMusic();
changeMusicFlag = false;
}
}
//一時停止
public void onClickPause(View view) {
if (musicPlayer.isPlaying()) {
musicPlayer.pause();
pauseFlag = true; //ここのみtrueに。
}
}
//停止
public void onClickStop(View view) {
if(musicPlayer.isPlaying()) musicPlayer.stop();
else pauseFlag = false; //一時停止解除
}
//skip。これは、そのまま。
public void onClickSkip(View view) {
if(musicPlayer.isPlaying()) musicPlayer.skipMusic();
}
//タイトルをセット。
public void setTitle() {
pauseFlag = false; //一時停止解除
changeMusicFlag = true;//曲変更のお知らせ。
int n = musicPlayer.getMusicNum();
titleView.setText((n + 1) + ": " + musicList.get(n));
}
//タイトルをセット。listViewがクリックされた時用
public void setTitle(int num) {
pauseFlag = false;
changeMusicFlag = true;
titleView.setText((num + 1) + ": " + musicList.get(num));
}
}
こんな感じ↓。
まあ、アレのイメージです。
前のよりボタンを増やしすぎて、だんだんワケが分からなくなってきた。
進むとか戻るはいるのか。listViewをタッチして再生した方がいいか。
動きが変なとこもあるかも。まあ、だいたいで。
次は、また大きく変わるかも。変わらないかも。
mediaplayerを作ってみる(6)-1
今更ですが、target は Android1.6です。
かなり変更してしまいました。2回に分けて載せときます。
とりあえず、string.xmlから。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">SDMP</string>
<string name="back_button">戻る</string>
<string name="next_button">進む</string>
<string name="start_button">再生</string>
<string name="pause_button">一時停止</string>
<string name="stop_button">停止</string>
<string name="skip_button">skip</string>
<color name="violet">#400a40</color>
<color name="black">#010101</color>
<color name="green">#40e91f</color>
<color name="red">#b00a0a</color>
</resources>
ボタンが増えて、色も変えてます。
次は、main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@color/violet">
<TextView
android:id="@+id/titleView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="16sp"
android:background="@color/black"
android:textColor="@color/red">
</TextView>
<ListView
android:id="@+id/listView"
android:layout_width="fill_parent"
android:layout_height="240dp">
</ListView>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="30dp"
android:background="@color/red">
<Button
android:id="@+id/backButton"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_weight="1"
android:gravity="center"
android:background="@color/black"
android:textColor="@color/red"
android:text="@string/back_button"
android:onClick="onClickBack">
</Button>
<Button
android:id="@+id/nextButton"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_weight="1"
android:gravity="center"
android:background="@color/black"
android:textColor="@color/red"
android:text="@string/next_button"
android:onClick="onClickNext">
</Button>
<Button
android:id="@+id/startButton"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_weight="2"
android:background="@color/black"
android:textColor="@color/red"
android:text="@string/start_button"
android:onClick="onClickStart">
</Button>
<Button
android:id="@+id/pauseButton"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_weight="1"
android:background="@color/black"
android:textColor="@color/red"
android:text="@string/pause_button"
android:onClick="onClickPause">
</Button>
<Button
android:id="@+id/stopButton"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_weight="1"
android:gravity="center"
android:background="@color/black"
android:textColor="@color/red"
android:text="@string/stop_button"
android:onClick="onClickStop">
</Button>
</LinearLayout>
<Button
android:id="@+id/skipButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/skip_button"
android:onClick="onClickSkip">
</Button>
</LinearLayout>
色と文字の配置が増えてます。前作ってたのより増えてる。色々。
次は、ListViewのレイアウト rowdata.xml。 res/layoutの下に配置。
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/textView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="@color/green">
</TextView>
ほぼ、javadrive。
次は、MusicPlayer classを載せときます。
package net.asasvata.sdmediaplayer;
import java.io.File;
import java.util.ArrayList;
import android.media.MediaPlayer;
import android.os.Environment;
import android.util.Log;
import android.widget.TextView;
public class MusicPlayer extends MediaPlayer
implements MediaPlayer.OnCompletionListener {
private static final String SD_PATH = //SDのパス
Environment.getExternalStorageDirectory().getPath();
private static final String FILE_SEP = File.separator;//pathの区切り文字
private ArrayList<String> musicList;
private int musicNum;
private TextView titleView;//タイトル表示用
//引数にTextView追加。
public MusicPlayer(ArrayList<String> list, TextView tv) {
super();
this.musicList = list;
titleView = tv;
musicNum = 0;
super.setOnCompletionListener(this);
}
public int getMusicNum() {
return musicNum;
}
public void setMusicNum(int num) {
musicNum = num;
}
//音楽ファイルのパスを取得してスタート。
public void playMusic() {
super.stop();
super.reset();//これが要る様だ。
setTitle();
try{
super.setDataSource(SD_PATH + FILE_SEP + "deepfm"
+ FILE_SEP + musicList.get(musicNum));
super.prepare();
super.seekTo(0);
super.start();
} catch (Exception e) {
Log.v("playMusic", "" + e);//なんとなく変更。
}
}
//残り3秒まで飛びます。
public void skipMusic() {
int duration = super.getDuration();
super.seekTo(duration - 3000);
}
//曲が終わったときの処理
public void onCompletion(MediaPlayer mp) {
if (++musicNum < musicList.size()) {
playMusic();
} else {
musicNum = 0;
playMusic();
}
}
//タイトルをセット。
public void setTitle() {
titleView.setText((musicNum + 1) + ": " + musicList.get(musicNum));
}
}
次の回へ。
かなり変更してしまいました。2回に分けて載せときます。
とりあえず、string.xmlから。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">SDMP</string>
<string name="back_button">戻る</string>
<string name="next_button">進む</string>
<string name="start_button">再生</string>
<string name="pause_button">一時停止</string>
<string name="stop_button">停止</string>
<string name="skip_button">skip</string>
<color name="violet">#400a40</color>
<color name="black">#010101</color>
<color name="green">#40e91f</color>
<color name="red">#b00a0a</color>
</resources>
ボタンが増えて、色も変えてます。
次は、main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@color/violet">
<TextView
android:id="@+id/titleView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="16sp"
android:background="@color/black"
android:textColor="@color/red">
</TextView>
<ListView
android:id="@+id/listView"
android:layout_width="fill_parent"
android:layout_height="240dp">
</ListView>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="30dp"
android:background="@color/red">
<Button
android:id="@+id/backButton"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_weight="1"
android:gravity="center"
android:background="@color/black"
android:textColor="@color/red"
android:text="@string/back_button"
android:onClick="onClickBack">
</Button>
<Button
android:id="@+id/nextButton"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_weight="1"
android:gravity="center"
android:background="@color/black"
android:textColor="@color/red"
android:text="@string/next_button"
android:onClick="onClickNext">
</Button>
<Button
android:id="@+id/startButton"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_weight="2"
android:background="@color/black"
android:textColor="@color/red"
android:text="@string/start_button"
android:onClick="onClickStart">
</Button>
<Button
android:id="@+id/pauseButton"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_weight="1"
android:background="@color/black"
android:textColor="@color/red"
android:text="@string/pause_button"
android:onClick="onClickPause">
</Button>
<Button
android:id="@+id/stopButton"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_weight="1"
android:gravity="center"
android:background="@color/black"
android:textColor="@color/red"
android:text="@string/stop_button"
android:onClick="onClickStop">
</Button>
</LinearLayout>
<Button
android:id="@+id/skipButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/skip_button"
android:onClick="onClickSkip">
</Button>
</LinearLayout>
色と文字の配置が増えてます。前作ってたのより増えてる。色々。
次は、ListViewのレイアウト rowdata.xml。 res/layoutの下に配置。
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/textView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="@color/green">
</TextView>
ほぼ、javadrive。
次は、MusicPlayer classを載せときます。
package net.asasvata.sdmediaplayer;
import java.io.File;
import java.util.ArrayList;
import android.media.MediaPlayer;
import android.os.Environment;
import android.util.Log;
import android.widget.TextView;
public class MusicPlayer extends MediaPlayer
implements MediaPlayer.OnCompletionListener {
private static final String SD_PATH = //SDのパス
Environment.getExternalStorageDirectory().getPath();
private static final String FILE_SEP = File.separator;//pathの区切り文字
private ArrayList<String> musicList;
private int musicNum;
private TextView titleView;//タイトル表示用
//引数にTextView追加。
public MusicPlayer(ArrayList<String> list, TextView tv) {
super();
this.musicList = list;
titleView = tv;
musicNum = 0;
super.setOnCompletionListener(this);
}
public int getMusicNum() {
return musicNum;
}
public void setMusicNum(int num) {
musicNum = num;
}
//音楽ファイルのパスを取得してスタート。
public void playMusic() {
super.stop();
super.reset();//これが要る様だ。
setTitle();
try{
super.setDataSource(SD_PATH + FILE_SEP + "deepfm"
+ FILE_SEP + musicList.get(musicNum));
super.prepare();
super.seekTo(0);
super.start();
} catch (Exception e) {
Log.v("playMusic", "" + e);//なんとなく変更。
}
}
//残り3秒まで飛びます。
public void skipMusic() {
int duration = super.getDuration();
super.seekTo(duration - 3000);
}
//曲が終わったときの処理
public void onCompletion(MediaPlayer mp) {
if (++musicNum < musicList.size()) {
playMusic();
} else {
musicNum = 0;
playMusic();
}
}
//タイトルをセット。
public void setTitle() {
titleView.setText((musicNum + 1) + ": " + musicList.get(musicNum));
}
}
次の回へ。
2010-11-27
mediaplayerを作ってみる(5)
ちょっとおかしな事に気づきました。
MusicPlayer class。 MediaPlayerを継承してる意味がない。
外してもいいですが、本来意図していた方向に。
フィールドのmediaPlayerを削除
コンストラクタの mediaPlayer = new MediaPlayer(); 削除
後は、mediaPlayer をひたすら super に変更。
isPlayMusic() 削除。
stopMusic() も削除。
SDMediaPlayerの方は、ついでに地味に変更しときます。
(2)でこれの方がいいかもと書いた、xmlでonClickを書いとくのを。
android:onClick="onClickStart"
android:onClick="onClickStop"
android:onClick="onClickSkip"
を、それぞれxmlに追加。
で、SDMediaPlayerのimplements View.OnClickListener削除。
フィールドの
private Button btnStart;
private Button btnStop;
private Button btnSkip;
も、削除。さらに、onCreate内の
//ボタンの取得
btnStart = (Button)findViewById(R.id.start_button);
btnStop = (Button)findViewById(R.id.stop_button);
btnSkip = (Button)findViewById(R.id.skip_button);
//OnClickListenerのセット
btnStart.setOnClickListener(this);
btnStop.setOnClickListener(this);
btnSkip.setOnClickListener(this);
も削除。で、onClickも削除して、
//ボタンが押されたときの処理
public void onClickStart(View view) {
musicNum = musicPlayer.getMusicNum();
if (musicPlayer.isPlaying()) {
if (++musicNum < musicList.size()) {
musicPlayer.setMusicNum(musicNum);
musicPlayer.playMusic();
} else {
musicPlayer.setMusicNum(0);
musicPlayer.playMusic();
}
} else {
musicPlayer.playMusic();
}
}
public void onClickStop(View view) {
if(musicPlayer.isPlaying()) musicPlayer.stop();
}
public void onClickSkip(View view) {
if(musicPlayer.isPlaying()) musicPlayer.skipMusic();
}
に、変更。ボタン一個一個ばらばら。良いのか悪いのか。
まあ、とりあえず。
一度作ったとはいえ、行き当たりばったりは変わらず。
ふらふら、ふらふら。
後、結構重要な事を書くのを忘れてました。
Android Manifestのactivityのとこを、
<activity android:name=".SDMediaPlayerActivity"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:configChanges="orientation|keyboardHidden">
こんな感じに、下2行追加しておくと、縦画面固定で
横にしても音楽が、かかりっぱなしの暴走をしなくなります。
ここに 書いてました。わたくし、is01なので、keyboardHiddenをつけてます。
これは、もう少し見つけやすいとこに書いといた方が良かったかも。
次回の先頭につけときます。
ただ、他で見たときは、お勧めしない見たいなことが書いてあったような気が。
まあ、ね。
次回は、大きく変更予定。主に、見た目を。
MusicPlayer class。 MediaPlayerを継承してる意味がない。
外してもいいですが、本来意図していた方向に。
フィールドのmediaPlayerを削除
コンストラクタの mediaPlayer = new MediaPlayer(); 削除
後は、mediaPlayer をひたすら super に変更。
isPlayMusic() 削除。
stopMusic() も削除。
SDMediaPlayerの方は、ついでに地味に変更しときます。
(2)でこれの方がいいかもと書いた、xmlでonClickを書いとくのを。
android:onClick="onClickStart"
android:onClick="onClickStop"
android:onClick="onClickSkip"
を、それぞれxmlに追加。
で、SDMediaPlayerのimplements View.OnClickListener削除。
フィールドの
private Button btnStart;
private Button btnStop;
private Button btnSkip;
も、削除。さらに、onCreate内の
//ボタンの取得
btnStart = (Button)findViewById(R.id.start_button);
btnStop = (Button)findViewById(R.id.stop_button);
btnSkip = (Button)findViewById(R.id.skip_button);
//OnClickListenerのセット
btnStart.setOnClickListener(this);
btnStop.setOnClickListener(this);
btnSkip.setOnClickListener(this);
も削除。で、onClickも削除して、
//ボタンが押されたときの処理
public void onClickStart(View view) {
musicNum = musicPlayer.getMusicNum();
if (musicPlayer.isPlaying()) {
if (++musicNum < musicList.size()) {
musicPlayer.setMusicNum(musicNum);
musicPlayer.playMusic();
} else {
musicPlayer.setMusicNum(0);
musicPlayer.playMusic();
}
} else {
musicPlayer.playMusic();
}
}
public void onClickStop(View view) {
if(musicPlayer.isPlaying()) musicPlayer.stop();
}
public void onClickSkip(View view) {
if(musicPlayer.isPlaying()) musicPlayer.skipMusic();
}
に、変更。ボタン一個一個ばらばら。良いのか悪いのか。
まあ、とりあえず。
一度作ったとはいえ、行き当たりばったりは変わらず。
ふらふら、ふらふら。
後、結構重要な事を書くのを忘れてました。
Android Manifestのactivityのとこを、
<activity android:name=".SDMediaPlayerActivity"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:configChanges="orientation|keyboardHidden">
こんな感じに、下2行追加しておくと、縦画面固定で
横にしても音楽が、かかりっぱなしの暴走をしなくなります。
ここに 書いてました。わたくし、is01なので、keyboardHiddenをつけてます。
これは、もう少し見つけやすいとこに書いといた方が良かったかも。
次回の先頭につけときます。
ただ、他で見たときは、お勧めしない見たいなことが書いてあったような気が。
まあ、ね。
次回は、大きく変更予定。主に、見た目を。
2010-11-26
mediaplayerを作ってみる(4)
今回の変更は、SDのディレクトリから音楽ファイルを読み込むように
してみました。といっても、1個のディレクトリからですが。
とりあえず、フィールドにこんなのを↓追加
private static final String SD_PATH = //SDのパス
Environment.getExternalStorageDirectory().getPath();
private static final String FILE_SEP = File.separator;//pathの区切り文字
まあ、何となく。やってみました。
で、用意したディレクトリがdeepfm。これを使って
//musicListの生成と曲の追加
musicList = new ArrayList<String>();
File musicFile = new File(SD_PATH + FILE_SEP + "deepfm");
String[] musicFileList = musicFile.list();
for(String fileName : musicFileList) {
File f = new File(SD_PATH + FILE_SEP + "deepfm"
+ FILE_SEP + fileName);
if(f.isFile() && fileName.endsWith("mp3"))
musicList.add(fileName);
}
んな感じ。MusicPlayerの方もちょっと変更。フィールドに
private static final String SD_PATH = //SDのパス
Environment.getExternalStorageDirectory().getPath();
private static final String FILE_SEP = File.separator;//pathの区切り文字
同じ物を追加。static final。なんか響きが気に入ってて。
で、mediaPlayerに曲のパスをセットするとこを
mediaPlayer.setDataSource(SD_PATH + FILE_SEP + "deepfm"
+ FILE_SEP + musicList.get(musicNum));
それだけ。次もまた、地味に変更予定。
してみました。といっても、1個のディレクトリからですが。
とりあえず、フィールドにこんなのを↓追加
private static final String SD_PATH = //SDのパス
Environment.getExternalStorageDirectory().getPath();
private static final String FILE_SEP = File.separator;//pathの区切り文字
まあ、何となく。やってみました。
で、用意したディレクトリがdeepfm。これを使って
//musicListの生成と曲の追加
musicList = new ArrayList<String>();
File musicFile = new File(SD_PATH + FILE_SEP + "deepfm");
String[] musicFileList = musicFile.list();
for(String fileName : musicFileList) {
File f = new File(SD_PATH + FILE_SEP + "deepfm"
+ FILE_SEP + fileName);
if(f.isFile() && fileName.endsWith("mp3"))
musicList.add(fileName);
}
んな感じ。MusicPlayerの方もちょっと変更。フィールドに
private static final String SD_PATH = //SDのパス
Environment.getExternalStorageDirectory().getPath();
private static final String FILE_SEP = File.separator;//pathの区切り文字
同じ物を追加。static final。なんか響きが気に入ってて。
で、mediaPlayerに曲のパスをセットするとこを
mediaPlayer.setDataSource(SD_PATH + FILE_SEP + "deepfm"
+ FILE_SEP + musicList.get(musicNum));
それだけ。次もまた、地味に変更予定。
2010-11-25
mediaplayerを作ってみる(3)
前回のまま続けると、また同じ事になりそうなので新しくclassを作って分離。
MusicPlayer class。見たままです。貼っときます。
package net.asasvata.sdmediaplayer;
import java.util.ArrayList;
import android.media.MediaPlayer;
import android.os.Environment;
public class MusicPlayer extends MediaPlayer
implements MediaPlayer.OnCompletionListener {
private MediaPlayer mediaPlayer;
private ArrayList<String> musicList;
private int musicNum;
public MusicPlayer(ArrayList<String> list) {
this.musicList = list;
musicNum = 0;
//mediaPlayerの生成と曲が終わったときの処理の準備
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnCompletionListener(this);
}
public int getMusicNum() {
return musicNum;
}
public void setMusicNum(int num) {
musicNum = num;
}
//音楽ファイルのパスを取得してスタート。
public void playMusic() {
mediaPlayer.reset();//これが要る様だ。
try{
mediaPlayer.setDataSource(Environment.getExternalStorageDirectory().getPath()
+ "/" + musicList.get(musicNum));
mediaPlayer.prepare();
mediaPlayer.seekTo(0);
mediaPlayer.start();
} catch (Exception e) {
System.exit(-1);
}
}
public void stopMusic() {
mediaPlayer.stop();
try {
mediaPlayer.prepare();
} catch (Exception e) {
System.exit(-1);
}
}
//残り3秒まで飛びます。
public void skipMusic() {
int duration = mediaPlayer.getDuration();
mediaPlayer.seekTo(duration - 3000);
}
//getterを作ってもいいんですが、何となく。
public boolean isPlayMusic() {
return mediaPlayer.isPlaying();
}
//曲が終わったときの処理
public void onCompletion(MediaPlayer mp) {
if (++musicNum < musicList.size()) {
playMusic();
} else {
musicNum = 0;
playMusic();
}
}
}
SDMediaPlayerActivityの方は
//mpの生成以下の3行削除で、
//musicPlayerの生成とmusicNumの取得
musicPlayer = new MusicPlayer(musicList);
musicNum = musicPlayer.getMusicNum();
↑を追加。後は、onClickを
public void onClick(View view) {
musicNum = musicPlayer.getMusicNum();
if (musicPlayer.isPlayMusic()) {
if (view == btnStart) {
if (++musicNum < musicList.size()) {
musicPlayer.setMusicNum(musicNum);
musicPlayer.playMusic();
} else {
musicPlayer.setMusicNum(0);
musicPlayer.playMusic();
}
}
else if (view == btnStop) musicPlayer.stopMusic();
else if (view == btnSkip) musicPlayer.skipMusic();
} else {
if (view == btnStart) musicPlayer.playMusic();
}
}
んな感じに変更。 動きに変化はありません。が、何となくすっきり。
したと思いたい。
次は、またちょっとだけ変更予定。
MusicPlayer class。見たままです。貼っときます。
package net.asasvata.sdmediaplayer;
import java.util.ArrayList;
import android.media.MediaPlayer;
import android.os.Environment;
public class MusicPlayer extends MediaPlayer
implements MediaPlayer.OnCompletionListener {
private MediaPlayer mediaPlayer;
private ArrayList<String> musicList;
private int musicNum;
public MusicPlayer(ArrayList<String> list) {
this.musicList = list;
musicNum = 0;
//mediaPlayerの生成と曲が終わったときの処理の準備
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnCompletionListener(this);
}
public int getMusicNum() {
return musicNum;
}
public void setMusicNum(int num) {
musicNum = num;
}
//音楽ファイルのパスを取得してスタート。
public void playMusic() {
mediaPlayer.reset();//これが要る様だ。
try{
mediaPlayer.setDataSource(Environment.getExternalStorageDirectory().getPath()
+ "/" + musicList.get(musicNum));
mediaPlayer.prepare();
mediaPlayer.seekTo(0);
mediaPlayer.start();
} catch (Exception e) {
System.exit(-1);
}
}
public void stopMusic() {
mediaPlayer.stop();
try {
mediaPlayer.prepare();
} catch (Exception e) {
System.exit(-1);
}
}
//残り3秒まで飛びます。
public void skipMusic() {
int duration = mediaPlayer.getDuration();
mediaPlayer.seekTo(duration - 3000);
}
//getterを作ってもいいんですが、何となく。
public boolean isPlayMusic() {
return mediaPlayer.isPlaying();
}
//曲が終わったときの処理
public void onCompletion(MediaPlayer mp) {
if (++musicNum < musicList.size()) {
playMusic();
} else {
musicNum = 0;
playMusic();
}
}
}
SDMediaPlayerActivityの方は
//mpの生成以下の3行削除で、
//musicPlayerの生成とmusicNumの取得
musicPlayer = new MusicPlayer(musicList);
musicNum = musicPlayer.getMusicNum();
↑を追加。後は、onClickを
public void onClick(View view) {
musicNum = musicPlayer.getMusicNum();
if (musicPlayer.isPlayMusic()) {
if (view == btnStart) {
if (++musicNum < musicList.size()) {
musicPlayer.setMusicNum(musicNum);
musicPlayer.playMusic();
} else {
musicPlayer.setMusicNum(0);
musicPlayer.playMusic();
}
}
else if (view == btnStop) musicPlayer.stopMusic();
else if (view == btnSkip) musicPlayer.skipMusic();
} else {
if (view == btnStart) musicPlayer.playMusic();
}
}
んな感じに変更。 動きに変化はありません。が、何となくすっきり。
したと思いたい。
次は、またちょっとだけ変更予定。
2010-11-24
mediaplayerを作ってみる(2)
そういえば、一応目標を。と言うか、理想の完成形を。
1・・・SDカードのいくつかのディレクトリから音楽ファイルを読み込む。
2・・・ListViewに表示する。
3・・・ListViewをタッチすると音楽が聴ける。
4・・・ディレクトリ内で連続再生 。
5・・・ディレクトリをまたいで連続再生。
6・・・ランダム再生。
こんな感じ。
前回のでは、曲が終わると止まってしまう。
まず、これを何とかしようと。ここなどを参考に。(ちょっと下の方)
OnCompletionListenerとやらで、何とかなりそう。
変更点だけ書いていきます。
フィールドの
private static int num = 0; を private int musicNum; に
なんかこの方が良さそうなので。
implementsに MediaPlayer.OnCompletionListener を追加。
//mpの生成 のとこを
mp = new MediaPlayer();
mp.setOnCompletionListener(this); //ここと
musicNum = 0; //ここを追加
で、一番下に
public void onCompletion(MediaPlayer mp) {
if (++musicNum < musicList.size()) playMusic();
else {
musicNum = 0;
playMusic();
}
}
を追加。
で、このままだと1曲終わるまで動きが確認できないのでボタンを1つ追加。
<Button
android:id="@+id/skip_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/skip_button">
</Button>
ボタンのテキストをstringに追加。
<string name="skip_button">skip</string>
なんか英語。あってるんだろうか。英語力がないのが残念。
で、↓を追加。他のボタンの下あたりに適当に。
btnSkip = (Button)findViewById(R.id.skip_button);
btnSkip.setOnClickListener(this);
この書き方でなく、ここを参考にして書き直したほうがいいかも。
僕は、まあ、そのうち。
それと、ボタンイベントを追加。btnStopの次に。(else ifの { の閉じた後)
} else if (view == btnSkip) {
int duration = mp.getDuration();
mp.seekTo(duration - 3000);
}
これで、残り3秒まで飛びます。続けて再生してるか確認しやすい。
最近気づきました。
実は一度、完成形間近まで作ったんですが、コードが読みにくいし、
ちょっと行き詰まったので、ここに書きながら作り直してます。
まあ、それはそれで動いてるんですが。あまり色々操作をしなければ。
例の8円運用 is01に 取り込んでみて、今もそれで音楽を聴いてます。
でもねー、なんかねー、と言う感じなんですわ。色々と。
なので、あせらず急がず。ちょとづつ。なるべく、読みやすく。
いつか、完成するんだろうか。しないかも。
まあ、それはそれで。
1・・・SDカードのいくつかのディレクトリから音楽ファイルを読み込む。
2・・・ListViewに表示する。
3・・・ListViewをタッチすると音楽が聴ける。
4・・・ディレクトリ内で連続再生 。
5・・・ディレクトリをまたいで連続再生。
6・・・ランダム再生。
こんな感じ。
前回のでは、曲が終わると止まってしまう。
まず、これを何とかしようと。ここなどを参考に。(ちょっと下の方)
OnCompletionListenerとやらで、何とかなりそう。
変更点だけ書いていきます。
フィールドの
private static int num = 0; を private int musicNum; に
なんかこの方が良さそうなので。
implementsに MediaPlayer.OnCompletionListener を追加。
//mpの生成 のとこを
mp = new MediaPlayer();
mp.setOnCompletionListener(this); //ここと
musicNum = 0; //ここを追加
で、一番下に
public void onCompletion(MediaPlayer mp) {
if (++musicNum < musicList.size()) playMusic();
else {
musicNum = 0;
playMusic();
}
}
を追加。
で、このままだと1曲終わるまで動きが確認できないのでボタンを1つ追加。
<Button
android:id="@+id/skip_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/skip_button">
</Button>
ボタンのテキストをstringに追加。
<string name="skip_button">skip</string>
なんか英語。あってるんだろうか。英語力がないのが残念。
で、↓を追加。他のボタンの下あたりに適当に。
btnSkip = (Button)findViewById(R.id.skip_button);
btnSkip.setOnClickListener(this);
この書き方でなく、ここを参考にして書き直したほうがいいかも。
僕は、まあ、そのうち。
それと、ボタンイベントを追加。btnStopの次に。(else ifの { の閉じた後)
} else if (view == btnSkip) {
int duration = mp.getDuration();
mp.seekTo(duration - 3000);
}
これで、残り3秒まで飛びます。続けて再生してるか確認しやすい。
最近気づきました。
実は一度、完成形間近まで作ったんですが、コードが読みにくいし、
ちょっと行き詰まったので、ここに書きながら作り直してます。
まあ、それはそれで動いてるんですが。あまり色々操作をしなければ。
例の8円運用 is01に 取り込んでみて、今もそれで音楽を聴いてます。
でもねー、なんかねー、と言う感じなんですわ。色々と。
なので、あせらず急がず。ちょとづつ。なるべく、読みやすく。
いつか、完成するんだろうか。しないかも。
まあ、それはそれで。
2010-11-22
mediaplayerを作ってみる(1)
SDカードのファイルを再生する
作っています。少しづつ。まあ、どこまでいけるか分かりませんが。
とりあえず、貼っときます。
xmlから。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button
android:id="@+id/start_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/start_button">
</Button>
<Button
android:id="@+id/stop_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/stop_button">
</Button>
</LinearLayout>
ボタンが二つだけ。一応string.xmlも使ってみました。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, SDMediaPlayerActivity!</string>
<string name="app_name">SDMP</string>
<string name="start_button">再生 / 次へ</string>
<string name="stop_button">停止</string>
</resources>
HelloWorld消すの忘れてました。
で、Activity。
package net.asasvata.sdmediaplayer;
import java.util.ArrayList;
import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.Button;
public class SDMediaPlayerActivity extends Activity
implements View.OnClickListener {
//フィールド
private static int num = 0;//次の曲に進む用
private MediaPlayer mp;
private ArrayList<String> musicList;
private Button btnStart;
private Button btnStop;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//mpの生成
mp = new MediaPlayer();
//musicListの生成と曲の追加
musicList = new ArrayList<String>();
musicList.add("leavetheworldbehind.mp3");
musicList.add("onlygirl.mp3");
musicList.add("richgirl.mp3");
musicList.add("rudeboy.mp3");
musicList.add("yeahyeah.mp3");
//ボタンの取得
btnStart = (Button)findViewById(R.id.start_button);
btnStop = (Button)findViewById(R.id.stop_button);
//OnClickListenerのセット
btnStart.setOnClickListener(this);
btnStop.setOnClickListener(this);
}
//ボタンが押されたときの処理
public void onClick(View view) {
if (mp.isPlaying()) {
if (view == btnStart) {
if (++num < musicList.size()) {
playMusic();
} else {
num = 0;
playMusic();
}
} else if (view == btnStop) {
mp.stop();
try {
mp.prepare();
} catch (Exception e){
}
}
} else {
if (view == btnStart) {
playMusic();
}
}
}
public void playMusic() {
mp.reset();
try{
mp.setDataSource(Environment.getExternalStorageDirectory().getPath()
+ "/" + musicList.get(num));
mp.prepare();
mp.seekTo(0);
mp.start();
} catch (Exception e) {
}
}
}
Environment.getExternalStorageDirectory().getPath()
↑で、SDのパスが得られるようです。"/sdcard"でもいける様ですが。
こっちの方が確実みたいなので。
ボタンを押したときの動きは見たままです。
とりあえず、sdの音楽は再生できます。
エミュレーターのsdにファイルを入れるやり方はここを参考に。
sdのパスの取りかたも。
なんか疲れました。
作っています。少しづつ。まあ、どこまでいけるか分かりませんが。
とりあえず、貼っときます。
xmlから。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button
android:id="@+id/start_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/start_button">
</Button>
<Button
android:id="@+id/stop_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/stop_button">
</Button>
</LinearLayout>
ボタンが二つだけ。一応string.xmlも使ってみました。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, SDMediaPlayerActivity!</string>
<string name="app_name">SDMP</string>
<string name="start_button">再生 / 次へ</string>
<string name="stop_button">停止</string>
</resources>
HelloWorld消すの忘れてました。
で、Activity。
package net.asasvata.sdmediaplayer;
import java.util.ArrayList;
import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.Button;
public class SDMediaPlayerActivity extends Activity
implements View.OnClickListener {
//フィールド
private static int num = 0;//次の曲に進む用
private MediaPlayer mp;
private ArrayList<String> musicList;
private Button btnStart;
private Button btnStop;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//mpの生成
mp = new MediaPlayer();
//musicListの生成と曲の追加
musicList = new ArrayList<String>();
musicList.add("leavetheworldbehind.mp3");
musicList.add("onlygirl.mp3");
musicList.add("richgirl.mp3");
musicList.add("rudeboy.mp3");
musicList.add("yeahyeah.mp3");
//ボタンの取得
btnStart = (Button)findViewById(R.id.start_button);
btnStop = (Button)findViewById(R.id.stop_button);
//OnClickListenerのセット
btnStart.setOnClickListener(this);
btnStop.setOnClickListener(this);
}
//ボタンが押されたときの処理
public void onClick(View view) {
if (mp.isPlaying()) {
if (view == btnStart) {
if (++num < musicList.size()) {
playMusic();
} else {
num = 0;
playMusic();
}
} else if (view == btnStop) {
mp.stop();
try {
mp.prepare();
} catch (Exception e){
}
}
} else {
if (view == btnStart) {
playMusic();
}
}
}
public void playMusic() {
mp.reset();
try{
mp.setDataSource(Environment.getExternalStorageDirectory().getPath()
+ "/" + musicList.get(num));
mp.prepare();
mp.seekTo(0);
mp.start();
} catch (Exception e) {
}
}
}
Environment.getExternalStorageDirectory().getPath()
↑で、SDのパスが得られるようです。"/sdcard"でもいける様ですが。
こっちの方が確実みたいなので。
ボタンを押したときの動きは見たままです。
とりあえず、sdの音楽は再生できます。
エミュレーターのsdにファイルを入れるやり方はここを参考に。
sdのパスの取りかたも。
なんか疲れました。
2010-11-20
自作Viewをレイアウトに追加
seesaaから、移動。
自作Viewの貼り付けについては、ここを参考に。
で、本に乗ってたのを改造したのを。長いですが。
SurfaceViewなんですが、ここを見ると一手間要るようです。
が、なぜか動きます。Viewと同じやり方で。何かの参考になればいいですが。
とりあえず、xmlから。色とか文字はstring.xmlで管理するようですが
それは、まあ、そのうちに。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#00000000"
>
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#00c608"
android:textSize="12sp"
android:text="適当にボタンを押してください\n数字はフォントサイズです"
android:layout_weight="2"
/>
</LinearLayout>
<net.asasvata.SampleSurfaceView
android:id="@+id/surfaceView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#00000000"
>
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="start"
/>
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="stop"
/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#00000000"
>
<RadioGroup
android:id="@+id/radioGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_weight="1"
>
<RadioButton
android:id="@+id/radioButton0"
android:text="H"
android:textColor="#00c608"
/>
<RadioButton
android:id="@+id/radioButton1"
android:text="M"
android:textColor="#00c608"
/>
<RadioButton
android:id="@+id/radioButton2"
android:text="L"
android:textColor="#00c608"
/>
</RadioGroup>
</LinearLayout>
</LinearLayout>
パッケージ名とファイル名を指定。あとは同じようなやり方。
次は、SurfaceViewを。
package net.asasvata;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet; //これが重要みたいです。
import android.view.*;
//サーフェイスビューの利用
public class SampleSurfaceView extends SurfaceView
implements SurfaceHolder.Callback,Runnable {
private SurfaceHolder holder;//サーフェイスホルダー
private Thread thread; //スレッド
private int px = 0;//X座標
private int py = 5;//Y座標
private int vx = 0;//X速度
private int vy = 0;//Y座標
//コンストラクタ
public SampleSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
//サーフェイスホルダーの生成
holder = getHolder();
holder.addCallback(this);
holder.setFixedSize(getWidth(), getHeight());
}
//フィールドをprivateにしてみたので、ゲッター&セッター
public int getVx() {
return vx;
}
public int getVy() {
return vy;
}
public void setVx(int vx) {
this.vx = vx;
}
public void setVy(int vy) {
this.vy = vy;
}
//サーフェイスの生成
public void surfaceCreated(SurfaceHolder holder) {
//スレッドの開始
thread = new Thread(this);
thread.start();
}
//サーフェイスの変更
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
}
//サーフェイスの破棄
public void surfaceDestroyed(SurfaceHolder holder) {
thread = null;
}
//スレッドの処理
public void run() {
int i = 5;
Paint paint = new Paint();
paint.setTextSize(i);
Canvas canvas;
int j=0, k=0, l = 0;
while(thread != null) {
//ダブルバッファリング
String str = ""+i;
paint.setTextSize(i);
paint.setColor(Color.rgb(255-j, 255-k, 255-l));
canvas = holder.lockCanvas();
canvas.drawColor(Color.argb(255, j, k, l));
canvas.drawText(str, px, py, paint);
holder.unlockCanvasAndPost(canvas);
//移動
if (vx > 0) {
//文字サイズに合わせて跳ね返る位置を調整
if (getWidth()-paint.measureText(str)< px){
vx = -vx;
i += 5; j += 10; k += 20; l += 30;
if (i > 101) i = 5;
if (j > 255) j = 0;
if (k > 255) k = 0;
if (l > 255) l = 0;
}
} else {
if (px < 0) {
vx = -vx;
i += 5; j += 10; k += 20; l += 30;
if (i > 101) i = 5;
if (j > 255) j = 0;
if (k > 255) k = 0;
if (l > 255) l = 0;
}
}
if (vy < 0) {
//フォントサイズに合わせて跳ね返る位置を調整・・・のはずなんですが。
if (py < i) vy = -vy;
} else {
if (getHeight()< py) vy = -vy;
}
px += vx;
py += vy;
//スリープ
try {
Thread.sleep(50);
} catch (Exception e) {
}
}
}
}
次は、Activity。
package net.asasvata;
import android.app.Activity;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RadioGroup;
//サーフェイスビュー、テキストビュー、ボタン、ラジオボタンを使います
public class SampleActivity extends Activity implements View.OnClickListener {
SampleSurfaceView sv;
private Button button1, button2;
private RadioGroup radioGroup;
int num = 1;//ボタンを押したときの状態保持のために使います
int sp = 0;//移動速度を変更するために使います
//アプリの初期化
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
ImageView imageView = (ImageView)findViewById(R.id.imageView);
imageView.setImageBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.icon));
sv = (SampleSurfaceView)findViewById(R.id.surfaceView);
button1 = (Button)findViewById(R.id.button1);
button1.setOnClickListener(this);
button2 = (Button)findViewById(R.id.button2);
button2.setOnClickListener(this);
radioGroup =(RadioGroup)findViewById(R.id.radioGroup);
radioGroup.check(R.id.radioButton1);
}
//ボタンとラジオボタンがクリックされたときの処理
public void onClick(View view) {
//ラジオボタンが押されたときの処理
switch (radioGroup.getCheckedRadioButtonId()) {
//ラジオボタンのidによって処理を変えます
case R.id.radioButton0:
sp = 14;
//ラジオボタンが押されたときの速度方向を維持します
keepSpDir(sv);
break;
case R.id.radioButton1:
sp = 7;
keepSpDir(sv);
break;
case R.id.radioButton2:
sp = 3;
keepSpDir(sv);
break;
}
//ボタンがクリックされたときの処理
if (view == button1) {
//button1が連続して押されたとき何もしないようにしてます
if (num == 0) {
} else {
//button2が押されたときのnumの値で処理を変えます
switch (num) {
case 1:
//速度方向の維持
sv.setVx(sp); sv.setVy(sp);
num = 0;//これで連続して押されたときの処理につなげます
break;
case 2:
sv.setVx(-sp); sv.setVy(sp);
num = 0;
break;
case 3:
sv.setVx(sp); sv.setVy(-sp);
num = 0;
break;
case 4:
sv.setVx(-sp); sv.setVy(-sp);
num = 0;
break;
}
}
} else if (view == button2) {
//button2が押された時点での速度方向によってnumの値を変えます
if (sv.getVx()>0 && sv.getVy()>0) {
sv.setVx(0); sv.setVy(0);
num = 1;
} else if (sv.getVx()<0 && sv.getVy() >0) {
sv.setVx(0); sv.setVy(0);
num = 2;
} else if (sv.getVx()>0 && sv.getVy() <0) {
sv.setVx(0); sv.setVy(0);
num = 3;
} else if (sv.getVx()<0 && sv.getVy()<0) {
sv.setVx(0); sv.setVy(0);
num = 4;
}
}
}
private void keepSpDir(SampleSurfaceView sv) {
if (sv.getVx()>0 && sv.getVy()>0) {
sv.setVx(sp); sv.setVy(sp);
} else if (sv.getVx()<0 && sv.getVy() >0) {
sv.setVx(-sp); sv.setVy(sp);
} else if (sv.getVx()>0 && sv.getVy() <0) {
sv.setVx(sp); sv.setVy(-sp);
} else if (sv.getVx()<0 && sv.getVy()<0) {
sv.setVx(-sp); sv.setVy(-sp);
} else {
sv.setVx(sp); sv.setVy(sp);
}
}
}
なんかよく分からないままに改造したんで、おかしなとこもあるかも。
まあ、だいたいで。
ここだと、貼り付けたときもインデントが残る・・・。
初めからここで書いとけばよかった。
自作Viewの貼り付けについては、ここを参考に。
で、本に乗ってたのを改造したのを。長いですが。
SurfaceViewなんですが、ここを見ると一手間要るようです。
が、なぜか動きます。Viewと同じやり方で。何かの参考になればいいですが。
とりあえず、xmlから。色とか文字はstring.xmlで管理するようですが
それは、まあ、そのうちに。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#00000000"
>
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#00c608"
android:textSize="12sp"
android:text="適当にボタンを押してください\n数字はフォントサイズです"
android:layout_weight="2"
/>
</LinearLayout>
<net.asasvata.SampleSurfaceView
android:id="@+id/surfaceView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#00000000"
>
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="start"
/>
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="stop"
/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#00000000"
>
<RadioGroup
android:id="@+id/radioGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_weight="1"
>
<RadioButton
android:id="@+id/radioButton0"
android:text="H"
android:textColor="#00c608"
/>
<RadioButton
android:id="@+id/radioButton1"
android:text="M"
android:textColor="#00c608"
/>
<RadioButton
android:id="@+id/radioButton2"
android:text="L"
android:textColor="#00c608"
/>
</RadioGroup>
</LinearLayout>
</LinearLayout>
パッケージ名とファイル名を指定。あとは同じようなやり方。
次は、SurfaceViewを。
package net.asasvata;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet; //これが重要みたいです。
import android.view.*;
//サーフェイスビューの利用
public class SampleSurfaceView extends SurfaceView
implements SurfaceHolder.Callback,Runnable {
private SurfaceHolder holder;//サーフェイスホルダー
private Thread thread; //スレッド
private int px = 0;//X座標
private int py = 5;//Y座標
private int vx = 0;//X速度
private int vy = 0;//Y座標
//コンストラクタ
public SampleSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
//サーフェイスホルダーの生成
holder = getHolder();
holder.addCallback(this);
holder.setFixedSize(getWidth(), getHeight());
}
//フィールドをprivateにしてみたので、ゲッター&セッター
public int getVx() {
return vx;
}
public int getVy() {
return vy;
}
public void setVx(int vx) {
this.vx = vx;
}
public void setVy(int vy) {
this.vy = vy;
}
//サーフェイスの生成
public void surfaceCreated(SurfaceHolder holder) {
//スレッドの開始
thread = new Thread(this);
thread.start();
}
//サーフェイスの変更
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
}
//サーフェイスの破棄
public void surfaceDestroyed(SurfaceHolder holder) {
thread = null;
}
//スレッドの処理
public void run() {
int i = 5;
Paint paint = new Paint();
paint.setTextSize(i);
Canvas canvas;
int j=0, k=0, l = 0;
while(thread != null) {
//ダブルバッファリング
String str = ""+i;
paint.setTextSize(i);
paint.setColor(Color.rgb(255-j, 255-k, 255-l));
canvas = holder.lockCanvas();
canvas.drawColor(Color.argb(255, j, k, l));
canvas.drawText(str, px, py, paint);
holder.unlockCanvasAndPost(canvas);
//移動
if (vx > 0) {
//文字サイズに合わせて跳ね返る位置を調整
if (getWidth()-paint.measureText(str)< px){
vx = -vx;
i += 5; j += 10; k += 20; l += 30;
if (i > 101) i = 5;
if (j > 255) j = 0;
if (k > 255) k = 0;
if (l > 255) l = 0;
}
} else {
if (px < 0) {
vx = -vx;
i += 5; j += 10; k += 20; l += 30;
if (i > 101) i = 5;
if (j > 255) j = 0;
if (k > 255) k = 0;
if (l > 255) l = 0;
}
}
if (vy < 0) {
//フォントサイズに合わせて跳ね返る位置を調整・・・のはずなんですが。
if (py < i) vy = -vy;
} else {
if (getHeight()< py) vy = -vy;
}
px += vx;
py += vy;
//スリープ
try {
Thread.sleep(50);
} catch (Exception e) {
}
}
}
}
次は、Activity。
package net.asasvata;
import android.app.Activity;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RadioGroup;
//サーフェイスビュー、テキストビュー、ボタン、ラジオボタンを使います
public class SampleActivity extends Activity implements View.OnClickListener {
SampleSurfaceView sv;
private Button button1, button2;
private RadioGroup radioGroup;
int num = 1;//ボタンを押したときの状態保持のために使います
int sp = 0;//移動速度を変更するために使います
//アプリの初期化
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
ImageView imageView = (ImageView)findViewById(R.id.imageView);
imageView.setImageBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.icon));
sv = (SampleSurfaceView)findViewById(R.id.surfaceView);
button1 = (Button)findViewById(R.id.button1);
button1.setOnClickListener(this);
button2 = (Button)findViewById(R.id.button2);
button2.setOnClickListener(this);
radioGroup =(RadioGroup)findViewById(R.id.radioGroup);
radioGroup.check(R.id.radioButton1);
}
//ボタンとラジオボタンがクリックされたときの処理
public void onClick(View view) {
//ラジオボタンが押されたときの処理
switch (radioGroup.getCheckedRadioButtonId()) {
//ラジオボタンのidによって処理を変えます
case R.id.radioButton0:
sp = 14;
//ラジオボタンが押されたときの速度方向を維持します
keepSpDir(sv);
break;
case R.id.radioButton1:
sp = 7;
keepSpDir(sv);
break;
case R.id.radioButton2:
sp = 3;
keepSpDir(sv);
break;
}
//ボタンがクリックされたときの処理
if (view == button1) {
//button1が連続して押されたとき何もしないようにしてます
if (num == 0) {
} else {
//button2が押されたときのnumの値で処理を変えます
switch (num) {
case 1:
//速度方向の維持
sv.setVx(sp); sv.setVy(sp);
num = 0;//これで連続して押されたときの処理につなげます
break;
case 2:
sv.setVx(-sp); sv.setVy(sp);
num = 0;
break;
case 3:
sv.setVx(sp); sv.setVy(-sp);
num = 0;
break;
case 4:
sv.setVx(-sp); sv.setVy(-sp);
num = 0;
break;
}
}
} else if (view == button2) {
//button2が押された時点での速度方向によってnumの値を変えます
if (sv.getVx()>0 && sv.getVy()>0) {
sv.setVx(0); sv.setVy(0);
num = 1;
} else if (sv.getVx()<0 && sv.getVy() >0) {
sv.setVx(0); sv.setVy(0);
num = 2;
} else if (sv.getVx()>0 && sv.getVy() <0) {
sv.setVx(0); sv.setVy(0);
num = 3;
} else if (sv.getVx()<0 && sv.getVy()<0) {
sv.setVx(0); sv.setVy(0);
num = 4;
}
}
}
private void keepSpDir(SampleSurfaceView sv) {
if (sv.getVx()>0 && sv.getVy()>0) {
sv.setVx(sp); sv.setVy(sp);
} else if (sv.getVx()<0 && sv.getVy() >0) {
sv.setVx(-sp); sv.setVy(sp);
} else if (sv.getVx()>0 && sv.getVy() <0) {
sv.setVx(sp); sv.setVy(-sp);
} else if (sv.getVx()<0 && sv.getVy()<0) {
sv.setVx(-sp); sv.setVy(-sp);
} else {
sv.setVx(sp); sv.setVy(sp);
}
}
}
なんかよく分からないままに改造したんで、おかしなとこもあるかも。
まあ、だいたいで。
ここだと、貼り付けたときもインデントが残る・・・。
初めからここで書いとけばよかった。
登録:
投稿 (Atom)