本播放器是通过Service实现自定义的MusicService完成音乐播放器的基本功能,实现了登录注册,提示用户是否注册成功或登录成功,记住用户,本地音乐搜索,进度条拖动,自动播放下一首等功能。
在main文件下新建一个assets文件夹
将音乐放入其中(mp3音乐)
通过SQLiteOpenHelper实现自定义的MyHelper完成user表的创建,通过用户输入的密码和账号在数据库进行查询,判断用户是否存在,用户的密码是否输入错误。
通过在user表的查询,判断用户是否存在,如果不存在就注册账号,注册成功自动跳转到用户登录界面,并向user表添加一条用户记录。
通过SharedPreferences记录用户的登录状态,如果checkBox被勾选了,就保存用户登录的密码和账号,下次登录,自动填写密码和账号。
通过Service实现自定义的MusicService,在MusicActivity中使用bindService将启动MusicService,使用mediaPlayer加载音乐资源并实现音乐播放、暂停、停止、继续等功能。当点击播放按钮时,默认播放列表当中的第一首歌。
为mediaPlayer设置监听器,当当前歌曲播放完毕时,自动播放下一首。
在MusicService开启一个新线程,用于向MusicActivity提供歌曲播放进度,并随时更新seekBar。通过为seekBar设置监听器,监听进度条的拖动行为。
将assets下所有歌曲的名字存入到musicName数组中,实例化一个适配器,将列表歌曲结果显示在listView上。
1.直接点击列表中的歌曲也可以播放和暂停
2.点击列表和点击播放按钮都可互相控制
使用MyHelper完成song表的创建,并保存歌曲名,获取输入框的输入,在song表进行模糊查询,将搜索结果存入musicName,并通过适配器显示在listView上。
package com.example.finaltask;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import androidx.annotation.Nullable;
public class MyHelper extends SQLiteOpenHelper {
public MyHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
String a = "create table if not exists user(" +
"id integer primary key autoincrement," +
"username varchar(20) not null," +
"password varchar(20) not null," +
"phone varchar(20) default ''," +
"address varchar(20) default '')";
db.execSQL(a);
String b = "create table if not exists song(" +
"id integer primary key autoincrement," +
"musicName varchar(20) not null)";
db.execSQL(b);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
package com.example.finaltask;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private EditText editText1,editText2;
private CheckBox checkBox;
private Button button1,button2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText1 = findViewById(R.id.editText1);
editText2 = findViewById(R.id.editText2);
checkBox = findViewById(R.id.checkBox);
button1 = findViewById(R.id.button1);
button2 = findViewById(R.id.button2);
SharedPreferences sp = getPreferences(MODE_PRIVATE);
final SharedPreferences.Editor editor = sp.edit();
editText1.setText(sp.getString("username",""));
editText2.setText(sp.getString("password",""));
//获取checkBox的勾选状态
checkBox.setChecked(sp.getBoolean("flag",false));
//登录按钮
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String username = editText1.getText().toString().trim();
String password = editText2.getText().toString().trim();
//判断用户是否输入了用户名、密码
if (!TextUtils.isEmpty(username)&&!TextUtils.isEmpty(password)){
MyHelper myHelper = new MyHelper(MainActivity.this,"musicPlayer",null,1);
SQLiteDatabase db = myHelper.getReadableDatabase();
Cursor cursor1 = db.rawQuery("select * from user where username = ?",new String[]{username});
//判断此用户是否存在
if (cursor1.moveToNext()){
Cursor cursor2 = db.rawQuery("select password from user where username = ?",new String[]{username});
cursor2.moveToNext();
//判断用户输入的密码是否正确
if (cursor2.getString(0).equals(password)){
//是否记住密码
if (checkBox.isChecked()){
editor.putString("username",username);
editor.putString("password",password);
//保存checkBox的勾选状态
editor.putBoolean("flag",checkBox.isChecked());
editor.commit();
}else {
editor.clear();
editor.commit();
}
Toast.makeText(MainActivity.this,"成功登录!",Toast.LENGTH_SHORT).show();
Intent intent = new Intent(MainActivity.this,MusicActivity.class);
startActivity(intent);
finish();
}else {
Toast.makeText(MainActivity.this,"密码错误!",Toast.LENGTH_SHORT).show();
}
}else {
Toast.makeText(MainActivity.this,"抱歉,此用户不存在,请注册!",Toast.LENGTH_SHORT).show();
}
}else {
Toast.makeText(MainActivity.this,"用户名、密码都不能为空!",Toast.LENGTH_SHORT).show();
}
}
});
//点击注册按钮,跳转到注册界面
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setClass(MainActivity.this,RegisterActivity.class);
startActivityForResult(intent,100);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode==100){
//填充用户名和密码
editText1.setText(data.getExtras().get("username")+"");
editText2.setText(data.getExtras().get("password")+"");
}
}
}
package com.example.finaltask;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class RegisterActivity extends AppCompatActivity {
private EditText editText1,editText2,editText3;
private Button button1,button2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
editText1 = findViewById(R.id.editText1);
editText2 = findViewById(R.id.editText2);
editText3 = findViewById(R.id.editText3);
button1 = findViewById(R.id.button1);
button2 = findViewById(R.id.button2);
//返回登陆页面
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(RegisterActivity.this,MainActivity.class);
startActivity(intent);
}
});
//注册
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//用户名
String username = editText1.getText().toString().trim();
//密码
String password = editText2.getText().toString().trim();
//确认密码
String rePassword = editText3.getText().toString().trim();
//判断用户名、密码、确认密码是否为空
if(!TextUtils.isEmpty(username)&&!TextUtils.isEmpty(password)&&!TextUtils.isEmpty(rePassword)) {
MyHelper myHelper = new MyHelper(RegisterActivity.this, "musicPlayer", null, 1);
SQLiteDatabase db = myHelper.getReadableDatabase();
Cursor cursor1 = db.rawQuery("select * from user where username = ?",new String[]{username});
//判断用户名是否被注册
if (cursor1.moveToNext()){
Toast.makeText(RegisterActivity.this,"此用户名已被注册,换一个试试!",Toast.LENGTH_SHORT).show();
}else {
//判断两次输入密码是否一致
if (password.equals(rePassword)){
db.execSQL("insert into user(username,password) values(?,?)",new String[]{username,password});
Cursor cursor2 = db.rawQuery("select * from user where username = ? and password = ?",new String[]{username,password});
//判断是否注册成功
if (cursor2.moveToNext()){
Toast.makeText(RegisterActivity.this,"注册成功!",Toast.LENGTH_SHORT).show();
Intent intent = new Intent();
intent.putExtra("username",username);
intent.putExtra("password",password);
setResult(RESULT_OK,intent);
finish();
}else {
Toast.makeText(RegisterActivity.this,"注册失败!",Toast.LENGTH_SHORT).show();
}
}else {
Toast.makeText(RegisterActivity.this,"确认密码与密码不相同!",Toast.LENGTH_SHORT).show();
}
}
}else {
Toast.makeText(RegisterActivity.this,"用户名、密码、确认密码都不能为空!",Toast.LENGTH_SHORT).show();
}
}
});
}
}
package com.example.finaltask;
import android.app.Service;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.media.MediaPlayer;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Message;
import java.io.IOException;
import java.util.List;
public class MusicService extends Service {
private MediaPlayer mediaPlayer;
protected static int index = 0;
protected static boolean isFirstPlay = true;
private List<String> musicNameList;
//当前正在播放的音乐的名字
protected static String currentMusicName = "";
public IBinder onBind(Intent intent) {
return new MyBinder();
}
public MusicService() {
super();
}
@Override
public void onCreate() {
super.onCreate();
mediaPlayer = new MediaPlayer();
musicNameList = MusicActivity.musicName;
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
public class MyBinder extends Binder{
//加载音乐,启动播放器
public void play(String musicName)
{
try {
//得到当前正在播放的音乐的名字
currentMusicName = musicName;
MusicActivity.textView1.setText("正在播放 "+currentMusicName+"........");
AssetFileDescriptor descriptor = getAssets().openFd(currentMusicName+".mp3");
mediaPlayer.reset();
mediaPlayer.setDataSource(descriptor.getFileDescriptor(),
descriptor.getStartOffset(),descriptor.getLength());
mediaPlayer.prepareAsync();
//当mediaPlayer准备完毕,开始播放,并更新进度条
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.start();
updateSeekBar();
}
});
//当前歌曲播放完毕,直接播放下一首
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
nextSong();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
//上一首
public void lastSong(){
index = index - 1;
index = index%musicNameList.size();//防止下标越界
if (index<0) {
index = index + musicNameList.size();//防止下标越界
play(musicNameList.get(index));
}else {
play(musicNameList.get(index));
}
}
//暂停,开始,继续,默认播放第一首
public void startOrPause(){
//判断是否是第一次播放音乐,如果是第一次播放,需要加载音乐,直接调用play方法
if (isFirstPlay){
index = index % musicNameList.size();//防止下标越界
isFirstPlay = false;
play(musicNameList.get(index));
}else {
/**
* 如果不是第一次播放,
* 判断mediaPlayer的状态,正在播放就暂停,
* 如果是暂停的,就继续播放
*/
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
MusicActivity.textView1.setText(currentMusicName+" 已暂停..........");
} else {
mediaPlayer.start();
updateSeekBar();
MusicActivity.textView1.setText("正在播放 "+currentMusicName+"........");
}
}
}
//下一首
public void nextSong(){
index = index + 1;
index = index%musicNameList.size();//防止下标越界
play(musicNameList.get(index));
}
//更新进度条,向MusicActivity的handler传递信息更行进度条
public void updateSeekBar(){
new Thread(new Runnable() {
@Override
public void run() {
while (mediaPlayer.isPlaying()) {
try {
Thread.sleep(1000);
Message message = Message.obtain();
message.what = 1;
Bundle bundle = new Bundle();
bundle.putInt("totalDuration", mediaPlayer.getDuration());
bundle.putInt("currentDuration", mediaPlayer.getCurrentPosition());
message.setData(bundle);
MusicActivity.handler.sendMessage(message);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
public void stop(){
mediaPlayer.stop();
}
public void release() {
mediaPlayer.reset();
mediaPlayer.release();
}
//音乐随着进度条进行播放
public void seekTo(int progress){
mediaPlayer.seekTo(progress);
}
}
}
package com.example.finaltask;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.res.AssetManager;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.SeekBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class MusicActivity extends AppCompatActivity {
private String[] fileNames;
private ListView listView;
protected static TextView textView1;
private TextView textView2;
private EditText editText;
private SeekBar seekBar;
private MusicService.MyBinder myBinder;
private MyHelper myHelper;
private ArrayAdapter arrayAdapter;
protected static Handler handler;
protected static List<String> musicName;
private SQLiteDatabase db = null;
private ImageButton imageButton,imageButton1,imageButton2,imageButton3;
//连接服务
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myBinder = (MusicService.MyBinder) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_music);
listView = findViewById(R.id.listView);
textView1 = findViewById(R.id.textView1);
textView2 = findViewById(R.id.textView2);
editText = findViewById(R.id.editText);
imageButton = findViewById(R.id.imageButton);
imageButton1 = findViewById(R.id.imageButton1);
imageButton2 = findViewById(R.id.imageButton2);
imageButton3 = findViewById(R.id.imageButton3);
seekBar = findViewById(R.id.seekBar);
textView2.setText("00:00/00:00");
//创建新表保存歌曲名
myHelper = new MyHelper(MusicActivity.this,"musicPlayer",null,1);
//音乐表清空
myHelper.getWritableDatabase().execSQL("delete from song");
//创建顺序表保存从数据数据库得到的歌曲名
musicName = new ArrayList<>();
//获取assets下的音乐
addMusic();
//新建适配器
arrayAdapter = new ArrayAdapter(MusicActivity.this,android.R.layout.simple_list_item_1,musicName);
listView.setAdapter(arrayAdapter);
//绑定服务
final Intent intent = new Intent(MusicActivity.this,MusicService.class);
bindService(intent,connection,BIND_AUTO_CREATE);
//搜索歌曲
imageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
musicName.clear();
String keyWord = editText.getText().toString().trim();
db = myHelper.getReadableDatabase();
Cursor cursor = null;
//当文本框不为空时,将模糊查询的音乐名添加到musicName
if (!TextUtils.isEmpty(keyWord)){
cursor = db.rawQuery("select * from song where musicName like ?",new String[]{"%"+keyWord+"%"});
}else {
cursor = db.rawQuery("select * from song",null);
}
while (cursor.moveToNext()){
//将音乐名添加到musicName
musicName.add(cursor.getString(1));
}
//刷新适配器
arrayAdapter.notifyDataSetChanged();
}
});
//上一首
imageButton1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myBinder.lastSong();
}
});
//开始,播放,暂停
imageButton2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myBinder.startOrPause();
}
});
//下一首
imageButton3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myBinder.nextSong();
}
});
//进度条监听
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean isFromUser) {
//判断是否人工拖动进度条
if(isFromUser) {
myBinder.seekTo(progress);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
//判断是否是第一次播放音乐
if (MusicService.isFirstPlay){
if (MusicService.index!=i){
MusicService.index = i;
myBinder.play(musicName.get(i));
}else {
//当进行搜索之后,musicName保存的音乐发生了改变,我们就不能仅通过索引相同来判断是同一首歌
if (musicName.get(i).equals(MusicService.currentMusicName)){
myBinder.startOrPause();
}else {
myBinder.play(musicName.get(i));
}
}
MusicService.isFirstPlay = false;
}else {
if (MusicService.index!=i){
MusicService.index = i;
myBinder.play(musicName.get(i));
}else {
if (musicName.get(i).equals(MusicService.currentMusicName)){
myBinder.startOrPause();
}else {
myBinder.play(musicName.get(i));
}
}
}
}
});
handler = new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
switch (msg.what){
case 1:
Bundle bundle = msg.getData();
int totalDuration = bundle.getInt("totalDuration");
int currentDuration = bundle.getInt("currentDuration");
seekBar.setProgress(currentDuration);
seekBar.setMax(totalDuration);
textView2.setText(formatTime(currentDuration)+"/"+formatTime(totalDuration));
break;
}
}
};
}
//获取音乐
private void addMusic(){
AssetManager assetManager = getAssets();
db = myHelper.getWritableDatabase();
try {
fileNames = assetManager.list("");
for (String name:fileNames) {
if (name.endsWith(".mp3")) {
//去掉歌曲名的后缀".mp3"
String substring = name.substring(0, name.length() - 4);
musicName.add(substring);
//防止数据库重复插入数据
db.execSQL("insert or ignore into song(musicName) values(?)", new String[]{substring});
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
myBinder.stop();
myBinder.release();
if (db!=null){
db.close();
}
myHelper.close();
unbindService(connection);
}
private static String formatTime(int time) {
Date date = new Date(time);
SimpleDateFormat sdf = new SimpleDateFormat("mm:ss");
String totalTime = sdf.format(date);
return totalTime;
}
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="30dp"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10sp"
android:layout_weight="1"
android:text="账号"
android:textSize="25sp" />
<EditText
android:id="@+id/editText1"
android:layout_width="280dp"
android:layout_height="wrap_content"
android:layout_marginRight="10sp"
android:layout_weight="1"
android:ems="10"
android:inputType="textPersonName"
android:textSize="20sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout2"
android:layout_width="wrap_content"
android:layout_height="43dp"
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/linearLayout">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10sp"
android:layout_weight="1"
android:text="密码"
android:textSize="25sp" />
<EditText
android:id="@+id/editText2"
android:layout_width="280dp"
android:layout_height="wrap_content"
android:layout_marginRight="10sp"
android:layout_weight="1"
android:ems="10"
android:inputType="textPassword"
android:textSize="20sp" />
</LinearLayout>
<LinearLayout
android:layout_width="385dp"
android:layout_height="46dp"
android:layout_marginStart="20dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="30dp"
android:layout_marginEnd="20dp"
android:layout_marginRight="20dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/checkBox">
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10sp"
android:layout_weight="1"
android:text="登录"
android:textSize="20sp" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10sp"
android:layout_weight="1"
android:text="注册"
android:textSize="20sp" />
</LinearLayout>
<CheckBox
android:id="@+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="40dp"
android:layout_marginLeft="40dp"
android:layout_marginTop="20dp"
android:text="记住我"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/linearLayout2" />
</androidx.constraintlayout.widget.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".RegisterActivity">
<LinearLayout
android:id="@+id/linearLayout3"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="30dp"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="注册账号"
android:textSize="25sp" />
<EditText
android:id="@+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:inputType="textPersonName"
android:textSize="20sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout4"
android:layout_width="386dp"
android:layout_height="40dp"
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/linearLayout3">
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="输入密码"
android:textSize="25sp" />
<EditText
android:id="@+id/editText2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:inputType="textPassword"
android:text=""
android:textSize="20sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout5"
android:layout_width="388dp"
android:layout_height="46dp"
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/linearLayout4">
<TextView
android:id="@+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="确认密码"
android:textSize="25sp" />
<EditText
android:id="@+id/editText3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:inputType="textPassword"
android:textSize="20sp" />
</LinearLayout>
<LinearLayout
android:layout_width="394dp"
android:layout_height="51dp"
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="30dp"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/linearLayout5">
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginRight="5sp"
android:layout_weight="1"
android:text="返回"
android:textSize="20sp" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5sp"
android:layout_weight="1"
android:text="注册"
android:textSize="20sp" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<SeekBar
android:id="@+id/seekBar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView2" />
<LinearLayout
android:id="@+id/linearLayout2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="1dp"
android:layout_marginLeft="1dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="1dp"
android:layout_marginRight="1dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/seekBar">
<ImageButton
android:id="@+id/imageButton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@color/colorAccent"
app:srcCompat="@android:drawable/ic_media_previous" />
<ImageButton
android:id="@+id/imageButton2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@color/colorAccent"
app:srcCompat="@android:drawable/ic_media_play" />
<ImageButton
android:id="@+id/imageButton3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@color/colorAccent"
app:srcCompat="@android:drawable/ic_media_next" />
</LinearLayout>
<TextView
android:id="@+id/textView1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/linearLayout7" />
<TextView
android:id="@+id/textView2"
android:layout_width="0dp"
android:layout_height="27dp"
android:layout_marginStart="300dp"
android:layout_marginLeft="300dp"
android:layout_marginTop="5dp"
android:layout_weight="1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView1" />
<LinearLayout
android:id="@+id/linearLayout6"
android:layout_width="409dp"
android:layout_height="0dp"
android:layout_marginStart="20dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="10dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<EditText
android:id="@+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="3"
android:ems="10"
android:gravity="center"
android:inputType="text"
android:singleLine="true" />
<ImageButton
android:id="@+id/imageButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="3"
android:contentDescription="TODO"
app:srcCompat="@android:drawable/ic_menu_search" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout7"
android:layout_width="409dp"
android:layout_height="478dp"
android:layout_marginStart="1dp"
android:layout_marginLeft="1dp"
android:layout_marginTop="1dp"
android:layout_marginEnd="1dp"
android:layout_marginRight="1dp"
android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/linearLayout6">
<ListView
android:id = "@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
源码:Android音乐播放器