Xamarin.Forms 特定のキーワードを含むツイートを検索
@ytabuchiさんのTweetに反応して・・・
@ch3coohさんのBlogで紹介されていた、CoreTweetをXamarin.Formsに載せてみました。
C#とCoreTweetを使って特定のキーワードを含むツイートを検索する - 酢ろぐ!
CoreTweetのインストール
パッケージマネージャコンソールで一発でした。
※PCLだけでOKです。
PM> Install-Package CoreTweet 依存関係 'Newtonsoft.Json (≥ 4.5.11)' の解決を試みています。 'Newtonsoft.Json 4.5.11' をインストールしています。 'Newtonsoft.Json 4.5.11' が正常にインストールされました。 'CoreTweet 0.4.0' をインストールしています。 'CoreTweet 0.4.0' が正常にインストールされました。 'Newtonsoft.Json 4.5.11' を SearchTweet に追加しています。 'Newtonsoft.Json 4.5.11' が SearchTweet に正常に追加されました。 'CoreTweet 0.4.0' を SearchTweet に追加しています。 'CoreTweet 0.4.0' が SearchTweet に正常に追加されました。
セルのビュー
↓のコードを殆どそのまま使用しました。
Xamarin.Forms ListViewでTwitter風のレイアウトを作成してみました(機種依存コードなし) - SIN@SAPPOROWORKSの覚書
できた!?
一応できたんだけど・・・何故かAndroidだけ画面が遠慮がちになっている。
Android | iOS | WindowsPhone |
![]() |
![]() |
![]() |
書いたコードは、下記で全部です。PCLのみになってます。
namespace SearchTweet { public class App : Application { public App() { MainPage = new MyPage(); } protected override void OnStart() { // Handle when your app starts } protected override void OnSleep() { // Handle when your app sleeps } protected override void OnResume() { // Handle when your app resumes } } //1つのTweetを表現するクラス internal class Tweet { public string Name { get; set; } //表示名 public string Text { get; set; } //メッセージ public string ScreenName { get; set; } //アカウント名 public string CreatedAt { get; set; } //作成日時 public string Icon { get; set; } //アイコン } internal class MyPage : ContentPage { //データソース(class Tweetのコレクション) private readonly ObservableCollection<Tweet> _tweets = new ObservableCollection<Tweet>(); public MyPage() { var entry = new Entry { HorizontalOptions = LayoutOptions.FillAndExpand, Text = "愛宕" }; var button = new Button() { Text = "Search" }; button.Clicked += (sender, args) => { Refresh(entry.Text); }; var layoutTop = new StackLayout { BackgroundColor = Color.FromRgb(169, 206, 152), Padding = 5, Spacing = 10, Orientation = StackOrientation.Horizontal, Children = {entry, button} }; //ListViewの生成 var listView = new ListView { ItemTemplate = new DataTemplate(typeof (MyCell)), //セルの指定 ItemsSource = _tweets, //データソースの指定 HasUnevenRows = true, //行の高さを可変とする }; var layout = new StackLayout { Padding = new Thickness(0, Device.OnPlatform(20, 0, 0), 0, 0), //iOSのみ上余白 //2015.01.21修正 //VerticalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.Fill, Children = {layoutTop, listView} }; Content = layout; } //セル用のテンプレート private class MyCell : ViewCell { public MyCell() { //アイコン var icon = new Image(); icon.WidthRequest = icon.HeightRequest = 50; //アイコンのサイズ icon.VerticalOptions = LayoutOptions.Start; //アイコンを行の上に詰めて表示 icon.SetBinding(Image.SourceProperty, "Icon"); //名前 var name = new Label {Font = Font.SystemFontOfSize(12)}; name.SetBinding(Label.TextProperty, "Name"); //アカウント名 var screenName = new Label {Font = Font.SystemFontOfSize(12)}; screenName.SetBinding(Label.TextProperty, "ScreenName"); //作成日時 var createAt = new Label {Font = Font.SystemFontOfSize(8), TextColor = Color.Gray}; createAt.SetBinding(Label.TextProperty, "CreatedAt"); //メッセージ本文 var text = new Label {Font = Font.SystemFontOfSize(10)}; text.SetBinding(Label.TextProperty, "Text"); //名前行 var layoutName = new StackLayout { Orientation = StackOrientation.Horizontal, //横に並べる Children = {name, screenName} //名前とアカウント名を横に並べる }; //サブレイアウト var layoutSub = new StackLayout { Spacing = 0, //スペースなし Children = {layoutName, createAt, text} //名前行、作成日時、メッセージを縦に並べる }; View = new StackLayout { Padding = new Thickness(5), Orientation = StackOrientation.Horizontal, //横に並べる Children = {icon, layoutSub} //アイコンとサブレイアウトを横に並べる }; } //テキストの長さに応じて行の高さを増やす protected override void OnBindingContextChanged() { base.OnBindingContextChanged(); //メッセージ var text = ((Tweet)BindingContext).Text; //メッセージを改行で区切って、各行の最大文字数を27として行数を計算する(27文字は、日本を基準にしました) var row = text.Split('\n').Select(l => l.Length / 27).Select(c => c + 1).Sum(); Height = 12 + 8 + row * 10 + 20;//名前行、作成日時行、メッセージ行、パディングの合計値 if (Height < 60) { Height = 60;//列の高さは、最低でも60とする } } } private async void Refresh(string keyword) { const string ApiKey = "p5n9vK9AxxxxxxxxxxTrCVcZ8"; const string ApiSecret = "P07hcAAsF5qHxxxxxxxxxxxxxxxxxxxxHdNZgs9Aebfs63"; const string AccessToke = "109802325-UWdxxxxxxxxxxJxxxxxxxxxxVJGSq4xeQCV"; const string AccessTokeSecret = "llKQWYFh2xxxxxxxxxxxxxxxxxxxaqA89eFg"; var tokens = CoreTweet.Tokens.Create(ApiKey,ApiSecret,AccessToke,AccessTokeSecret); var result = await tokens.Search.TweetsAsync(count => 100, q => keyword); foreach (var tweet in result) { _tweets.Add(new Tweet { Text = tweet.Text, Name = tweet.User.Name, ScreenName = tweet.User.ScreenName, CreatedAt = tweet.CreatedAt.ToString("f"), Icon = tweet.User.ProfileImageUrl.ToString() }); } } } }
画像付きのツイートを検索する
Androidで画面が遠慮がちになっているし・・・・
@ch3coohさんの所では、Mediaタグの有無で画像付きツイートの検索を紹介されてましたが・・・
力尽きたので、今日はもう寝ます。
[2015.01.21追記]
「Androidで画面が遠慮がち」の原因が分かりました。
画面全体のStackLayoutのVerticalOptionsが、Centerになっていました。これをFillに変更することで問題は解消しました。
ある意味、当たり前のオチでした。
var layout = new StackLayout { Padding = new Thickness(0, Device.OnPlatform(20, 0, 0), 0, 0), //iOSのみ上余白 //VerticalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.Fill, Children = {layoutTop, listView} };
AndroidのListViewコントロールのデフォルトの高さが、画面の高さより小さかったって事でしょうか・・・