android课设--图片浏览音乐播放器
1.前言
作为一个Android初学者,花了4天捣腾出了这个app,功能还是蛮复杂的,特此记录一下我做的过程及遇到的问题。先来展示一下。
2.课设要求
1、用户登录注册界面:实现“注册”功能即注册一个新用户并将用户名(姓名的拼音),微信号(密码,也即学号)存储到SP中,注册后清空编辑框的内容;实现“登录”,从SP读取用户名和密码并与编辑框的内容进行比较,Toast方式提示“验证成功”。如果正确后进入“图片浏览音乐播放器主界面”。
2、图片浏览音乐播放器主界面:实现“图片显示”功能、“音乐播放”功能和“收藏”功能。
具体描述:
(1)“图片显示”功能,自选jpg、png等格式图片文件若干张,每次显示一张图片,当向左或者向右滑动屏幕的时候,可以切换一张图片显示。
(2)“音乐播放”功能,具有基本的播放/停止、上一首、下一首等按钮;可以显示歌曲长度、当前播放进度、当前播放的歌曲名称等信息;
(3)“收藏”功能,有收藏按钮,点击收藏按钮可以将当前的歌曲信息和图片信息存入到数据库中,并能够显示收藏的总数目。注意同一首歌曲和同一张图片只能收藏1次。
(4)“图片显示”功能和“音乐播放”功能的关联,当向左滑动屏幕时,在切换图片的同时、需要将音乐切换到上一首;当向右滑动屏幕时,在切换图片的同时、需要将音乐切换到下一首。当点击上一首/下一首按钮的时候,在切换音乐的同时,需要切换图片的显示。
3.实现过程
3.1.登陆注册界面
主要问题是从SP读取用户名和密码即要求不在程序中直接判断,这里我使用了SharedPreferences,利用SharedPreferences可以在本地存储信息,第二次登陆还保留有之前注册的信息。
MainActivity.java
/******************登陆界面*******************/
public class MainActivity extends ActionBarActivity {
/*0 定义账户 和密码的控件变量 定义登录按钮的控件变量*/
private Button loginBt,RegisterBt;
private EditText qqNo,qqPsw;
private static final String TAG = "MainActivity";
private String userNameValue,passwordValue,userNameTemp,passwordTemp;
private SharedPreferences sp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*1 账户 和密码的控件变量赋值 登录按钮的控件变量 赋值*/
loginBt = (Button)findViewById(R.id.login);
RegisterBt=(Button)findViewById(R.id.register);
qqNo = (EditText)findViewById(R.id.login_edit_account);
qqPsw = (EditText)findViewById(R.id.login_edit_pwd);
/*SharedPreferences实例化*/
sp = this.getSharedPreferences("userInfo", Context.MODE_PRIVATE);
/*2登录按钮添加事件响应函数*/
RegisterBt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v1) {
userNameValue=qqNo.getText().toString();
passwordValue=qqPsw.getText().toString();
if(userNameValue!=null&&!"".equals(userNameValue.trim())&&passwordValue!=null&&!"".equals(passwordValue.trim())){
/*信息存储到sp*/
SharedPreferences.Editor editor = sp.edit();
editor.putString("USER_NAME",userNameValue);
editor.putString("PASSWORD", passwordValue);
editor.commit();
Toast.makeText(getApplicationContext(), "注册成功", Toast.LENGTH_SHORT).show();
/*信息清空*/
qqNo.setText("");
qqPsw.setText("");
}else {
Toast.makeText(getApplicationContext(), "请输入完整信息", Toast.LENGTH_SHORT).show();
}
}
});
/*2登录按钮添加事件响应函数*/
loginBt.setOnClickListener(new View.OnClickListener(){
public void onClick(View v2){
userNameTemp=qqNo.getText().toString();
passwordTemp=qqPsw.getText().toString();
if(userNameTemp==null||"".equals(userNameTemp.trim())||passwordTemp==null||"".equals(passwordTemp.trim())){
Toast.makeText(getApplicationContext(), "请输入完整信息", Toast.LENGTH_SHORT).show();
}else if (userNameTemp.equals(sp.getString("USER_NAME", ""))&&passwordTemp.equals(sp.getString("PASSWORD", ""))){
Toast.makeText(getApplicationContext(), "登陆成功", Toast.LENGTH_SHORT).show();
/*3登录成功后跳转页面视图*/
Intent intent = new Intent(MainActivity.this,TabHostActivity.class);
startActivity(intent);
}else if("".equals(sp.getString("USER_NAME", ""))||"".equals(sp.getString("PASSWORD", ""))){
Toast.makeText(getApplicationContext(), "未注册,请先注册", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(getApplicationContext(), "输入错误,请重新输入", Toast.LENGTH_SHORT).show();
}
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
//getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<RelativeLayout
android:id="@+id/login_view"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_width="match_parent">
<EditText
android:layout_width="400dp"
android:layout_height="60dp"
android:inputType="textPersonName"
android:id="@+id/login_edit_account"
android:drawableLeft="@android:drawable/ic_menu_myplaces"
android:hint="请输入您的用户名"
android:layout_marginTop="20dp"
android:layout_below="@+id/logo"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<EditText
android:layout_width="400dp"
android:layout_height="60dp"
android:inputType="textPassword"
android:ems="10"
android:id="@+id/login_edit_pwd"
android:drawableLeft="@android:drawable/ic_menu_view"
android:hint="请输入您的密码"
android:layout_below="@+id/login_edit_account"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="false" />
<TextView
android:layout_width="400dp"
android:layout_height="30dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="提示:用户名及密码均为df"
android:id="@+id/textView2"
android:layout_alignParentBottom="false"
android:layout_alignParentStart="true"
android:layout_marginTop="320dp" />
<ImageView
android:id="@+id/logo"
android:layout_alignWithParentIfMissing="false"
android:background="@android:color/white"
android:layout_width="150dp"
android:layout_height="150dp"
android:src="@android:drawable/ic_menu_gallery"
android:layout_gravity="top"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
<Button
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="登录"
android:id="@+id/login"
android:onClick="finish_login"
android:background="#545bcb"
android:textSize="20dp"
android:textColor="#ffffff"
android:layout_marginEnd="53dp"
android:layout_below="@+id/login_view"
android:layout_alignParentEnd="true" />
<Button
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="注册"
android:id="@+id/register"
android:onClick="finish_login"
android:background="#545bcb"
android:textSize="20dp"
android:textColor="#ffffff"
android:layout_marginStart="45dp"
android:layout_below="@+id/login_view"
android:layout_alignParentStart="true" />
</RelativeLayout>
3.2.tabhost导航
计划一个界面播放音乐,另一个界面显示收藏信息,刚好用之前作业做过的tabhost来实现。默认显示界面为音乐播放界面。
遇到的问题:希望每次跳转到收藏信息界面都进行刷新显示,内部涉及到一个SharedPreferences需要刷新才能显示最新的收藏信息,原因在下面3.4部分会讲。但是一个activity的oncreat只能调用一次,具体原因应该与Android的生命周期有关,没有深究,总之不能重复的调用oncreat方法来刷新。
解决办法:
setContent(new Intent(this, CollectionActivity.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP))
TabHostActivity.java
public class TabHostActivity extends TabActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_tabhost);
//获取TabHost布局
TabHost tabhost = this.getTabHost();
TabHost.TabSpec spec;
Intent intent;
//加载音乐播放器
intent = new Intent().setClass(this, MusicPlayerActivity.class);
spec = tabhost.newTabSpec("music player").setIndicator("music player").setContent(intent);
tabhost.addTab(spec);
//加载收藏列表
intent = new Intent().setClass(this, CollectionActivity.class);
spec = tabhost.newTabSpec("collection").setIndicator("collection").setContent(new Intent(this, CollectionActivity.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
tabhost.addTab(spec);
//设置当前的显示页面卡
tabhost.setCurrentTab(0);
}
}
activity_tabhost.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".TabHostActivity" >
<TabHost
android:id="@android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TabWidget
android:id="@android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</TabWidget>
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="@+id/tab1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
</LinearLayout>
<LinearLayout
android:id="@+id/tab2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
</LinearLayout>
</FrameLayout>
</LinearLayout>
</TabHost>
</RelativeLayout>
3.3.音乐播放界面
分成两个部分实现:第一个是音乐播放器,使用button触发播放及下一首功能;第二个是图片滑动显示,类似探探app那种(探探的UI真的没话说),先能够滑动显示,然后再加上滑动触发播放下一首歌的功能。
3.3.1.音乐播放器的实现
做的过程中先用listview做了音乐播放器的列表显示,最后设置了invisible。音乐播放器用mediaPlayer实现的,个人觉得比MusicAdapter好用,不多说。
遇到的问题1:
seekbar.setProgress(mediaPlayer.getCurrentPosition())不成功,改为seekbar.setProgress(mediaPlayer.getCurrentPosition()*mSeekBar.getMax()/mSeekBar.getMax())后成功。进度条已拉宽度和播放器当前歌曲进度比例需一致。
遇到的问题2:
seekbar歌曲进度条的功能需求有两部分:一是手动拖动进度条,使播放器从当前位置播放并更新当前时间,这里可用进度条OnSeekBarChangeListener监听;二是实现自动更新进度条进度,要求进度条进度与播放器进度一致,实现联动,这里可用线程或者广播消息等实现。
3.3.2.图片滑动与音乐播放的关联实现
图片滑动显示有很多种方法,这里用的是ViewFlipper,其中图片是静态加载的。手势左右滑动需要添加手势控制的监听内部类,通过判断x的位置来判断左右滑动。另外还需添加左右滑动的动画,可以使视觉上感到滑动。
图片能够滑动显示后,为了实现关联,这里用了一个简单粗暴的方法:在图片向左滑动后加入切换到下一首;在切换到下一首后加入向左滑动图片。效果还不错。
遇到的问题:
GestureDetector的onFling()和onSingleTapUp()方法无法触发。
解决办法:
onDown方法return了false,导致依赖于onDown的onFling()和onSingleTapUp()方法无法被触发。return true即可。
注意:event监听方法返回true还是false是很有讲究的,多个event,处理不好就会冲突。
3.3.3.收藏功能的实现
想做成网易云那种点击红心收藏的样式,这里用ImageView切换显示红心图片。整理了一下需求:当前歌曲与收藏状态与红心图片要对应,切换歌曲后红心状态也要对应,点击红心实现收藏与取消收藏,涉及到数据库增删查。那么有下面情景:
1.点击下一首按钮,查询数据库中该歌曲收藏状态(即查询数据库中是否有该歌曲)对应设置当前ImageView的红心图片;
2.滑动至下一张图片,查询数据库中该歌曲收藏状态,对应设置当前ImageView的红心图片;
3.点击ImageView,若当前歌曲显示不红心,则添加歌曲至数据库;若当前歌曲显示红心,则将该歌曲从数据库中删除。
这样切换歌曲前后,红心状态也能随之变化,像网易云一样嘻嘻。
MusicPlayerActivity.java
主要部分代码
/*收藏功能*/
mCollectView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(song!=null&&!"".equals(song.trim())){
if (dbManager.query_one_state(song) == false) {
mCollectView.setBackgroundResource(R.drawable.like);
dbManager.insert(singer, song);
Toast.makeText(getApplicationContext(), "成功收藏" + singer + song + "!" + "\n" + "当前已收藏" + dbManager.query_num() + "首!", Toast.LENGTH_SHORT).show();
} else {
mCollectView.setBackgroundResource(R.drawable.normal);
dbManager.delete(song);
Toast.makeText(getApplicationContext(), "取消收藏" + singer + song + "!" + "\n" + "当前已收藏" + dbManager.query_num() + "首!", Toast.LENGTH_SHORT).show();
}
ExecSharedPerferenceTransfer();//收藏歌曲信息传入CollectionActivity
}else {
Toast.makeText(getApplicationContext(), "当前无播放歌曲!", Toast.LENGTH_SHORT).show();
}
}
});
}
/*将收藏信息从MusicPlayerActivity传递到CollectionActivity*/
private void ExecSharedPerferenceTransfer() {
collection_data="";
collection_data=dbManager.query();
SharedPreferences mySharedPreferences= getSharedPreferences("CollectionData", Activity.MODE_PRIVATE );
SharedPreferences.Editor editor = mySharedPreferences.edit();
editor.putString("data", collection_data);
//editor.putInt("num", dbManager.query_num());
editor.commit();
}
/*歌曲进度条监听*/
private SeekBar.OnSeekBarChangeListener sbLis=new SeekBar.OnSeekBarChangeListener(){
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
//手动调节进度
int dest = seekBar.getProgress();
int time = mediaPlayer.getDuration();
int max = seekBar.getMax();
mediaPlayer.seekTo(time*dest/max);
}
};
/*回调更新歌曲进度*/
Runnable updatesb =new Runnable(){
@Override
public void run() {
//自动更新进度,每秒钟更新一次
int position = mediaPlayer.getCurrentPosition();
int time = mediaPlayer.getDuration(); mediaPlayer.getDuration();
int max = mSeekBar.getMax();
mSeekBar.setProgress(position * max / time);
mCurrentTimeTv.setText(calculateTime(position / 1000));
handler.postDelayed(updatesb, 1000);
}
};
/*flipper图片滑动检测*/
public boolean onFling(MotionEvent e1, MotionEvent e2, float arg2,
float arg3) {
Log.i("Fling", "Fling Happened!");
if (e1.getX() - e2.getX() > 5) {
this.flipper.setInAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_left_in));
this.flipper.setOutAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_left_out));
this.flipper.showNext();
if(imgnum==5)imgnum=1;
else imgnum++;
changeMusic(++mCurrentPosition);//歌曲切换到下一首
return true;
} else if (e1.getX() - e2.getX() < -5) {
this.flipper.setInAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_right_in));
this.flipper.setOutAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_right_out));
this.flipper.showPrevious();
if(imgnum==1)imgnum=5;
else imgnum--;
changeMusic(--mCurrentPosition);//歌曲切换到上一首
return true;
}
return true;
}
/**********music player按钮事件********/
@Override
public void onClick(View view) {
if (view.getId()==R.id.mPreviousBtn){//上一曲
this.flipper.setInAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_right_in));
this.flipper.setOutAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_right_out));
this.flipper.showPrevious();//图片切换到上一张
if(imgnum==1)imgnum=5;
else imgnum--;
changeMusic(--mCurrentPosition);
}else if (view.getId()==R.id.mPlayBtn){//暂停/播放
if (is_first_start){
if(mediaPlayer.isPlaying()){//由于滑动图片或点击下一首按钮使mediaPlayer正在播放但是mPlayBtn是第一次按下
mediaPlayer.pause();
is_first_start=false;
}else {// 首次点击播放按钮,默认播放第0首
changeMusic(0);
is_first_start=false;
}
}else {
if (mediaPlayer.isPlaying()){
mediaPlayer.pause();
}else {
mediaPlayer.start();
}
}
} else if (view.getId() == R.id.mNextBtn) {// 下一首
this.flipper.setInAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_left_in));
this.flipper.setOutAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_left_out));
this.flipper.showNext();//图片切换到下一张
if(imgnum==5)imgnum=1;
else imgnum++;
changeMusic(++mCurrentPosition);
}
}
/******************切歌************************/
private void changeMusic(int position){
if (position<0){
mCurrentPosition = position =list.size()-1;
}else if (position>list.size()-1){
mCurrentPosition = position=0;
}
try {
// 切歌之前先重置,释放掉之前的资源
mediaPlayer.reset();
// 设置播放源
mediaPlayer.setDataSource(list.get(position).path);
// 开始播放前的准备工作,加载多媒体资源,
mediaPlayer.prepare();
// 开始播放
mediaPlayer.start();
//显示当前歌曲信息
singer=list.get(position).singer;
song=list.get(position).song;
song_now.setText(singer+song);
img_now.setText("img"+"<"+imgnum+">");
//根据当前歌曲收藏状态显示红心
if(dbManager.query_one_state(song)){
mCollectView.setBackgroundResource(R.drawable.like);
} else {
mCollectView.setBackgroundResource(R.drawable.normal);
}
} catch (IOException e) {
e.printStackTrace();
}
// 切歌时重置进度条并展示歌曲时长
//获取音乐总时间
int durationTotal = mediaPlayer.getDuration() / 1000;
mTotalTimeTv.setText(calculateTime(durationTotal));
//将音乐总时间设置为SeekBar的最大值
mSeekBar.setMax(durationTotal);
mSeekBar.setProgress(0);
mediaPlayer.seekTo(0);
//用一个handler更新SeekBar
handler.post(updatesb);
}
/**** 设置音量**********/
private void setVolume() {
myRegisterReceiver();//注册同步更新的广播
audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); //获取系统最大音量
mView_sb_play_volume.setMax(maxVolume);
currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC); //获取当前值
mView_sb_play_volume.setProgress(currentVolume);
mView_sb_play_volume.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress, 0);
}
});
}
/*** 注册当音量发生变化时接收的广播*/
private void myRegisterReceiver(){
MyVolumeReceiver mVolumeReceiver = new MyVolumeReceiver() ;
IntentFilter filter = new IntentFilter() ;
filter.addAction("android.media.VOLUME_CHANGED_ACTION") ;
registerReceiver(mVolumeReceiver, filter) ;
}
/*** 处理音量变化时的界面显示*/
private class MyVolumeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//如果音量发生变化则更改seekbar的位置
if(intent.getAction().equals("android.media.VOLUME_CHANGED_ACTION")){
//AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC) ;// 当前的媒体音量
mView_sb_play_volume.setProgress(currentVolume) ;
}
}
}
activity_musicplayer.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp"
tools:context=".MusicPlayerActivity">
<LinearLayout
android:orientation="horizontal"
android:id="@+id/main_textview"
android:layout_width="match_parent"
android:layout_height="40dp">
<Button
android:id="@+id/mPreviousBtn"
android:text="上一曲"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent" />
<Button
android:id="@+id/mPlayBtn"
android:text="播放/暂停"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent" />
<Button
android:id="@+id/mNextBtn"
android:text="下一曲"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:layout_marginRight="10dp" />
<ImageView
android:id="@+id/collect_state_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/normal" />
</LinearLayout>
<RelativeLayout
android:id="@+id/main_textview1"
android:layout_below="@+id/main_textview"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/current_time_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="当前时间"/>
<TextView
android:id="@+id/total_time_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="全部时间"/>
<SeekBar
android:id="@+id/seek_bar"
style="?android:progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_toLeftOf="@id/total_time_tv"
android:layout_toRightOf="@id/current_time_tv"/>
</RelativeLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="50dp"
android:id="@+id/linearLayout"
android:layout_below="@+id/main_textview1"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="当前歌曲:"
android:id="@+id/textView3" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="@+id/song_now" />
</LinearLayout>
<ListView
android:id="@+id/main_listview"
android:layout_width="match_parent"
android:layout_height="20dp"
android:cacheColorHint="#ffffff"
android:layout_below="@+id/linearLayout"
android:layout_centerHorizontal="true"
android:visibility="invisible"
android:layout_marginTop="390dp" />
<!--
<ViewFlipper
android:id="@+id/ViewFlipper1"
android:layout_width="fill_parent"
android:layout_height="230dp"
android:layout_marginTop="150dp">
</ViewFlipper>-->
<LinearLayout
android:id="@+id/layout"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginTop="150dp"
android:layout_marginBottom="70dp">
<ViewFlipper
android:id="@+id/view_flipper"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:persistentDrawingCache="animation"
android:flipInterval="1000"
android:inAnimation="@anim/push_left_in"
android:outAnimation="@anim/push_right_out">
<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<ImageView android:id="@+id/view_bg1" android:src="@drawable/wall01"
android:layout_width="fill_parent" android:layout_height="fill_parent">
</ImageView>
</LinearLayout>
<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<ImageView android:id="@+id/view_bg2" android:src="@drawable/wall02"
android:layout_width="fill_parent" android:layout_height="fill_parent">
</ImageView>
</LinearLayout>
<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<ImageView android:id="@+id/view_bg3" android:src="@drawable/wall03"
android:layout_width="fill_parent" android:layout_height="fill_parent">
</ImageView>
</LinearLayout>
<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<ImageView android:id="@+id/view_bg4" android:src="@drawable/wall04"
android:layout_width="fill_parent" android:layout_height="fill_parent">
</ImageView>
</LinearLayout>
<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<ImageView android:id="@+id/view_bg5" android:src="@drawable/wall05"
android:layout_width="fill_parent" android:layout_height="fill_parent">
</ImageView>
</LinearLayout>
</ViewFlipper>
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="@+id/img_now"
android:layout_marginBottom="48dp"
android:layout_marginLeft="270dp"
android:layout_alignParentBottom="true"
android:layout_alignEnd="@+id/layout"
android:layout_marginEnd="10dp" />
</RelativeLayout>
3.4.收藏信息界面
这个界面要求里是没有的,但是我希望做一个收藏歌曲列表。之前在音乐播放界面里点红心的歌曲存储至数据库,这里需要从数据库查询所有歌曲再显示,其实就是一个简单的数据库查询功能。界面只用了简单的TextView进行显示,后续优化可以变成ListView显示。
遇到的问题:
虽然是一个简单的数据库查询功能,然鹅此界面和音乐播放是2个activity,涉及到不同activity之间的数据传输,方法还是有很多的。
解决思路:
1.在收藏activity中对数据库操作,但是数据库在音乐activity中实例化了,不能在收藏activity对实例化的数据库对象操作。搜索过有说在同一个app中对数据库操作是可以的,获取数据库的具体path,尝试后无果;
2.在音乐activity中对数据库做查询后存储在一个String,将String通过SharedPreferences传输至收藏activity,真好用。
另外每次进入收藏activity需要对SharedPreferences刷新收藏信息,在TabHostActivity中解决了。
CollectionActivity.java
/*从sharedPreferences获取收藏信息*/
SharedPreferences sharedPreferences= getSharedPreferences("CollectionData", Activity.MODE_PRIVATE);
collection_data =sharedPreferences.getString("data", "0");
/*收藏歌曲内容显示*/
if(collection_data.length()<5){
CollectionView.setText("还未收藏歌曲哦~");
}else CollectionView.setText(collection_data);
activity_collection.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout" android:orientation="horizontal"
android:layout_width="fill_parent" android:layout_height="fill_parent"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:id="@+id/CollectionView" />
</LinearLayout>
DatabaseHelper.java
public class DatabaseHelper extends SQLiteOpenHelper{
private static String DB_NAME = "collection.db";
private static final int VERSION = 1;
private static final String SWORD="SWORD";
public DatabaseHelper(Context context) {
super(context, DB_NAME, null, VERSION);
}
//创建数据库
public void onCreate(SQLiteDatabase db) {
Log.i(SWORD,"create a Database");
//创建数据库sql语句
String sql = "create table collection(singer varchar(20),song varchar(30))";
//执行创建数据库操作
db.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//创建成功,日志输出提示
Log.i(SWORD,"update a Database");
}
}
DatabaseManager.java
public class DatabaseManager {
private DatabaseHelper helper;
private SQLiteDatabase db;
public DatabaseManager(Context context) {
helper = new DatabaseHelper(context);
db = helper.getWritableDatabase();
}
/*添加收藏歌曲*/
public void insert(String singer_now,String song_now){
//创建存放数据的ContentValues对象
ContentValues values = new ContentValues();
values.put("singer",singer_now);
values.put("song",song_now);
//数据库执行插入命令
db.insert("collection", null, values);
}
/*删除收藏歌曲*/
public void delete(String song_now){
db.delete("collection", "song=?", new String[]{song_now});
}
/*查询所有歌曲*/
public String query(){
Cursor cursor = db.query("collection", new String[]{"singer","song"}, null, null, null, null, null);
//利用游标遍历所有数据对象
//为了显示全部,把所有对象连接起来,放到TextView中
String collection_data = "";
while(cursor.moveToNext()){
String singer = cursor.getString(cursor.getColumnIndex("singer"));
String song = cursor.getString(cursor.getColumnIndex("song"));
collection_data = collection_data + "\n" +singer+" "+song;
}
cursor.close();
//textview.setText(collection_data);
return collection_data;
}
/*获取收藏歌曲数量*/
public int query_num(){
Cursor cursor = db.query("collection", new String[]{"singer","song"}, null, null, null, null, null);
//利用游标遍历所有数据对象
; int num=0;
while(cursor.moveToNext()){
num++;
}
cursor.close();
return num;
}
/*查询当前歌曲收藏状态*/
public boolean query_one_state(String songname){
boolean state;
Cursor cursor = db.rawQuery("select * from collection where song=?", new String[]{songname});
if(cursor.moveToFirst()){
cursor.close();
return true;//存在此歌曲
}
return false;//不存在
}
}
4.小结
基础不够,做个课设全程都在搜搜搜。时间不充裕,还能优化的地方有很多。TabHost里上面那个黑色阴影也暂时找不到办法去掉了,暂时先这样吧。欢迎留言讨论。
5.致谢
多谢下面这些大佬的思路,让我能够完成这个课设。
简单的音乐播放器(上一曲,下一曲,暂停/播放,自动播放下一曲)
Android 多个Activity间对象共享
android实现音乐播放器,SQLite数据库的操作
Android操作SQLite数据库(极简洁,极易懂)
rawQuery的使用
Android 记住密码和自动登录界面的实现(SharedPreferences 的用法)
ViewFlipper(翻转视图)的基本使用
Android 开发:ViewFlipper 左右滑动效果
Android 音乐播放器-带seekBar滑动
android 播放音乐-进度条
Android音乐播放器SeekBar控制音量变化的实现
Android tabHost 刷新Activity
ImageView控件的使用
…
PS:好久没登博客了,最近整理了本科的学习资料,放一下课设源码
https://download.csdn.net/download/qq_39028641/12812734