今天感觉好累啊。。还是坚持记录下。

收集的API:

https://github.com/HakurouKen/douban.fm-api

https://github.com/zonyitoo/doubanfm-qt/wiki/%E8%B1%86%E7%93%A3FM-API

https://github.com/ampm/douban-fm-sdk

都没有提到Cookie

利用这个API,本来想弄下COOKie的但是Post请求老是通过不过,索性作罢

记录下频道部分的搭建

根据下面的已知分组情况,想到用XML保存下来,再用分组的控件比较好。

想到像Toolkit的longlist(具体名字我忘了)在telerik的控件下,有一个更加方便使用的,叫RadDataBoundListBox,非常好用,分起组来很简单。

首先老样子,先绑定一个DataContext,新建VM类,Ioc注册等等。

一:频道表:

已知固定频道

channel=0 私人兆赫 type=e()

Region&Lang

channel=1 公共兆赫【地区 语言】:华语MHZ
channel=6 公共兆赫【地区 语言】:粤语MHZ
channel=2 公共兆赫【地区 语言】:欧美MHZ
channel=22 公共兆赫【地区 语言】:法语MHZ
channel=17 公共兆赫【地区 语言】:日语MHZ
channel=18 公共兆赫【地区 语言】:韩语MHZ

Ages

channel=3  公共兆赫【年代】:70年代MHZ
channel=4 公共兆赫【年代】:80年代MHZ
channel=5 公共兆赫【年代】: 90年代MHZ

Genre

channel=8 公共兆赫【流派】:民谣MHZ
channel=7 公共兆赫【流派】:摇滚MHZ
channel=13 公共兆赫【流派】:爵士MHZ
channel=27 公共兆赫【流派】:古典MHZ
channel=14 公共兆赫【流派】:电子MHZ
channel=16 公共兆赫【流派】:R&BMHZ
channel=15 公共兆赫【流派】:说唱MHZ
channel=10 公共兆赫【流派】:电影原声MHZ

Special

channel=20 公共兆赫【特辑】:女声MHZ
channel=28 公共兆赫【特辑】:动漫MHZ
channel=32 公共兆赫【特辑】:咖啡MHZ
channel=67 公共兆赫【特辑】:东京事变MHZ

Com

channel=52 公共兆赫【品牌】:乐混翻唱MHZ
channel=58 公共兆赫【品牌】:路虎揽胜运动MHZ

Artist

channel=26 公共兆赫:豆瓣音乐人MHZ
channel=dj DJ兆赫 其对应的XML
 <?xml version="1.0" encoding="utf-8"?>
<AlreadyKnowChannels>
<Channel name="华语MHZ" channelid="1" group="Langurage"></Channel>
<Channel name="粤语MHZ" channelid="6" group="Langurage"></Channel>
<Channel name="欧美MHZ" channelid="2" group="Langurage"></Channel>
<Channel name="法语MHZ" channelid="22" group="Langurage"></Channel>
<Channel name="日语MHZ" channelid="17" group="Langurage"></Channel>
<Channel name="韩语MHZ" channelid="18" group="Langurage"></Channel>
<Channel name="70年代MHZ" channelid="3" group="Ages"></Channel>
<Channel name="80年代MHZ" channelid="4" group="Ages"></Channel>
<Channel name="90年代MHZ" channelid="5" group="Ages"></Channel>
<Channel name="民谣MHZ" channelid="8" group="Genre"></Channel>
<Channel name="摇滚MHZ" channelid="7" group="Genre"></Channel>
<Channel name="爵士MHZ" channelid="13" group="Genre"></Channel>
<Channel name="古典MHZ" channelid="27" group="Genre"></Channel>
<Channel name="电子MHZ" channelid="14" group="Genre"></Channel>
<Channel name="RBMHZ" channelid="16" group="Genre"></Channel>
<Channel name="说唱MHZ" channelid="15" group="Genre"></Channel>
<Channel name="电影原声MHZ" channelid="10" group="Genre"></Channel>
<Channel name="女声MHZ" channelid="20" group="Special"></Channel>
<Channel name="动漫MHZ" channelid="28" group="Special"></Channel>
<Channel name="咖啡MHZ" channelid="32" group="Special"></Channel>
<Channel name="东京事变MHZ" channelid="67" group="Special"></Channel>
<Channel name="乐混翻唱MHZ" channelid="52" group="Com"></Channel>
<Channel name="路虎揽胜运动MHZ" channelid="58" group="Com"></Channel>
<Channel name="豆瓣音乐人MHZ" channelid="26" group="Artist"></Channel>
<Channel name="DJ兆赫" channelid="dj" group="Artist"></Channel>
</AlreadyKnowChannels>
         XDocument xdoc = XDocument.Load("XML/Channels.xml");
