-
Android 课设 万年历源码
2018-12-05 15:09:50Android 课设 万年历源码,apk在bin目录下,源码可直接导入开发工程中,含程序截图。建议apk在模拟器中安装。好用请给5星哦~ -
Android 课设 健康饮食搭配源码
2018-12-05 14:26:12Android 课设 健康饮食搭配源码, 可直接安装apk,apk在bin目录下,含截图。(建议在模拟器中安装apk),好用记得5星哦 -
Android 课设 在线订餐项目源码(含apk)
2018-12-27 11:52:22Android 课设 在线订餐项目源码(含apk),apk在bin目录里面,含软件截图。建议在模拟器中安装运行 -
Android 课设 精美闹钟源码(含apk)
2018-12-28 11:22:01Android 课设 精美闹钟源码(含apk、含源码),apk在bin目录中,含软件截图。建议在模拟器中安装运行,好用记得给五星好评。===每一次努力,需要你的支持。 -
Android 课设 简单计算器源码(含apk)
2018-12-28 11:32:52Android 课设 简单计算器源码(含apk),apk在bin目录下,含软件截图。建议在模拟器中运行。好用给五星好评哦。===您的支持,是我最大的动力 -
Android课设之校园二手交易app
2019-06-12 16:45:49好了,这学期的Android课设基本完工了,我这次选取的是校园二手交易的主题。好了,相信大家也都等不及了,接下来直接进行演示了。代码已经上传到GitHub上,链接为https://github.com/229394/CollegeIdleApp。(如果...好了,这学期的Android课设基本完工了,我这次选取的是校园二手交易的主题。好了,相信大家也都等不及了,接下来直接进行演示了。代码已经上传到GitHub上,链接为https://github.com/229394/CollegeIdleApp。(如果觉得对你有帮助,请不要吝啬你的Star,感激不尽!)
首先介绍一下我所用的开发环境,Android Studio的版本是3.3.1,sdk的版本是28,运行的模拟器我用的是Genymotion,比它自带的模拟机要好用一点,好了,接下来运行截图如下所示。
1.登录界面
2.注册界面
3.系统首页
4.生活用品界面
5.发布商品界面
6.添加发布的商品信息
7.发布商品成功后首页
8.点击小熊,显示商品详情,不同用户可以在下面发评论。
9.点击爱心,可添加到我的收藏,长按可进行删除。
10.个人中心界面
11.个人信息初始界面
12.点击修改,修改信息如下:
13.修改成功后,跳转到个人信息界面,点击刷新即可查看。
14.我的发布商品,长按商品项可选择是否删除,点击刷新即可更新信息。
15.修改密码界面
16.关于系统简介界面
17.退出系统
好了,关于系统截图就到这里了,我做的只面向学生用户,如果感兴趣的可以再考虑加一个管理员权限进行管理学生信息以及商品信息!
-
android课设--图片浏览音乐播放器
2019-05-09 00:28:02android课设--图片浏览音乐播放器1.前言2.课设要求3.实现过程3.1.登陆注册界面MainActivity.javaactivity_main.xml3.2.tabhost导航TabHostActivity.javaactivity_tabhost.xml3.3.音乐播放界面3.3.1.音乐播放器的实现...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 -
Android课设开发日志 电影售票系统 day01
2019-05-09 09:21:37 -
Android课设开发日志 电影售票系统 day02
2019-05-22 21:33:22Android课设开发日志 电影售票系统 day02任务分配dao层service层 任务分配 dao层及service层实现(我的part) servlet 安卓页面及逻辑 dao层 dao层:dao层叫数据访问层,全称为data access object,属于一种比较...任务分配
- dao层及service层实现(我的part)
- servlet
- 安卓页面及逻辑
dao层
dao层:dao层叫数据访问层,全称为data access object,属于一种比较底层,比较基础的操作,具体到对于某个表、某个实体的增删改查。
- 工具类
DBDao
类,用于完成数据库操作的封装,其中包含三个常量,再按照操作的过程,封装了四个方法。如图所示:
变量
DRIVER
:链接数据库的驱动
URL
:数据库路径
USER
:登陆数据库的用户名
方法
getConn
:与数据库建立连接,返回数据库连接对象。
closeAll
:释放相关的资源。
operUpdate
:装配sql语句及变量,完成增删改操作。
operQuery
:装配sql语句及变量,完成查询操作。- 实体类
存放了从数据库中读取的各个表的数据内容,每张表对应一个实体类。 - Dao层接口及其实现
service层
service层:service层叫服务层,被称为服务,肯定是相比之下比较高层次的一层结构,相当于将几种操作封装起来。
-
电池电量监控(Android课设)
2018-02-08 11:36:03电池电量监控 题目描述:点一下桌面显示的小Android小机器人,可以显示电池状态、电池电量、电池健康、电池温度、电池电压等信息。 -
Android 课设-- 新闻app
2016-06-20 12:13:19利用Jsoup写的一个app去抓取腾讯新闻与网易新闻上的内容。 -
Unity3D for Android 课设
2019-09-24 08:23:39Unity 2017.1.0f3 (64-bit) + installer_r24.4.1-windows(Android SDK) + JAVA 8 一开始装Unity2018发现版本有问题,没办法build and run,Unity 2017采用Personal版本无需License激活,注册个号就能用(支持微信)。... -
影院选座app(Android课设,含数据库)
2018-02-08 11:26:081、影院选座app 题目描述:实现一个基于本地服务的影院选座软件。用户登录后可以看到所有座位的情况,选中自己想要的座位后提交。(最好以图形化的方式展示出当前座位的状态) -
Android课设----人脸识别考勤系统
2020-01-05 09:32:230.使用方法:进入/ArcSoft_ArcFace_Android_V3.0/samplecode/,该目录下放置了我项目的服务器、Android客户端、数据库源文件,自己部署就行。 1.因为这是我只花了一周时间做的人脸识别考勤课设题目,后台只使用简单的... -
Android Studio 课设图片
2020-06-17 18:24:23@TOC 哈哈哈哈 ##fdhgf -
android期末课设选题_Android课程设计报告书.doc
2020-12-19 17:41:00题目山东交通学院课程设计报告PAGE 2PAGE 1Android课程设计报告书题目:RFID药品WMS仓库管理系统院(系)别 交通与物流工程学院专 业 物联网工程专业班 级 物联132成 员 伊 华 130516234宫玮钰 130516229刘文清 ... -
android期末课设选题_大二下学期的两三事之数电实验&课设
2020-12-30 00:49:06数电实验&课设叮写在前面 这学期的数电实验老师是陈W老师。上学期的模电,选过一次他的课,线下教学,老师讲课游刃自如,点到为止,但又醍醐灌顶;这学期线上教学,可能是软件运用不熟练,他多少有些手足无措,上课... -
android期末课设选题_基于本科计算机安卓android毕业设计选题题目
2020-12-19 17:41:011.安卓android教学管理系统2.JAVA JSP学生信息管理系统3.安卓Android考勤系统设计(MySQL)4.安卓+lw+电子阅读器5.安卓+lw+电子阅读器录像6.安卓教师教学信息查询系统7.开发仓库管理系统毕业作品8.图书管理-论文-项目-... -
Android 2048——课设简单版
2020-12-21 18:59:05Android studio开发的2048简单游戏! -
android期末课设选题_基于Android的毕业设计选题系统设计与实现
2020-12-19 17:40:55基于Android的毕业设计选题系统设计与实现郁书好1,田志会1,朱成棋2,范祥林1【摘要】摘要:毕业设计是大学教学任务中最重要的实践环节,也是培养大学生综合运用大学知识解决实际问题极为重要的过程。现有毕业设计... -
android期末课设选题_计算机系毕业设计安卓选题
2021-01-26 15:05:51备注:本文章为六月雪毕业设计网xmbylw.cn/index.html所有android+web课程表android教学管理系统录像android考勤系统设计android电子阅读器android教师教学信息查询系统adroid开发仓库管理系统毕业作品andori图书... -
android期末课设选题_Java期末课程设计题目
2021-01-15 04:17:31题号一二三四五六总分总分人复分人得分一、用Java设计一个应用程序。题目如下(从如下两题中任选一题):1.(1)创建一个三维图形类Spere(球体),它实现第三章中的Shape3D接口;(2)创建一个具有缩放功能的三维球类...
-
【Python-随到随学】FLask第二周
-
JMETER 性能测试基础课程
-
SSH Shell_16.09_xclient.info.dmg
-
82
-
基于非局部先验的单幅图像去雾算法
-
网易再次下注10亿元,能在视频领域“砸”出水花吗
-
linux基础入门和项目实战部署系列课程
-
2021 PHP租车系统 毕业设计 毕设源码 源代码使用教程
-
项目管理工具与方法
-
Practice02
-
陈彧--信息学竞赛中的思维方法.rar
-
实施情感检测分类器-源码
-
【读书笔记:算法小抄】最长递增子序列——Java实现
-
序列图像运动自适应V1—MT光流估计算法
-
2021 年该学的 CSS 框架 Tailwind CSS 实战视频
-
awesome-rl:精选强化学习资源-源码
-
C++11 14 17 20 多线程从原理到线程池实战
-
automx:不建议使用此项目,而推荐使用automx2。 您可以在gitlab上找到automx2-源码
-
spring_AOP_jar.zip
-
白话:java从入门到实战