65.9K
CodeProject 正在变化。 阅读更多。
Home

iPod touch UI

2009年1月6日

CPOL

7分钟阅读

viewsIcon

72113

downloadIcon

1232

这是一款具有透明效果的媒体播放器,可以播放 MP3 和 Wav 文件,如果存在,则显示标签信息和专辑封面图像。

iPodTouchUI/SampleImage2.gif

目录

引言

这是一款具有透明效果的媒体播放器。它还播放 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,或者可以在状态更改时调用,并且使用的 dcCreateGraphics()。然后,我的 paint 会绘制屏幕上的所有内容,包括所有控件,从背景开始,然后是 TopBarSongBarLocationBar(如果需要)、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;
}

默认图像

iPodTouchUI/wallpaperDefault2.gif

如果我需要拉伸图像,我会使用这段代码

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)。

所有图像

  • 电池电量位图

    iPodTouchUI/AllBatteryLevelBitmaps.gif

  • GSM 电量位图

    iPodTouchUI/AllGSMLevel.gif

  • 顶部播放器状态

    iPodTouchUI/AllTopPlayerStatus.gif

以及这两个视图示例。

iPodTouchUI/TopBar1.gif

iPodTouchUI/TopBar2.gif

带文本缩放的歌曲栏

这部分是将单个位图拉伸到屏幕的全部宽度,并具有固定的高度。

这是原始位图。

 iPodTouchUI/SongBar.gif

这是两个拉伸示例。

iPodTouchUI/SongBarSample_.gif

在上面,我放置了两个 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);

iPodTouchUI/Info.png 信息:brochpirate 在他的文章中提供了一种滚动文本的方法。您可以参考一下,我认为它会很有用。

这些是使用的所有图像。

iPodTouchUI/SongTopbar.gif

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

iPodTouchUI/SongBarSample2.gif

定位栏

iPodTouchUI/Info.png信息:这部分仅在用户单击 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.LocationStringPlayer.DurationString 检索的字符串。背景图像是这个。

进度分为 2 部分:已播放和未播放。我使用两张图像,并计算屏幕上的位置 iWidthProgressPlayed。然后,我从固定起始位置绘制 PlayedProgressiWidthProgressPlayed,并从 iWidthProgressPlayed 绘制 NotPlayedProgress,其动态宽度为(所有可能的尺寸减去已播放的尺寸)iWidthTotal - iWidthProgressPlayed

随机播放按钮设置为 WMP 的重复状态。

使用的所有图像。

iPodTouchUI/AllTimelineBitmaps.gif

这是 3 个工作示例。

iPodTouchUI/LocationBarSample.gif

iPodTouchUI/LocationBarSample3.gif

iPodTouchUI/Warning.png 注意:我在一些设备上测试了此应用程序,有时发现它运行缓慢,我建议您仅在需要时使用 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);
    }
}

这是一个示例。

iPodTouchUI/FilesNotFound2.gif

底部栏

底部使用了一个大的背景,左锚定和右锚定。

位图分为两个部分(上半部分和下半部分)。

在前半部分,我放置了播放器控件:上一个、播放/暂停、下一个。这些图像存储在三个 ImageButton 中。播放器状态也位于顶部栏。

后半部分包含音量滑块,这是一个 SlideButton。在这里,我对 iPhone UI 中发布的先前版本进行了一些修改。我增加了与进度交互的可能性,并将其设置为百分比。当鼠标移动到滑块按钮上时,音量会改变,并显示百分比,这与定位栏中使用的相似。
这些是使用的所有图像。

iPodTouchUI/AllBottomBitmaps.gif

这是两个示例。

iPodTouchUI/BottomBarSample.gif

有趣的点

我想提醒您,这个程序不是一个完整的界面。本文添加了一些在 iPhone UI 中使用的功能,希望您觉得它们有用。

注意:我认为这篇文章包含一些翻译错误,请您包涵并继续阅读。我很快就会将其翻译得更好。

链接

  • Audio Book Player 在此处[^],非常感谢 **BrochPirate** 的帮助。
  • 在 .NET Compact Framework 2.0 中托管 ActiveX 控件 在此处[^]
  • 本文的引言 iPhone UI[^]

历史

  • 2009 年 1 月 7 日 - 首次发布
  • 2009 年 1 月 10 日 - 第二次发布
    • 次要 bug 修复
    • 启动时隐藏 LocationBar
    • 添加了 Message 位图。
© . All rights reserved.