XMLChannels = xdoc.Root.Descendants("Channel").Select(
(element) =>
{
return new Channel
{
name = (string)element.Attribute("name"),
channelid = (string)element.Attribute("channelid"),
group = (string)element.Attribute("group")
};
}).ToList();

再导入, XMLChannels是List<Channe>类型。

接下来创建Model

      for (int i = ; i < XMLChannels.Count; i++)
{
channels.Add(new 豆瓣电台.Model.Channel() { ChannelGroup = XMLChannels[i].group, ChannelName = XMLChannels[i].name, ChannelId = XMLChannels[i].channelid });
}

下面是请求图片,由于异步关系,我们要把请求的顺序编号(就是那个i)也放到get类中去。

再在返回的string中放入末尾。最后就可以从订阅者里面取出来了。10,11行即是计算编号并去掉末尾这个编号,(这个编号是为了表明请求的频道ID与我们的频道表的索引(index)的一一对应的关系)

    for (int i = ; i < Channels.Count; i++)
{
new MyRxGetMethodService().Get("http://douban.fm/j/explore/get_channel_info?cid=" + channels[i].ChannelId, i).ObserveOn(Deployment.Current)
.Subscribe(
(result) =>
{ try
{
int tempcount = int.Parse(result.Substring(result.LastIndexOf("}") + , ));
result = result.Substring(, result.LastIndexOf("}") + );
JToken temptoken = JToken.Parse(result)["data"]["res"];
// BitmapImage bitmap = new BitmapImage();
// bitmap.UriSource = new Uri(temptoken["cover"].ToString(), UriKind.Absolute);
var dataitem = channels[tempcount];
dataitem.ChannelImageSource = new Uri(temptoken["cover"].ToString(), UriKind.Absolute);
dataitem.ChannelIntro = temptoken["intro"].ToString(); }
catch
{
} });
// Thread.Sleep(100);
}

背后逻辑基本好了,下面是界面

databoundlist的itemtemplate如下:用了一个SlideHubTile,使结果看起来生动一点,SlideHubTile有正面样式和背面样式。

   <DataTemplate x:Key="JumpListItemTemplate">
<Grid >
<Grid.Resources>
<DataTemplate x:Key="TitleHub">
<Grid>
<TextBlock Text="{Binding ChannelName}" Foreground="White"/>
</Grid>
</DataTemplate>
<DataTemplate x:Key="BackHub">
<Grid Background="#FF0072FF">
<Image Source="{Binding ChannelImageSource}"
Stretch="UniformToFill"/>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding ChannelIntro}" Foreground="White" Height="85.5" Width="150" HorizontalAlignment="Left"/>
<TextBlock Height="85.5" Text="{Binding ChannelName}" Width="150" HorizontalAlignment="Left" Margin="0" Foreground="#FFE2901B"/>
</StackPanel>
</Grid>
</DataTemplate>
</Grid.Resources>
<telerikPrimitives:RadSlideHubTile Title="{Binding}" TitleTemplate="{StaticResource TitleHub}" BackContentTemplate="{StaticResource BackHub}" BackContent="{Binding}" Foreground="#FF1BA1E2">
<telerikPrimitives:RadSlideHubTile.Picture>
<Image Source="{Binding ChannelImageSource}"
Stretch="UniformToFill"/>
</telerikPrimitives:RadSlideHubTile.Picture>
</telerikPrimitives:RadSlideHubTile>
</Grid>
</DataTemplate>

