您的位置:首页 > 移动开发 > Android开发

Android项目实战--【谁是歌手-布局篇】

2016-03-08 00:54 381 查看

项目简介:

项目设定游戏时间为60秒,在这60秒内,播放音乐,并且给出六张歌手的图片(其中有一张是正确是,其这5张是随机的干扰歌手图片,且每首歌都会随机选5张与正确那张组合),让用户选择当前音乐是哪位歌手唱的,当用户点击了歌手图片,代表用户已出做选择,如果用户选择正确,加10个金币,如果用户选择不正确,则减10个金币,同时刷新界面上的金币数并弹出Toast提示用户增加或减少了10个金币。用户选择完后会切换到下一首音乐,继续播放。然后用户继续选择。只要60秒时间没有耗尽用户可以一直玩,直到所有歌曲都播放完,游戏结束,并弹出对话框,显示总歌曲数以及用户选对了几首,选错了几首,同时该对话框提供了两个按钮,一个是重新玩,一个是退出游戏,用户可以根据自己的喜好进行选择。如果用户选择了重新玩,则和刚打开APP的效果一样,重新计时(有计时进度条),重头播放第一首音乐
,并且金币清零; 如果用户选择退出游戏,则退出APP。当然60秒的时间在玩的过程中耗尽了,则弹出对话框,告知用户,60秒时间已耗尽,用户同样可以选择重新玩或退出游戏。

项目效果图:













技术实现:

主界面布局:layout------>activity_main.xml

(1)为主界面布局添加背景:

在根布局上,使用android:background属性为其指定一张背景图片即可。我的背景图片名为main_bg.png,存放 在drawable-hdpi目录中。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/main_bg" >
</RelativeLayout>




(2)标题栏布局实现:

标题栏的实现非常简单,中简一个标题文字(TextView),右边是显示金币的图标(ImageView)和金币数 (TextView),然后为标题栏添加一个背景就可以了。我的标题背景图片名为title_bg,存放在drawable-hdpi目录 中。至于金币这块的具体实现大家一看代码就明白了。
<RelativeLayout
android:id="@+id/rl_title"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@drawable/title_bg" >

<TextView
android:id = "@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="谁是歌手"
android:textColor="#ffffff"
android:textSize="22sp"
android:textStyle="bold" />

<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="5dp"
android:background="@drawable/game_coin" >

<ImageView
android:id="@+id/iv_coin_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="25dp"
android:src="@drawable/game_coin_icon" />

<TextView
android:id="@+id/tv_coin_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="5dp"
android:layout_toRightOf="@id/iv_coin_icon"
android:text="0"
android:textColor="#ffffff"
android:textStyle="bold" />
</RelativeLayout>
</RelativeLayout>




(3)时间进度条布局实现 :

60秒的时间需要动态减少,所以使用一个ProgressBar控件来显示和控制,为了方便控制把进度条的最大值设 置成60,默认的进度也是60。且进度条的样式是水平样式,然后为ProgressBar的背景设置一个颜色,为 ProgressBar的进度设置另一个颜色,目的是为了在视觉可以明显的看到进度效果。

进度条颜色文件:drawable------>progressbar_color.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

<!-- 背景  gradient是渐变,corners定义的是圆角 -->
<item android:id="@android:id/background">
<shape>
<corners android:radius="10dp" />

<solid android:color="#ffffff" />
</shape>
</item>
<!-- 进度条-->
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="10dip" />

<solid android:color="#FF8080" />
</shape>
</clip>
</item>

</layer-list>


进度条布局:

<ProgressBar
android:id="@+id/pb_time"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="12dp"
android:layout_below="@id/rl_title"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="20dp"
android:max="60"
android:progress="60"
android:progressDrawable="@drawable/progressbar_color" />



(4)6张歌手头像显示布局实现 :

