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,处理不好就会冲突。

onFling()和onSingleTapUp()方法无法触发

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

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值