对于组的显示样式,我们可以用原先的模板

  <helpers:JumpListFirstItemTemplateSelector x:Key="HeaderTemplateSelector">
<helpers:JumpListFirstItemTemplateSelector.FirstItemTemplate>
<DataTemplate>
<Grid Margin="0,-8,0,12" Width="480">
<TextBlock FontSize="{StaticResource PhoneFontSizeMedium}" Text="{Binding }" TextWrapping="Wrap"/>
</Grid>
</DataTemplate>
</helpers:JumpListFirstItemTemplateSelector.FirstItemTemplate>
<helpers:JumpListFirstItemTemplateSelector.StandardItemTemplate>
<DataTemplate>
<Grid Margin="0,20,0,12" Width="480">
<TextBlock FontSize="{StaticResource PhoneFontSizeMedium}" Text="{Binding }" TextWrapping="Wrap"/>
</Grid>
</DataTemplate>
</helpers:JumpListFirstItemTemplateSelector.StandardItemTemplate>
</helpers:JumpListFirstItemTemplateSelector>

最后是DataBoundList的XAML

    <telerikData:RadJumpList Margin="18,56,18,-44"
GroupDescriptorsSource="{Binding ChannelGroupDescriptors}"
ItemsSource="{Binding Channels}"
ItemTemplate="{StaticResource JumpListItemTemplate}"
GroupHeaderTemplateSelector="{StaticResource HeaderTemplateSelector}"
x:Name="jumplist"
>
<telerikData:RadJumpList.VirtualizationStrategyDefinition>
<telerikPrimitives:WrapVirtualizationStrategyDefinition Orientation="Horizontal"/>
</telerikData:RadJumpList.VirtualizationStrategyDefinition>
<i:Interaction.Triggers>
<i:EventTrigger EventName="ItemTap">
<GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding ShowChannleDetials, Mode=OneWay}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</telerikData:RadJumpList>

用Command把点选的频道传到VM中去。

效果大致如下,(有些图片出不来,有点没弄明白)

二:具体频道信息

借用前段时间看DEEPDIVEMVVM中学到的,注入一个导航接口,

思路大致就是那个视频中提到的思路,也有源码下载。

    public RelayCommand<Telerik.Windows.Controls.ListBoxItemTapEventArgs> ShowChannleDetials
{
get
{
return showchanneldetials
?? (showchanneldetials = new RelayCommand<Telerik.Windows.Controls.ListBoxItemTapEventArgs>(
(args) =>
{
Channel item = (args.Item.Content) as Channel;
string key = item.ChannelId;
new MyRxGetMethodService().Get("http://douban.fm/j/mine/playlist?type=n&channel=" + item.ChannelId + "&pb=64&from=mainsite").ObserveOn(Deployment.Current).Subscribe(
(result) =>
{
var songs_string = JToken.Parse(result)["song"].ToString();
var MySongs = JsonConvert.DeserializeObject<List<Song>>(songs_string);
if (!SimpleIoc.Default.IsRegistered<ChannelDetailViewModel>(key))
{
SimpleIoc.Default.Register<ChannelDetailViewModel>(
() =>
{
var mainvm = new ChannelDetailViewModel(MySongs,item.ChannelName,item.ChannelIntro,item.ChannelId,item.ChannelImageSource); return mainvm;
}, key);
}
_navigate.NavigateTo(
new Uri(
"/ChannelDetail.xaml?" + key,
UriKind.Relative)); }); }));
}
}

注意new的ChannelDetailViewModel时候注入参数,还有在Ioc中注册