可以使用GridView九宫格控件实现,且指定GridView要显示的列数为3,这样6张图片就可以显示二行,这正是我 们需要的效果。这块也没有什么难点,唯一需要注意的是点击GridView条目的时候常用有自带的黄颜色,表示用户 按下了当前条目,这显示不是我们想要的,我们可以使用android:listSelector="@android:color/transparent",用透
明为替代黄颜色。
<GridView
android:id="@+id/gv_singers"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/pb_time"
android:layout_centerHorizontal="true"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="40dp"
android:gravity="center"
android:horizontalSpacing="5dp"
android:listSelector="@android:color/transparent"
android:numColumns="3"
android:scrollbars="none"
android:verticalSpacing="5dp" />



(4)播放按钮布局实现:

使用一个ImageButton就可以,这里需要注意的是,这个按钮的背景是个selector,可以根据用户点击改变普通 背景,也就是可以根据用户的点击状态切换不同的背景图片。

背景选择器实现:drawable-------->btn_play_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

<item android:drawable="@drawable/btn_play_pressed" android:state_pressed="true"/>
<item android:drawable="@drawable/btn_play"/>

</selector>


播放按钮:
<ImageButton

android:id="@+id/ib_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_below="@id/gv_singers"
android:layout_centerHorizontal="true"
android:layout_marginBottom="40dp"
android:layout_marginTop="20dp"
android:background="@null"
android:src="@drawable/btn_play_bg" />




最终完整布局如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/main_bg" >

<RelativeLayout
android:id="@+id/rl_title"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@drawable/title_bg" >

<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="谁是歌手"
android:textColor="#ffffff"
android:textSize="22sp"
android:textStyle="bold" />

<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="5dp"
android:background="@drawable/game_coin" >

<ImageView
android:id="@+id/iv_coin_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="25dp"
android:src="@drawable/game_coin_icon" />

<TextView
android:id="@+id/tv_coin_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="5dp"
android:layout_toRightOf="@id/iv_coin_icon"
android:text="0"
android:textColor="#ffffff"
android:textStyle="bold" />
</RelativeLayout>
</RelativeLayout>

<ProgressBar android:id="@+id/pb_time" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="12dp" android:layout_below="@id/rl_title" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:layout_marginTop="20dp" android:max="60" android:progress="60" android:progressDrawable="@drawable/progressbar_color" />

<GridView
android:id="@+id/gv_singers"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/pb_time"
android:layout_centerHorizontal="true"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="40dp"
android:gravity="center"
android:horizontalSpacing="5dp"
android:listSelector="@android:color/transparent"
android:numColumns="3"
android:scrollbars="none"
android:verticalSpacing="5dp" />

<ImageButton
android:id="@+id/ib_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_below="@id/gv_singers"
android:layout_centerHorizontal="true"
android:layout_marginBottom="40dp"
android:layout_marginTop="20dp"
android:background="@null"
android:src="@drawable/btn_play_bg" />

</RelativeLayout>




在XML编辑器中,默认GridView的高度是填充型的,所以它下面的播放按钮现在看到,运行到设备上就可以正常看了。

准备歌曲信息资源:

(1)歌曲:

本项目准备了11首歌,并把它们放到了项目的assets目录中。大家可以根据自己的喜欢好多放几首。
需要注意的是,我这里把歌曲名全起名成_000XX这种形式了,为的是增加一层安全性,不容易让用户通过歌曲文件 名得名是什么歌曲。



(2)歌手头像:

歌手头像文件名和歌曲文件名启的一样,并且是一一对应的。我把它放到了res/drawable-hdpi目录中。



(3)歌曲真正的名字:

把歌曲真正的名字以字符串数组的形式放到了res/values/arrays.xml中了,这个文件专门以XML的方式
存放项目中用到的字条串数组,整型数组等。如果项目中没有这个文件,可自己创建一个,并启名为arrays.xml。
为了将来在代码中让歌曲文件名,歌手头像文件名,歌曲真正的名字都封装到一个实体数据对象中,所以
在arrays.xml中把歌曲文件名,歌手头像文件名,歌曲真正的名字都放到了各自的字符串数组中了。

