iPod touch UI






4.89/5 (24投票s)
这是一款具有透明效果的媒体播放器,可以播放 MP3 和 Wav 文件,如果存在,则显示标签信息和专辑封面图像。
 
 
目录
引言
这是一款具有透明效果的媒体播放器。它还播放 MP3 和 wav 文件,如果存在,则显示标签信息,并显示专辑封面图像。
原始媒体播放器的用户界面无法通过手指进行控制。在这里,我尝试解决了这个问题。
作为示例,我使用了类似于 iPod touch 的界面。在本教程中,我主要继续解释在 Windows Mobile 上使用透明度的更好方法。作为本文的引言,我建议您阅读我之前关于透明度的文章 iPhone UI[^]。
在本文中,您还可以阅读到
- 分辨率感知和方向感知
- 动态图形文本缩放
- 鼠标手势
- 拦截按钮
- 在 Windows Mobile 上使用 Windows Media Player OCX
背景
我发现了一些关于声音文件的问题,特别是在检索标签信息和当前位置时间方面,经过长时间的搜索,我选择了使用 Windows Media Player OCX。brochpirate 的文章 Audio Book Player [^] 通过 OpenNETCF.org 为您提供了一种在移动设备上快速使用 OCX 的方法,这是一个很棒的实际示例。在这里,我将详细介绍如何使用它。
如何使用 WMP
要使用 Windows Media Player,您只需要将此 DLL 导入为引用
- OcxControls
- OpenNETCF.Windows.Forms.AxHost
- WMPLib
并将 cPlayer 添加到您的应用程序中。现在您可以完全控制 WMP 了,是不是很酷?
使用代码
解决方案
深入了解解决方案,您可以找到
- iPlayer类,主窗体具有:分辨率感知、动态图形文本缩放、鼠标手势,并且还可以与 Windows Media Player COM 一起使用。
- cPlayer类,此类与 Media Player OCX 一起使用,它位于- abPlayer下。我只添加了几个属性 - 循环和音量。
- FilesManger类,此类获取您移动设备上的所有 MP3 和 Wav 文件。
- ImageButtons类,一个具有透明度和其他功能的按钮类。
- PlatformAPIs类,它是管理 P/Invoke 的类。
- SlideButton类,用于移动图像(进度)的类。
- BMPs 文件夹,其中包含代码中使用的所有 BMP 文件。
iPlayer 类
这是应用程序的主窗体。我在 myPaint(Graphics dc) 方法中绘制所有窗体。myPaint 可以从 Paint 事件处理程序调用并使用 e.Graphics,或者可以在状态更改时调用,并且使用的 dc 是 CreateGraphics()。然后,我的 paint 会绘制屏幕上的所有内容,包括所有控件,从背景开始,然后是 TopBar、SongBar、LocationBar(如果需要)、BottomBar,以及使用的各种按钮。
背景
bitmapBackImage Bitmap 被加载为背景,并加载歌曲目录中找到的第一个图像作为默认图像。为了选择图像,我倾向于显示 "Folder.jpg"(如果存在),因为它是默认互联网 CD 搜索使用的默认图像。
这是代码
private void SearchBGImage()
{
    if (FormListScanFiles.lvwSoundFiles.Items.Count != 0)
    {
        string path = Player.PlayingPath.Remove(Player.PlayingPath.LastIndexOf(@"\"), 
		Player.PlayingPath.Length - Player.PlayingPath.LastIndexOf(@"\"));
        String[] ImageFiles = GetImageFiles(path);
        if (ImageFiles.Length != 0)
        {
            foreach (string ImageFile in ImageFiles)
            {
                //If you use the internet CD databases you can have more 
                //than a picture inside the folder
                //This method chooses the one that best fit screen
                if (ImageFile.Remove(0, ImageFile.LastIndexOf(@"\") + 1).ToLower() == 
				"folder.jpg")
                {
                    bitmapBackImage = new Bitmap(ImageFile);
                    return;
                }
            }
            bitmapBackImage = new Bitmap(ImageFiles[0]);
            return;
        }
    }         
    bitmapBackImage = bitmapBackImageDefault;
}
默认图像

如果我需要拉伸图像,我会使用这段代码
Rectangle srcRect = new Rectangle(0, 0, bitmapBackImage.Width, bitmapBackImage.Height);
Rectangle destRect = new Rectangle(0, 0, this.Width, this.Height);
gxBuffer.DrawImage(bitmapBackImage, destRect, srcRect, GraphicsUnit.Pixel); 
否则我居中并按原比例绘制:
int x = (this.Width - this.bitmapBackImage.Width) / 2;
int y = (this.Height - this.bitmapBackImage.Height) / 2;
gxBuffer.DrawImage(this.bitmapBackImage, x, y);
顶部栏
这部分与 iPhone UI 文章相似,但在这里我动态更改了图像的位置。Topbar 分为 4 张图像和一个时间文本。
- 电池电量,左锚定,不拉伸。
- 时间线,左锚定(电池电量宽度),右锚定(GSM 电量宽度 +
- 当前播放器状态宽度),使用拉伸。
- 当前播放器状态,左锚定(时间线宽度 + 电池电量宽度),右锚定(电池电量宽度),不拉伸。
- GSM 电量,右锚定,不拉伸。
- 时间绘制在屏幕宽度的中间,并在时间线中间居中(时间线高度/2 - 文本高度/2)。
所有图像
- 电池电量位图  
- GSM 电量位图  
- 顶部播放器状态  
以及这两个视图示例。
 
 

带文本缩放的歌曲栏
这部分是将单个位图拉伸到屏幕的全部宽度,并具有固定的高度。
这是原始位图。
 
这是两个拉伸示例。

在上面,我放置了两个 ImageButton,一个用于退出,一个用于文件列表。按钮位于 SongTopBar 位图高度的中间,退出按钮具有左锚定,右侧具有右锚定。
在屏幕中间,我放置了艺术家姓名、歌曲名称和专辑名称。字符串是从当前选定的文件中检索的标签。
在这里,我使用了我的 DynamicGraphicTextResizing 来实现 "动态图形文本缩放"。如果显示的字符串宽度远大于显示宽度,我会将 string 修改为适合屏幕宽度的最小尺寸,并在末尾添加 "..."。
private void DynamicGraphicTextResizing(ref string text, 
	ref SizeF size, Font songTitleFont)
{
    while (size.Width > this.Width - buttonExit.Image.Width - buttonList.Image.Width)
    {
        text = text.Remove(text.Length - 4, 4);
        text = text + "...";
        size = gxBuffer.MeasureString(text, songTitleFont);
    }
} 
要绘制 string,我使用了这段代码。
string title = Player.GetMediaTAG(eTagNames.TITLE); 
SizeF sizeTitle = gxBuffer.MeasureString(title, FontsongTitle);
DynamicGraphicTextResizing(ref title, ref sizeTitle, FontsongTitle);
xSong = this.Width / 2 - (int)sizeTitle.Width / 2 + buttonExit.Image.Width / 2;
gxBuffer.DrawString(title, FontSong, BrushWhite, xSong, 
	bitmapTopHeader.Height + sizeTitle.Height - 2);
 信息:brochpirate 在他的文章中提供了一种滚动文本的方法。您可以参考一下,我认为它会很有用。
 信息:brochpirate 在他的文章中提供了一种滚动文本的方法。您可以参考一下,我认为它会很有用。
这些是使用的所有图像。

这是一个关于其工作原理的示例。

定位栏
 信息:这部分仅在用户单击
信息:这部分仅在用户单击 SongBar 时显示,它显示当前位置、歌曲时长和一个当前位置的进度条。
为了显示定位栏,我使用了一个内部布尔值 ShowTimeLine,并决定在您单击 SongBar 时绘制它。当 LocationBar 显示时,它会启用一个计时器,每秒绘制当前位置并绘制进度条的步进。
private bool SongMouseUp(MouseEventArgs e)
{
    if (ClientAreaSong().Contains(e.X, e.Y))
    {
        ShowTimeLine = !ShowTimeLine;
        timerDrawLocation.Enabled = SetTimerDrawLocation();
        return true;
        }
    return false;
}
LocationBar 分为 8 个部分。
- 重复按钮(2 种状态:按下、关闭)。
- 当前位置时间 + 背景。
- 歌曲进度分为 2 部分:已播放和未播放。
- 时长 + 背景。
- 随机播放按钮(2 种状态:按下、关闭)。
注意:这里我没有涵盖算法中的所有内容,但我相信您会很容易理解这些。
重复按钮设置为 WMP 的重复状态。锚定在左侧,不拉伸。
当前位置时间和时长是从播放器 Player.LocationString 和 Player.DurationString 检索的字符串。背景图像是这个。
进度分为 2 部分:已播放和未播放。我使用两张图像,并计算屏幕上的位置 iWidthProgressPlayed。然后,我从固定起始位置绘制 PlayedProgress 到 iWidthProgressPlayed,并从 iWidthProgressPlayed 绘制 NotPlayedProgress,其动态宽度为(所有可能的尺寸减去已播放的尺寸)iWidthTotal - iWidthProgressPlayed。
随机播放按钮设置为 WMP 的重复状态。
使用的所有图像。
 
 
这是 3 个工作示例。
 
 
 
 
 注意:我在一些设备上测试了此应用程序,有时发现它运行缓慢,我建议您仅在需要时使用
 注意:我在一些设备上测试了此应用程序,有时发现它运行缓慢,我建议您仅在需要时使用 LocationBar。程序启动时 LocationBar 是隐藏的。
屏幕中间部分。
如果搜索找不到文件(MP3 或 wav),则在屏幕中央显示文本 "未找到文件"。
这是代码
private void DrawSongNumber(Graphics gx)
{
    if (FormListScanFiles.lvwSoundFiles.Items.Count == 0)
    {
        NoFilesFound = "No files found";
        SizeF sizeNoFilesFound = 
		gxBuffer.MeasureString(songname, FontSongNoFilesFound);
        int xSong = this.Width / 2 - (int)sizeNoFilesFound.Width / 2;
        int ySong = this.Height / 2 - (int)sizeNoFilesFound.Height / 2;
        int widthMessage = (int)sizeNoFilesFound.Width ;
        int xMessage = (this.Width / 2 - (int)widthMessage / 2 )-10;
                
        int yMessage = this.Height / 2 - (int)bitmapMessage.Height / 2;
        DrawAlphaStretchX(gxBuffer, bitmapMessage, 
		170, xMessage, yMessage, widthMessage);
                
        gxBuffer.DrawString(NoFilesFound, 
		FontSongNoFilesFound, BrushWhite, xSong, ySong);
    }
}
这是一个示例。

底部栏
底部使用了一个大的背景,左锚定和右锚定。
位图分为两个部分(上半部分和下半部分)。
在前半部分,我放置了播放器控件:上一个、播放/暂停、下一个。这些图像存储在三个 ImageButton 中。播放器状态也位于顶部栏。
后半部分包含音量滑块,这是一个 SlideButton。在这里,我对 iPhone UI 中发布的先前版本进行了一些修改。我增加了与进度交互的可能性,并将其设置为百分比。当鼠标移动到滑块按钮上时,音量会改变,并显示百分比,这与定位栏中使用的相似。
这些是使用的所有图像。
 
 
这是两个示例。

有趣的点
我想提醒您,这个程序不是一个完整的界面。本文添加了一些在 iPhone UI 中使用的功能,希望您觉得它们有用。
注意:我认为这篇文章包含一些翻译错误,请您包涵并继续阅读。我很快就会将其翻译得更好。
链接
- Audio Book Player 在此处[^],非常感谢 **BrochPirate** 的帮助。
- 在 .NET Compact Framework 2.0 中托管 ActiveX 控件 在此处[^]
- 本文的引言 iPhone UI[^]
历史
- 2009 年 1 月 7 日 - 首次发布
- 2009 年 1 月 10 日 - 第二次发布- 次要 bug 修复
- 启动时隐藏 LocationBar。
- 添加了 Message位图。
 