View部分直接使用Telerik的模板:最后效果如下:

要注意在View中也有部分代码:

别忘了在退出这个页面的时候取消掉VM的注册(再点击的过程中会重复注册)

  public partial class ChannelDetail : PhoneApplicationPage
{
private string itemUrl;
public ChannelDetail()
{
InitializeComponent();
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
if (DataContext == null)
{
var url = e.Uri.ToString();
itemUrl = url.Substring(url.IndexOf("?") + ); if (!SimpleIoc.Default.IsRegistered<ChannelDetailViewModel>(itemUrl))
{
MessageBox.Show("Item not found");
return;
} var vm = SimpleIoc.Default.GetInstance<ChannelDetailViewModel>(itemUrl); DataContext = vm;
}
base.OnNavigatedTo(e);
}
protected override void OnNavigatingFrom(System.Windows.Navigation.NavigatingCancelEventArgs e)
{
if (SimpleIoc.Default.IsRegistered<ChannelDetailViewModel>(itemUrl))
{
SimpleIoc.Default.Unregister<ChannelDetailViewModel > (itemUrl);
}
base.OnNavigatingFrom(e);
}
private void Option1_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
this.Option1Viewer.Visibility = System.Windows.Visibility.Visible;
this.Option1Arrow.Visibility = System.Windows.Visibility.Visible;
this.Option2Viewer.Visibility = System.Windows.Visibility.Collapsed;
this.Option2Arrow.Visibility = System.Windows.Visibility.Collapsed;
} private void Option2_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
this.Option1Viewer.Visibility = System.Windows.Visibility.Collapsed;
this.Option1Arrow.Visibility = System.Windows.Visibility.Collapsed;
this.Option2Viewer.Visibility = System.Windows.Visibility.Visible;
this.Option2Arrow.Visibility = System.Windows.Visibility.Visible;
}
}

还有点击图片更新歌曲:

使Songs重新指向一片区域,再raise属性改变,最后效果如下:

     public RelayCommand RefreshCommand
{
get
{
return refreshcommand
?? (refreshcommand = new RelayCommand(
() =>
{
new MyRxGetMethodService().Get("http://douban.fm/j/mine/playlist?type=n&channel=" + ChannelId + "&pb=64&from=mainsite").ObserveOn(Deployment.Current).Subscribe(
(result) =>
{
var songs_string = JToken.Parse(result)["song"].ToString();
var Songs3 = JsonConvert.DeserializeObject<List<Song>>(songs_string);
Song[] tempsongs = new Song[songs.Count];
songs.CopyTo(tempsongs);
List<Song> songstemp1 = new List<Song>(tempsongs);
songstemp1.AddRange(Songs3);
Songs = songstemp1;
});
}));
}
}

三.结语

还有些想法还没实现,今天就到这里吧