res/values/arrays.xml文件代码:
<?xml version="1.0" encoding="utf-8"?>
<resources>

<string-array name="music_file_names">
<item>"_00000.m4a"</item>
<item>"_00001.m4a"</item>
<item>"_00002.m4a"</item>
<item>"_00003.m4a"</item>
<item>"_00004.m4a"</item>
<item>"_00005.m4a"</item>
<item>"_00006.m4a"</item>
<item>"_00007.m4a"</item>
<item>"_00008.m4a"</item>
<item>"_00009.m4a"</item>
<item>"_00010.m4a"</item>
</string-array>
<string-array name="music_names">
<item>"征服"</item>
<item>"童话"</item>
<item>"传奇"</item>
<item>"老男孩"</item>
<item>"龙的传人"</item>
<item>"你的背包"</item>
<item>"同桌的你"</item>
<item>"七里香"</item>
<item>"大海"</item>
<item>"再见"</item>
<item>"后来"</item>
</string-array>
<string-array name="singer_names">
<item>"那英"</item>
<item>"光良"</item>
<item>"王菲"</item>
<item>"筷子兄弟"</item>
<item>"王力宏"</item>
<item>"陈奕迅"</item>
<item>"水木年华"</item>
<item>"周笔畅"</item>
<item>"张雨生"</item>
<item>"张震岳"</item>
<item>"刘若英"</item>
</string-array>
<!-- 歌手图片名 -->
<string-array name="singer_pic_names">
<item>"_00000"</item>
<item>"_00001"</item>
<item>"_00002"</item>
<item>"_00003"</item>
<item>"_00004"</item>
<item>"_00005"</item>
<item>"_00006"</item>
<item>"_00007"</item>
<item>"_00008"</item>
<item>"_00009"</item>
<item>"_00010"</item>
</string-array>
<string-array name="tone_file_names">
<item>enter.mp3</item>
<item>"cancel.mp3"</item>
<item>coin.mp3</item>
</string-array>

</resources>


创建数据模型对象------>Song

Song这个对象专门用来封装歌曲文件名,歌手头像文件名,歌曲真正的名字这些数据的,因为它们是相关数据。

项目src源码包结构:

(大家可根据自己的项目src源码包结构进行调整,不一定要和我一样。)






其中com.kedi.songs.model包就是专门存放数据模型类的包,大家可以看到里面有个Song.java,它就是我们要创 建的歌曲信息数据模型。这个类主要就是一个数据变量和它的getter,setter方法以及构造方法。

package com.kedi.songs.model;

/**
* 歌曲实体类
*
* @author 张科勇
*
*/
public class Song {
// 歌手名(这个非必须)
private String singerName;
// 歌手图片名
private String singerPicName;
// 歌曲文件名
private String musicFileName;
// 歌曲名
private String musicName;

public String getSingerName() {
return singerName;
}

public void setSingerName(String singerName) {
this.singerName = singerName;
}

public String getSingerPicName() {
return singerPicName;
}

public void setSingerPicName(String singerPicName) {
this.singerPicName = singerPicName;
}

public String getMusicFileName() {
return musicFileName;
}

public void setMusicFileName(String musicFileName) {
this.musicFileName = musicFileName;
}

public String getMusicName() {
return musicName;
}

public void setMusicName(String musicName) {
this.musicName = musicName;
}

public Song() {
}

public Song(String singerName, String singerPicName, String musicFileName, String musicName) {
this.singerName = singerName;
this.singerPicName = singerPicName;
this.musicFileName = musicFileName;
this.musicName = musicName;
}

}


功能逻辑实现:

欲知后事,且移步到下篇详解。(主要是再往下写,一篇文章显的太长,大家可以喝杯咖啡,缓缓眼,下篇见)Android项目实战--【谁是歌手-逻辑实现篇】
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: