• [转载]新浪微博客户端围脖七开发笔记(4) 实现SinaService接口


    新浪微博客户端围脖七开发笔记(4) 实现SinaService接口

    经过前面的准备,现在可以动手实现SinaService接口和界面布局啦!

    SinaService的实现不难,用linq解析下xml就好了。AppKey,用户名,密码就要自己去申请啦。

    代码
    private void InitWebClient(ref WebClient wc)
    {
    wc
    = new WebClient();
    string usernamePassword = Settings.Username + ":" + Settings.Password;
    wc.Credentials
    = new NetworkCredential(Settings.Username, Settings.Password);
    wc.Headers[
    "Authorization"] = "Basic " + Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(usernamePassword));
    }

    /// <summary>
    /// Gets the statuses.
    /// </summary>
    /// <param name="onGetStatusesCompleted">The on get Statuses completed.</param>
    /// <param name="onError">The on error.</param>
    public void GetStatuses(Int64 sinceId, Int64 maxId,
    Action
    <List<Status>> onGetStatusesCompleted = null, Action<Exception> onError = null, Action onFinally = null)
    {
    WebClient wcRefreshHome
    = null;

    InitWebClient(
    ref wcRefreshHome);

    //if (wcRefreshHome.IsBusy) wcRefreshHome.CancelAsync();

    // register on download complete event
    wcRefreshHome.DownloadStringCompleted += delegate(object sender, DownloadStringCompletedEventArgs e)
    {
    try
    {
    // report error
    if (e.Error != null)
    {
    if (onError != null)
    {
    onError(e.Error);
    }
    return;
    }

    XElement xmlResult
    = XElement.Parse(e.Result);

    List
    <Status> list = new List<Status>();

    ParseService.ParseTimeLine(xmlResult,
    ref list);

    // notify completed callback
    if (onGetStatusesCompleted != null)
    {
    onGetStatusesCompleted(list);
    }
    }
    catch(Exception ex)
    {
    Trace.DetailMsg(ex.Message);
    if (onError != null)
    {
    onError(ex);
    }
    return;
    }
    finally
    {
    // notify finally callback
    if (onFinally != null)
    {
    onFinally();
    }
    }
    };

    string requestUrl = Settings.RefreshHomeURL + "?source=" + Settings.AppKey;

    //The list is empty, just get some status
    if (sinceId == 0 && maxId == 0)
    {
    requestUrl
    = requestUrl + "&count=" + Settings.NumberPerRequest;
    }

    //Get status later than sinceId
    if (sinceId != 0 && maxId == 0)
    {
    requestUrl
    = requestUrl + "&since_id=" + (sinceId+1) + "&count=" + Settings.NumberPerRequest;
    }

    //Get status early than maxId
    if (sinceId == 0 && maxId != 0)
    {
    requestUrl
    = requestUrl + "&max_id=" + (maxId-1) + "&count=" + Settings.NumberPerRequest;
    }

    wcRefreshHome.DownloadStringAsync(
    new Uri(requestUrl), Settings.RefreshHomeURL);

    }

    }

    相应的ParseService如下:

    代码
    public static class ParseService
    {
    public static void ParseTimeLine(XElement xElement, ref List<Status> statusList)
    {
    try
    {
    foreach (XElement status in xElement.Descendants("status"))
    {
    statusList.Add(ParseStatus(status));
    }
    }
    catch (FormatException ex)
    {
    Deployment.Current.Dispatcher.BeginInvoke(()
    =>
    {
    MessageBox.Show(ex.Message.ToString());
    });
    }
    }

    private static void ParseUserList(XElement xElement, ref List<User> userList )
    {
    try
    {
    foreach (XElement user in xElement.Descendants("user"))
    {
    User friend
    = new User();

    userList.Add(ParseUser(user));
    }
    }

    catch (FormatException ex)
    {
    Deployment.Current.Dispatcher.BeginInvoke(()
    =>
    {
    MessageBox.Show(ex.Message.ToString());
    });
    }
    }

    private static Status ParseStatus(XElement status)
    {
    Status newStatus
    = new Status();
    try
    {
    newStatus.Id
    = long.Parse(status.Element("id").Value);
    newStatus.Text
    = status.Element("text").Value;

    Regex regex
    = new Regex(">.*<");
    newStatus.Source
    = status.Element("source").Value;
    Match match
    = regex.Match(newStatus.Source);
    if (match.Success)
    {
    newStatus.Source
    = match.ToString().Replace("<", string.Empty).Replace(">", string.Empty);
    }

    newStatus.CreatedAt
    = DateTime.ParseExact(status.Element("created_at").Value,
    "ddd MMM dd HH:mm:ss zzzz yyyy",
    CultureInfo.CurrentCulture,
    DateTimeStyles.AllowWhiteSpaces);

    newStatus.Favorited
    = bool.Parse(status.Element("favorited").Value);

    //newTweet.Retweeted = bool.Parse(status.Element("retweeted").Value);

    //newTweet.RetweetCount = int.Parse(status.Element("retweet_count").Value);

    newStatus.User
    = ParseUser(status.Element("user"));

    //if (!status.Element("thumbnail_pic").IsEmpty)
    //{
    // newStatus.ThumbnailPic = status.Element("thumbnail_pic").Value;
    //}

    newStatus.ThumbnailPic
    = status.Element("thumbnail_pic").Value;

    }
    catch (Exception ex)
    {
    Trace.DetailMsg(
    "ParseStatus Error: " + ex.Message);
    }

    return newStatus;
    }

    private static User ParseUser(XElement User)
    {
    User user
    = new User();
    try
    {
    user.Id
    = ulong.Parse(User.Element("id").Value);
    user.ScreenName
    = User.Element("screen_name").Value;
    user.Name
    = User.Element("name").Value;
    user.ImageUrl
    = User.Element("profile_image_url").Value;
    user.Url
    = User.Element("url").Value;
    user.Followers
    = int.Parse(User.Element("followers_count").Value);
    user.Friends
    = int.Parse(User.Element("friends_count").Value);
    user.Description
    = User.Element("description").Value;
    user.Location
    = User.Element("location").Value;
    user.CreatedAt
    = DateTime.ParseExact(User.Element("created_at").Value,
    "ddd MMM dd HH:mm:ss zzzz yyyy",
    CultureInfo.CurrentCulture,
    DateTimeStyles.AllowWhiteSpaces);
    }
    catch (Exception ex)
    {
    Trace.DetailMsg(
    "ParseUser Error: " + ex.Message);
    }
    return user;
    }

    }

    主页面用到了Pivot Control

    代码
    <Grid x:Name="LayoutRoot" Background="Transparent">

    <ProgressBar IsIndeterminate="{Binding IsHomeRefreshing}" VerticalAlignment="Top"
    Visibility
    ="{Binding IsHomeRefreshing, Converter={StaticResource VisibilityConverter}}"/>

    <!--Pivot Control-->
    <controls:Pivot Title="围脖七">
    <!--Pivot item one-->
    <controls:PivotItem>
    <controls:PivotItem.Header>
    <ContentControl>
    <StackPanel>
    <TextBlock Text="主页" FontSize="54"/>
    </StackPanel>
    </ContentControl>
    </controls:PivotItem.Header>
    <ListBox d:LayoutOverrides="Height" Grid.Row="1" d:IsHidden="True"
    ItemsSource
    ="{Binding HomeList, Mode=OneWay}" ItemTemplate="{StaticResource TweetItemTemplate}"
    SelectionChanged
    ="ListBox_SelectionChanged"/>
    </controls:PivotItem>

    <!--Pivot item two-->
    <controls:PivotItem>
    <controls:PivotItem.Header>
    <ContentControl>
    <TextBlock Text="消息" FontSize="54" FontFamily="Segoe WP Light"/>
    </ContentControl>
    </controls:PivotItem.Header>
    <Grid VerticalAlignment="Top">
    <ListBox x:Name="TopicList" ItemsSource="{Binding TopicList, Mode=OneWay}"/>
    </Grid>
    </controls:PivotItem>
    </controls:Pivot>
    </Grid>

    每条微博的DataTemplate如下

    代码
    <DataTemplate x:Name="TweetItemTemplate">
    <Grid Margin="0,5">
    <Grid.ColumnDefinitions>
    <ColumnDefinition Width="Auto"/>
    <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Image Grid.Column="0" Source="{Binding User.ImageUrl}"
    Height
    ="73" Width="73" VerticalAlignment="Top" Margin="0,5,7,0"
    HorizontalAlignment
    ="Left"/>
    <StackPanel Grid.Column="1" VerticalAlignment="Top">
    <Grid Width="380">
    <TextBlock Text="{Binding User.ScreenName}" VerticalAlignment="Center" Foreground="#FFC8AB14" FontSize="24"/>
    <StackPanel HorizontalAlignment="Right" Orientation="Horizontal" VerticalAlignment="Center">
    <Image Source="/Images/Tulips.png" Visibility="{Binding ThumbnailPic, Converter={StaticResource VisibilityConverter}}"/>
    <TextBlock Text="{Binding CreatedAt, Converter={StaticResource TimeConverter}}"
    FontSize
    ="20" Foreground="LightGray"
    Margin
    ="5,0"/>
    </StackPanel>
    </Grid>
    <!--TextBlock Text="{Binding Text}" FontSize="22" TextWrapping="Wrap"/-->
    <TextBlock Text="{Binding Text}" TextWrapping="Wrap" FontFamily="Arial"/>
    </StackPanel>
    </Grid>
    </DataTemplate>

    记得在MainPageViewModel的构造函数中调用RefreshHomeList

    代码
    if (!DesignerProperties.IsInDesignTool)
    {
    if (HomeList.Count == 0)
    {
    RefreshHomeList(
    0, 0);
    }
    }

    最后把viewmodel和view联系起来,在App.xaml中声明

    代码
    xmlns:viewModels="clr-namespace:WeiBo7.ViewModels"

    <Application.Resources>
    <misc:VisibilityConverter x:Key="VisibilityConverter"/>
    <misc:TimeConverter x:Key="TimeConverter"/>
    <viewModels:MainPageViewModel x:Key="MainPageViewModel" />

    </Application.Resources>

    在MainPage.xaml中声明就大功告成了!

    DataContext="{StaticResource MainPageViewModel}"

    因为间隔时间比较长,上面只是提到了些关键实现,有些地方可能忘记了。如有问题请留言给我!



  • 相关阅读:
    Codeforces Round #599 (Div. 2) B2. Character Swap (Hard Version) 构造
    Codeforces Round #598 (Div. 3) F Equalizing Two Strings(构造题)
    codeforces round # 384 div2 B Chloe and the sequence 神奇二进制找规律题
    codeforces round #384 div2 C Vladik and fractions(构造)
    线段树板子
    Codeforces Round #616 (Div. 2) D (找规律题)
    codeforces round #616 div2 A (Even but not even)水题
    2017的计划清单
    回顾2016,我的简单总结
    关于ubuntu下sublime text 3 的安装和中文配置问题
  • 原文地址:https://www.cnblogs.com/fx2008/p/2457387.html
Copyright © 2020-2023  润新知