使用Telerik控件搭建Doubanfm频道部分的更多相关文章

  1. WinFrom 第三方控件 TeleRik控件

    1.首先从工具-拓展与应用中下载安装  TeleRik WinFroms VsExtensions   TeleRik dll文件     2.工具箱控件  将Telerik控件更新过来 3.新建一个 ...

  2. Telerik 控件事例(鼠标拖动行,拖动列,设置行对齐,行宽,是否显示)

    People.cs using System;using System.Collections.Generic;using System.Data;using System.Linq;using Sy ...

  3. 【Telerik控件学习】-建立自己的图形编辑工具(Diagram)

    Telerik提供了RadDiagram控件,用于图形元素的旋转,拖拽和缩放.更重要的是,它还拓展了许多绑定的命令(复制,剪切,粘贴,回退等等). 我们可以用来组织自己的图形编辑工具. Step1.定 ...

  4. 【Telerik控件学习】-制作3D效果的柱状图(ChartView)

    首先,定义柱状图,并设置自定义的DataTemplate <telerik:RadCartesianChart > <telerik:RadCartesianChart.Horizo ...

  5. Telerik控件集-2019.R1.SP1.All

    Telerik 专注于微软.Net平台的表示层与内容管理控件,提供高度稳定性和丰富性能的组件产品DevCraft,并可应用在非常严格的环境中.Telerik拥有 Microsoft, HP, Alco ...

  6. Telerik 控件本地化

    一共四种方式: Localization using built-in resources Resource keys Localization using ResourceManager Local ...

  7. Telerik 控件 RadGridview实现绑定

    0.使用MiroModes框架请先阅读http://blogs.telerik.com/blogs/posts/10-01-20/micromodels_for_silverlight.aspx 1. ...

  8. telerik 控件 SCRIPT5007: 无法获取未定义或 null 引用的属性“documentElement” (IE 文档模式)

    IE对盒模型的渲染在 Standards Mode和Quirks Mode是有很大差别的,在Standards Mode下对于盒模型的解释和其他的标准浏览器是一样,但在Quirks Mode模式下则有 ...

  9. React Native环境搭建以及几个基础控件的使用

    之前写了几篇博客,但是没有从最基础的开始写,现在想了想感觉不太合适,所以现在把基础的一些东西给补上,也算是我从零开始学习RN的经验吧! 一.环境搭建 首先声明一下,本人现在用的编辑器是SublimeT ...

随机推荐

  1. 移动开发 android 入门开发 阶段视频

    一直想把 android 的开发学习录制成视频,这里录制了一部分供大家学习. http://www.chuanke.com/s5402069.html 到这里,文档,源码,视频基本就全了,祝愿大家能够 ...

  2. 【Flex教程】#009 As/typeof /instanceof /is的作用

    “as” :主要用它做类型转化 假设有一个类叫做Class1,我们声明了一个它的对象 c1,如果想要将它转换成Class2类型,只要这样写: Class2(c1); AS3 中的操作符: as 实现就 ...

  3. 华为OJ平台——尼科彻斯定理

    题目描述: 验证尼科彻斯定理,即:任何一个整数m的立方都可以写成m个连续奇数之和. 例如: 1^3=1 2^3=3+5 3^3=7+9+11 4^3=13+15+17+19 输入 输入一个int整数 ...

  4. devexpress中ASPxGridView控件初始化赋值

    写在ASPxGridView中OnCellEditorInitialize="ASPxGridView_progoods_CellEditorInitialize"  事件中: / ...

  5. 使用VAssistX给文件和函数添加注释-2015.12.31

    在Visual Studio使用VAssistX助手可以非常方便的给文件和函数添加注释,增加更多的记录信息,从而方便在时间久后,对代码阅读理解的提示,以及别人后续对代码的维护和BUG修改. 添加头文件 ...

  6. pxecfg&kickstart生成脚本

    em tm 00:00:00:00:00:12 10.180.1.12 255.255.255.0 173.45.34.25 255.255.255.225 173.45.34.1 em tm 00: ...

  7. Windbg 线程状态笔记

    1.ntdll!ZwWaitForSingleObject 线程被挂起,如果下面跟着是这样子: RetAddr : Args to Child : Call Site `7766e518 : `fff ...

  8. Qt中QObject中的parent参数

    今天写了一个小程序,验证了带参的构造函数中参数parent的作用. 在MainWindow中声明一个QDialog类型的指针,在MainWindow中对它进行初始化.我采用了两种初始化方式,一种是带参 ...

  9. Hadoop SecondaryNameNode备份及恢复

    1.同步各个服务器时间 yum install ntp ntpdate ntp.fudan.edu.cn hdfs-site.xml配置 如果没有配置这一项,hadoop默认是0.0.0.0:5009 ...

  10. Mir2源码详解之服务端-选择(角色)网关(SelGate)

    其实,SelGate也就是 LoginGate,其源码实现完全相同.不必怀疑,市面上的都是这么做~!这里单独写这篇文章,就是为了说明这点!