我正在为Android开发应用程序,它基本上是一个新闻提要阅读器并且卡住了。我正在从一个网站解析xml,现在我有一个列表视图,其中我代表了标题,日期,编写器等,但现在当用户点击其中一个项目时我想打开该项目并显示文本(新闻)这是我的代码:`
using System;
using System.Collections.Generic;
using Android.App;
using Android.Widget;
using Android.Views;
using Android.Media;
namespace NewsFeedReader
{
public class FeedItemListAdapter : BaseAdapter<FeedItem>
{
protected Activity context;
protected List<FeedItem> feedList = new List<FeedItem>();
public FeedItemListAdapter ( Activity context, List<FeedItem> feedList) : base()
{
this.context = context;
this.feedList = feedList;
}
public override FeedItem this [int position]
{
get { return this.feedList [position]; }
}
public override long GetItemId (int position)
{
return position;
}
public override int Count
{
get {
return this.feedList.Count;
}
}
public override View GetView (int position, View convertView, ViewGroup parent)
{
var feedItem = this.feedList [position];
var view = convertView ?? context.LayoutInflater.Inflate (Resource.Layout.FeedLayout, parent, false) as LinearLayout;
view.FindViewById<TextView> (Resource.Id.Title).Text = feedItem.Title.Length < 50 ? feedItem.Title : feedItem.Title.Substring (0, 50) + "...";
view.FindViewById<TextView> (Resource.Id.writer).Text = feedItem.Creator;
view.FindViewById<TextView> (Resource.Id.PubDate).Text = feedItem.PubDate.ToString ("dd/MM/yyyy HH:mm");
var imageView = view.FindViewById<ImageView> (Resource.Id.ListviewImage);
Koush.UrlImageViewHelper.SetUrlDrawable (imageView, feedItem.Image, Resource.Drawable.Icon);
return view;
}
}
}`
using System;
using System.Collections.Generic;
using System.Net;
using System.IO;
using System.Xml;
namespace NewsFeedReader
{
static internal class FeedService
{
internal static List<FeedItem> GetFeedItems (string url)
{
List<FeedItem> FeedItemList = new List<FeedItem> ();
try
{
WebRequest webRequest = WebRequest.Create (url);
WebResponse webResponse = webRequest.GetResponse();
Stream stream = webResponse.GetResponseStream ();
XmlDocument xmlDoc = new XmlDocument ();
xmlDoc.Load (stream);
XmlNamespaceManager xmlNM = new XmlNamespaceManager(xmlDoc.NameTable);
xmlNM.AddNamespace("dc", xmlDoc.DocumentElement.GetNamespaceOfPrefix("dc"));
xmlNM.AddNamespace("content", xmlDoc.DocumentElement.GetNamespaceOfPrefix("content"));
XmlNodeList xmlNode = xmlDoc.SelectNodes("rss/channel/item");
for (int i = 0; i < xmlNode.Count; i++)
{
FeedItem feedItem = new FeedItem();
if (xmlNode[i].SelectSingleNode("title") != null)
{
feedItem.Title = xmlNode[i].SelectSingleNode("title").InnerText;
}
if (xmlNode[i].SelectSingleNode("content:encoded", xmlNM) != null)
{
feedItem.Content = xmlNode[i].SelectSingleNode("content:encoded", xmlNM).InnerText;
}
if (xmlNode[i].SelectSingleNode("link") != null)
{
feedItem.Link = xmlNode[i].SelectSingleNode("link").InnerText;
}
if (xmlNode[i].SelectSingleNode("pubDate") != null)
{
feedItem.PubDate = Convert.ToDateTime(xmlNode[i].SelectSingleNode("pubDate").InnerText);
}
if (xmlNode[i].SelectSingleNode("category") != null)
{
feedItem.Category = xmlNode[i].SelectSingleNode("category").InnerText;
}
if (xmlNode[i].SelectSingleNode("description") != null)
{
feedItem.Description = xmlNode[i].SelectSingleNode("description").InnerText;
}
if (xmlNode[i].SelectSingleNode("image") != null)
{
feedItem.Image = xmlNode[i].SelectSingleNode("image").InnerText;
}
if (xmlNode[i].SelectSingleNode("dc:creator", xmlNM) != null)
{
feedItem.Creator = xmlNode[i].SelectSingleNode("dc:creator", xmlNM).InnerText;
}
else
{
feedItem.Content = feedItem.Description;
}
FeedItemList.Add(feedItem);
}
}
catch(Exception)
{
throw;
}
return FeedItemList;
}
}
}
using System;
using Android.Widget;
namespace NewsFeedReader
{
public class FeedItem
{
public FeedItem ()
{
}
public string Title {
get;
set;
}
public string Content {
get;
set;
}
public DateTime PubDate {
get;
set;
}
public string Creator {
get;
set;
}
public string Description {
get;
set;
}
public string Category {
get;
set;
}
public string Link {
get;
set;
}
public string Image {
get;
set;
}
}
}
现在我将发布我遇到问题的部分:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using Android.Support.V7.App;
using ToolbarV7 = Android.Support.V7.Widget.Toolbar;
using Android.Support.V4.Widget;
namespace NewsFeedReader
{
[Activity(Label = "Krajina.ba", MainLauncher = true, Icon = "@drawable/icon", Theme="@style/MyTheme")]
public class MainActivity : ActionBarActivity
{
private ActionBarDrawerToggle actionBarDrawerToggle;
Context context;
ToolbarV7 toolbar;
DrawerLayout drawerLayout;
ListView leftListView;
ListView rightListView;
ArrayAdapter leftArrayAdapter;
ArrayAdapter rightArrayAdapter;
List<string> leftList;
List<string> rightList;
private HorizontalScrollView horizontalScroll;
private List<FeedItem> list;
private ListView feedItemLisView;
private ProgressDialog progressDialog;
public static string MTitle = "";
public static string Pubdate = "";
public static string Description = "";
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
drawerLayout = FindViewById<DrawerLayout> (Resource.Id.drawer_layout);
leftListView = FindViewById<ListView> (Resource.Id.left_drawer);
rightListView = FindViewById<ListView> (Resource.Id.right_drawer);
toolbar = FindViewById<ToolbarV7> (Resource.Id.toolbar);
leftListView.Tag = 0;
rightListView.Tag = 1;
actionBarDrawerToggle = new ActionBarDrawerToggle (
this,
drawerLayout,
Resource.String.OpenDrawer,
Resource.String.ClosedDrawer
);
this.feedItemLisView = this.FindViewById<ListView> (Resource.Id.feedItemListView);
//this.feedItemListViewTop = this.FindViewById<ListView> (Resource.Id.feedItemListViewTop);
this.horizontalScroll = this.FindViewById<HorizontalScrollView> (Resource.Id.myHorizontalScroll);
leftList = new List<string> ();
leftList.Add ("BIH");
leftList.Add ("SPORT");
leftList.Add ("SVIJET");
leftList.Add ("MAGAZIN");
leftList.Add ("SCITECH");
leftList.Add ("ZANIMLJIVOSTI");
leftArrayAdapter = new ArrayAdapter<string> (
this,
Android.Resource.Layout.SimpleListItem1,
leftList);
leftListView.Adapter = leftArrayAdapter;
rightList = new List<string> ();
rightList.Add ("BIHAĆ");
rightList.Add ("CAZIN");
rightList.Add ("BOSANSKA KRUPA");
rightList.Add ("BUŽIM");
rightList.Add ("BOSANSKI PETROVAC");
rightList.Add ("VELIKA KLADUŠA");
rightList.Add ("KLJUČ");
rightList.Add ("SANSKI MOST");
rightArrayAdapter = new ArrayAdapter<string> (
this,
Android.Resource.Layout.SimpleListItem1,
rightList);
rightListView.Adapter = rightArrayAdapter;
SetSupportActionBar (toolbar);
drawerLayout.SetDrawerListener (actionBarDrawerToggle);
SupportActionBar.SetHomeButtonEnabled (true);
SupportActionBar.SetDisplayHomeAsUpEnabled (true);
actionBarDrawerToggle.SyncState ();
this.progressDialog = new ProgressDialog (this);
this.progressDialog.SetMessage ("Aplikacija u pripremi...");
GetItemList ();
}
private void GetItemList()
{
this.progressDialog.Show ();
Task<List<FeedItem>> task = Task.Factory.StartNew (() => {
return FeedService.GetFeedItems ("http://www.krajina.ba/feed/");
});
Task task2 = task.ContinueWith ((s) => {
try {
this.progressDialog.Dismiss ();
this.list = s.Result;
this.PopulateListView(this.list);
}
catch (AggregateException ex)
{
Toast.MakeText (this, ex.InnerException.Message, ToastLength.Short).Show ();
}
}, TaskScheduler.FromCurrentSynchronizationContext());
}
private void PopulateListView(List<FeedItem> listView)
{
var adapter = new FeedItemListAdapter (this, listView);
this.feedItemLisView.Adapter = adapter;
this.feedItemLisView.ItemClick += (object sender, AdapterView.ItemClickEventArgs e) =>
{
var myAdpter = e.Parent.GetItemAtPosition(e.Position);
FeedItem items = new FeedItem();
var newsDetail = new Intent(Application.Context, typeof(FeedDetails));
newsDetail.PutExtra(MTitle, items.Title);
newsDetail.PutExtra(Description, items.Content);
StartActivity(newsDetail);
/*Intent i = new Intent(this, typeof(FeedDetails));
i.PutExtra("item", JsonConvert.SerializeObject(items));
StartActivity(i);*/
};
}
private void PopulateLayout(List<FeedItem> feedItems)
{
var adapter = new MainFeedAdapter (this, feedItems);
//this.horizontalScroll.Adapter = adapter;
}
public override bool OnOptionsItemSelected (IMenuItem item)
{
switch (item.ItemId)
{
case Android.Resource.Id.Home:
drawerLayout.CloseDrawer (rightListView);
actionBarDrawerToggle.OnOptionsItemSelected (item);
return true;
case Resource.Id.action_refresh:
return true;
case Resource.Id.action_help:
if (drawerLayout.IsDrawerOpen (rightListView)) {
drawerLayout.CloseDrawer (rightListView);
} else {
drawerLayout.OpenDrawer (rightListView);
drawerLayout.CloseDrawer (leftListView);
}
return true;
default:
return base.OnOptionsItemSelected (item);
}
}
public override bool OnCreateOptionsMenu (IMenu menu)
{
MenuInflater.Inflate (Resource.Menu.action_menu, menu);
return base.OnCreateOptionsMenu (menu);
}
}
}
此处尝试从MainActivity接收数据并打开新闻文章:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using System.Threading.Tasks;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
namespace NewsFeedReader
{
[Activity (Label = "FeedDetails")]
public class FeedDetails : Activity
{
FeedItem list = new FeedItem ();
public static string title = "";
public static string description = "";
protected override void OnCreate (Bundle savedInstanceState)
{
base.OnCreate (savedInstanceState);
// Create your application here
SetContentView(Resource.Layout.FeedDetails);
//FeedItem feedItem = JsonConvert.DeserializeObject<FeedItem> (Intent.GetStringExtra("item"));
title = Intent.GetStringExtra(MainActivity.MTitle);
description = Intent.GetStringExtra (MainActivity.Description);
FindViewById<TextView> (Resource.Id.FeedDetailsTitle).Text = title;
FindViewById<TextView> (Resource.Id.FeedDetailsContent).Text = description;
}
}
}
希望你能知道我想要完成什么以及如何解决这个问题。谢谢!
答案 0 :(得分:2)
private void PopulateListView(List<FeedItem> listView)
{
var adapter = new FeedItemListAdapter (this, listView);
this.feedItemLisView.Adapter = adapter;
this.feedItemLisView.ItemClick += (object sender, AdapterView.ItemClickEventArgs e) =>
{
var myitem = adapter.GetItemAtPosition(e.Position);
//do something with selected feeditem
};
答案 1 :(得分:1)
(这个问题也在xamarin-android
gitter channel上提出。总结一下。)
您的应用存在两个相互关联的问题:
Intent.PutExtra()
要求该密钥包含“包前缀”Intent.PutExtra()
实际提供值。关于(1),回想一下PutExtra()
用法:
partial class MainActivity {
public static string MTitle = "";
public static string Description = "";
void PopulateListView(List<FeedItem> listView)
{
...
var newsDetail = new Intent(...);
newsDetail.PutExtra(MTitle, items.Title);
newsDetail.PutExtra(Description, items.Description);
}
}
问题是MTitle
和Description
都不包含“包前缀”。更糟糕的是,它们具有相同的值,这意味着newsDetail.PutExtra(Description, ...)
调用将替换之前的newsDetail.PutExtra(MTitle, ...)
调用的值。
修复方法是为这些键提供唯一的非空值:
partial class MainActivity {
public const string MTitle = "your.package.name.Title";
public const string Description = "your.package.name.Description";
}
关于(2),请回忆newsDetail.PutExtra()
代码,并附上更多背景信息:
newsDetail = new Intent(Application.Context, typeof(FeedDetails));
FeedItem items = new FeedItem();
newsDetail.PutExtra(MTitle, items.Title);
newsDetail.PutExtra(Description, items.Content);
此处的问题是items
尚未初始化。因此,items.Title
和items.Content
两者都是空字符串。要解决此问题,请初始化这些值:
var item = adapter [e.Position];
newsDetail = new Intent(Application.Context, typeof(FeedDetails));
FeedItem items = new FeedItem() {
Title = item.Title,
Content = item.Content,
};
newsDetail.PutExtra(MTitle, items.Title);
newsDetail.PutExtra(Description, items.Content);