How to get data by json on xamarin android - json

public async override void OnActivityCreated (Bundle savedInstanceState)
{
base.OnActivityCreated (savedInstanceState);
lst = View.FindViewById<ListView> (Resource.Id.lstHome);
var result = await json.GetStringbyJson ("https://api-v2.soundcloud.com/explore/Popular+Music?tag=out-of-experiment&limit=20&linked_partitioning=1");
if (result != null)
{
var items = Newtonsoft.Json.JsonConvert.DeserializeObject<TrackModel.RootObject> (result);
lst.Adapter = new TrackAdapter(Activity, items.tracks);
}
}
public class TrackAdapter:BaseAdapter
{
LayoutInflater _inflater;
List<TrackModel.Track> _tracks;
public TrackAdapter(Context context, List<TrackModel.Track> tracks)
{
_inflater=LayoutInflater.FromContext(context);
_tracks=tracks;
}
public override TrackModel.Track this[int index]
{
get{ return _tracks [index]; }
}
public override int Count{
get{ return _tracks.Count; }
}
public override long GetItemId(int position)
{
return position;
}
public override View GetView(int position, View convertView,ViewGroup parent)
{
View view = convertView ?? _inflater.Inflate (Resource.Layout.ExploreFragment, parent, false);
var track = _tracks [position];
var viewHolder = view.Tag as TrackViewHolder;
if (viewHolder == null) {
viewHolder.Title = view.FindViewById<TextView> (Resource.Id.textviewItems);
viewHolder.SubTitle = view.FindViewById<TextView> (Resource.Id.textviewSubItem);
viewHolder.Image = view.FindViewById<ImageView> (Resource.Id.image);
view.Tag = viewHolder;
}
viewHolder.Title.Text = track.title;
viewHolder.SubTitle.Text = track.track_type;
Android.Net.Uri uri = Android.Net.Uri.Parse (track.artwork_url);
viewHolder.Image.SetImageURI(uri);
return view;
}
}
public class TrackViewHolder:Java.Lang.Object
{
public TextView Title{ get; set;}
public TextView SubTitle{get;set;}
public ImageView Image{ get; set;}
}
public override TrackModel.Track this[int index]. It get a error is makred as an overdie but no suitable indexer found to overide.
I want to take data from json up listview on xamarin android.
If it is unviersal app then it easy to use.

The way you want to set the adapter for your listview will not work that way.
Setting the adapter property of the listview inside the foreach loop is totally wrong. The same applies to your textviews.
You need to implement a custom adapter that loads a layout for each of your track list item. Your custom adapter could look like the following example I've written out of my mind with out further testing. But it implements the required methods a custom adapter needs to implement.
The important part is the GetView method that returns your track layout every time the listview ask for a new item to represent. To keep the app memory down it uses the ViewHolder pattern, which isn't required if you want to use the RecycleView.
public class TrackAdapter : BaseAdapter<Tracks>
{
LayoutInflater _inflater;
List<Tracks> _tracks;
public TrackAdapter(Context context, List<Tracks) tracks)
{
_inflater = LayoutInflater.FromContext(context);
_tracks = tracks;
}
public override Tracks this [int index]
{
get { return _tracks[index]; }
}
public override int Count
{
get { return _tracks.Count; }
}
public override long GetItemId(int position)
{
return position;
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
View view = convertView ?? _inflater.Inflate(Resource.Layout.TrackListItem, parent, false);
var track = _tracks[position];
var viewHolder = view.Tag as TrackViewHolder;
if (viewHolder == null)
{
viewHolder = new TrackViewHolder();
viewHolder.Title = view.FindViewById<TextView>(Resource.Id.textviewItems);
viewHolder.Subtitle = view.FindViewById<TextView>(Resource.Id.textviewSubItems);
viewHolder.Image = view.FindViewById<ImageView>(Resource.Id.image);
view.Tag = viewHolder;
}
viewHolder.Title.Text = track.title;
viewHolder.SubTitle.Text = track.track_type;
viewHolder.Image.SetImageURI(Uri(track.artwork_url));
return view;
}
class TrackViewHolder : Java.Lang.Object
{
public TextView Title { get; set; }
public TextView SubTitle { get; set; }
public ImageView Image { get; set; }
}
}
The layout will contain your title, subtitle and image and could easily build with a normal layout file.
In your fragment you then create a new instance for TrackAdapter pass the context and the list of tracks you want to be shown in the listview.
public override void OnActivityCreated (Bundle savedInstanceState)
{
base.OnActivityCreated (savedInstanceState);
lst = View.FindViewById<ListView> (Resource.Id.lstHome);
var result = json.GetStringbyJson ("https://api-v2.soundcloud.com/explore/Popular+Music?tag=out-of-experiment&limit=20&linked_partitioning=1");
if (result != null)
{
var items = JsonConvert.DeserializeObject<TrackModel.RootObject> (result);
lst.Adapter = new TrackAdapter(Activity, items.tracks);
}
}

Related

how to open specific/different Activity in the recyclerview whose data is from json using volley

I want to open new activity that is different in each recyclerview item.
I have read and I do not need an image item here : How to open a different activity on recyclerView item onclick
This is my Adapter
public class B001Adapter extends RecyclerView.Adapter {
private Context context;
private LayoutInflater inflater;
List<B001Data> udata = Collections.emptyList();
public B001Adapter(Context context, List<B001Data> data) {
this.context = context;
inflater = LayoutInflater.from(context);
this.udata = data;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.datab001, parent, false);
MyHolder holder = new MyHolder(view);
return holder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
MyHolder myHolder = (MyHolder) holder;
final B001Data current = udata.get(position);
myHolder.device_name.setText(current.device_name);
myHolder.mac_address.setText(current.mac_address);
myHolder.status.setText("Status:" + String.valueOf(current.status));
}
#Override
public int getItemCount() {
return udata.size();
}
class MyHolder extends RecyclerView.ViewHolder {
TextView device_name, mac_address, status;
public MyHolder(View itemView) {
super(itemView);
context = itemView.getContext();
device_name = (TextView) itemView.findViewById(R.id.txt_device_name);
mac_address = (TextView) itemView.findViewById(R.id.txt_mac_address);
status = (TextView) itemView.findViewById(R.id.txt_status);
}
public void onClick(AdapterView<?> parent, View view, int position {
final Intent intent;
switch (getAdapterPosition()){
case 0:
intent = new Intent(context, MainActivity.class);
break;
case 1:
intent = new Intent(context, B001FacilityM.class);
break;
case 2:
intent = new Intent(context, B001HRD.class);
break;
default:
intent = new Intent(context, B001home.class);
break;
}
context.startActivity(intent);
}
}
}
I use volley to get Json data displayed on the recyclerView. Looking for your advice. Thanks
First You Should assign id to layout file (R.layout.datab001),
find out id using findViewsById in MyHolder() constructor
and then set onClickListener to layout like myHolder.layout.setOnClickListener(....);
in onBindViewHolder().
or check other answer
RecyclerView onClick

MVC6 alternative to #Html.DisplayFor

MVC6 introduces Tag Helpers which is a better way compared to using #Html.EditorFor, etc. However I have not found any Tag Helper that would be an alternative to #Html.DisplayFor.
Of course I can use a variable directly on a Razor page, such as #Model.BookingCode. But this does not allow to control formatting.
With MVC6, what's conceptually correct way for displaying a value of a model property?
#Html.DisplayFor still exists and can still be used.
The difference between HtmlHelpers and TagHelpers is that HtmlHelpers choose which html elements to render for you whereas TagHelpers work with html tags that you add yourself so you have more full control over what html element is used. You do have some control over the markup using templates with HtmlHelpers but you have more control with TagHelpers.
So you should think in terms of what html markup do I want to wrap this model property in and add that markup around the property itself using #Model.Property with some markup around it or continue using DisplayFor if you prefer to let the helper decide.
You can create your own tag helper
namespace MyDemo.TagHelpers
{
[HtmlTargetElement("p", Attributes = ForAttributeName)]
public class DisplayForTagHelper : TagHelper
{
private const string ForAttributeName = "asp-for";
[HtmlAttributeName(ForAttributeName)]
public ModelExpression For { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (output == null)
{
throw new ArgumentNullException(nameof(output));
}
var text = For.ModelExplorer.GetSimpleDisplayText();
output.Content.SetContent(text);
}
}
}
Add use it in view:
<p asp-for="MyProperty" class="form-control-static"></p>
I have been using this as a display tag helper.
[HtmlTargetElement("*", Attributes = ForAttributeName)]
public class DisplayForTagHelper : TagHelper
{
private const string ForAttributeName = "asp-display-for";
private readonly IHtmlHelper _html;
public DisplayForTagHelper(IHtmlHelper html)
{
_html = html;
}
[HtmlAttributeName(ForAttributeName)]
public ModelExpression Expression { get; set; }
public IHtmlHelper Html
{
get
{
(_html as IViewContextAware)?.Contextualize(ViewContext);
return _html;
}
}
[HtmlAttributeNotBound]
[ViewContext]
public ViewContext ViewContext { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
if (context == null)
throw new ArgumentNullException(nameof(context));
if (output == null)
throw new ArgumentNullException(nameof(output));
var type = Expression.Metadata.UnderlyingOrModelType;
if (type.IsPrimitive)
{
output.Content.SetContent(Expression.ModelExplorer.GetSimpleDisplayText());
}
// Special Case for Personal Use
else if (typeof(Dictionary<string, string>).IsAssignableFrom(type))
{
output.Content.SetHtmlContent(Html?.Partial("Dictionary", Expression.ModelExplorer.Model));
}
else
{
var htmlContent = Html.GetHtmlContent(Expression);
output.Content.SetHtmlContent(htmlContent);
}
}
}
public static class ModelExpressionExtensions
{
public static IHtmlContent GetHtmlContent(this IHtmlHelper html, ModelExpression expression)
{
var ViewEngine = html.ViewContext.HttpContext.RequestServices.GetService(typeof(ICompositeViewEngine)) as ICompositeViewEngine;
var BufferScope = html.GetFieldValue<IViewBufferScope>();
var htmlContent = new TemplateBuilder(ViewEngine, BufferScope, html.ViewContext, html.ViewContext.ViewData, expression.ModelExplorer, expression.Name, null, true, null).Build();
return htmlContent;
}
public static TValue GetFieldValue<TValue>(this object instance)
{
var type = instance.GetType();
var field = type.GetFields(BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance).FirstOrDefault(e => typeof(TValue).IsAssignableFrom(e.FieldType));
return (TValue)field?.GetValue(instance);
}
}
try below code
public class movie
{
public int ID { get; set; }
[DisplayName("Movie Title")]
public string Title { get; set; }
}
///////////////////////////////////////////////////
#model IEnumerable<MvcMovie.Models.Movie>
<h1>Show List Movies</h1>
<label asp-for="ToList()[0].Title">< /label>
#foreach (var movie in Model)
{
#movie.Title
}

How does Asp.net Core renders a view

How does MVC 6 renders a view. What's the actual method in Razor ViewEngine that generates the html output? Also if possible please explain the process of rendering a view.
May be you could point me to a file on mvc source on github. thanks!
Here is a complete solution of what you are looking for. I used dependency injection to get the HtmlHelper in the controller. You can inject your own helper if you want too.
using Microsoft.AspNet.Html.Abstractions;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Mvc.ViewEngines;
using Microsoft.AspNet.Mvc.ViewFeatures;
using Microsoft.AspNet.Mvc.ViewFeatures.Internal;
using Microsoft.Extensions.WebEncoders;
using System.ComponentModel.DataAnnotations;
using System;
public class MyController : Controller
{
private readonly IHtmlGenerator htmlGenerator;
ICompositeViewEngine viewEngine;
IModelMetadataProvider metadataProvider;
private readonly IHtmlHelper helper;
IHtmlEncoder htmlEncoder;
IUrlEncoder urlEncoder;
IJavaScriptStringEncoder javaScriptStringEncoder;
public MyController(IHtmlHelper helper, IHtmlGenerator htmlGenerator, ICompositeViewEngine viewEngine, IModelMetadataProvider metadataProvider, IHtmlEncoder htmlEncoder, IUrlEncoder urlEncoder, IJavaScriptStringEncoder javaScriptStringEncoder)
{
this.htmlGenerator = htmlGenerator;
this.viewEngine = viewEngine;
this.metadataProvider = metadataProvider;
this.htmlEncoder = htmlEncoder;
this.urlEncoder = urlEncoder;
this.javaScriptStringEncoder = javaScriptStringEncoder;
this.helper = helper;
}
[HttpGet]
public IActionResult MyHtmlGenerator()
{
MyViewModel temp = new MyViewModel();
var options = new HtmlHelperOptions();
options.ClientValidationEnabled = true;
ViewDataDictionary<MyViewModel> dic = new ViewDataDictionary<MyViewModel>(this.metadataProvider, new ModelStateDictionary());
ViewContext cc = new ViewContext(ActionContext, new FakeView(), dic, TempData, TextWriter.Null, options);
var type = typeof(MyViewModel);
var metadata = this.metadataProvider.GetMetadataForType(type);
ModelExplorer modelEx = new ModelExplorer(this.metadataProvider, metadata, temp);
ViewData["Description"] = "test desc";
ViewData["Id"] = 1;
this.ViewData = new ViewDataDictionary(this.metadataProvider, new ModelStateDictionary());
IHtmlHelper<MyViewModel> dd = new HtmlHelper<MyViewModel>(this.htmlGenerator, this.viewEngine, this.metadataProvider, this.htmlEncoder, this.urlEncoder, this.javaScriptStringEncoder);
((ICanHasViewContext)dd).Contextualize(cc);
dd.ViewContext.ViewData = this.ViewData;
var desc = GetString(dd.TextBoxFor(m => m.ID));
var ID = GetString(dd.TextBoxFor(m => m.Description));
// Do whatever you want with the ID and desc
return new ContentResult() { Content = ID + desc };
}
public static string GetString(IHtmlContent content)
{
var writer = new System.IO.StringWriter();
content.WriteTo(writer, new HtmlEncoder());
return writer.ToString();
}
}
public class MyViewModel : BaseAssetViewModel
{
// [RegularExpression(#"^-?\d{1,13}(\.\d{0,5})?$|^-?\.\d{1,5}$")]
[Required]
public int ID { get; set; }
[MinLength(2)]
public string Description { get; set; }
// Property with no validation
public string Other { get; set; }
}
public class FakeView : IView
{
string IView.Path
{
get
{
throw new NotImplementedException();
}
}
public Task RenderAsync(ViewContext viewContext)
{
throw new InvalidOperationException();
}
Task IView.RenderAsync(ViewContext context)
{
throw new NotImplementedException();
}
}
I don't know if this may be of help, may be you have to start to look at tag helpers:
https://github.com/DamianEdwards/TagHelperStarterWeb
they're working to a different way to create helpers that integrate in the page in a more natural way.

Using Castle.Windsor to register an interceptor for only the derived class, not the base class

I am working on upgrading our project from .Net 2 to .Net4.5, at the same time I'm pushing as many references as I can to NuGet and making sure the versions are current.
I am having a problem getting one of the tests to run
The Test Classes:
public class Person
{
public static int PersonBaseMethodHitCount { get; set; }
public virtual void BaseMethod()
{
PersonBaseMethodHitCount = PersonBaseMethodHitCount + 1;
}
public static int PersonSomeMethodToBeOverriddenHitCount { get; set; }
public virtual void SomeMethodToBeOverridden()
{
PersonSomeMethodToBeOverriddenHitCount = PersonSomeMethodToBeOverriddenHitCount + 1;
}
}
public class Employee : Person
{
public static int EmployeeSomeMethodToBeOverriddenHitCount { get; set; }
public override void SomeMethodToBeOverridden()
{
EmployeeSomeMethodToBeOverriddenHitCount = EmployeeSomeMethodToBeOverriddenHitCount + 1;
}
public static int EmployeeCannotInterceptHitCount { get; set; }
public void CannotIntercept()
{
EmployeeCannotInterceptHitCount = EmployeeCannotInterceptHitCount + 1;
}
public virtual void MethodWithParameter(
[SuppressMessage("a", "b"), InheritedAttribute, Noninherited]string foo)
{
}
}
public class MyInterceptor : IInterceptor
{
public static int HitCount { get; set; }
public void Intercept(IInvocation invocation)
{
HitCount = HitCount + 1;
invocation.Proceed();
}
}
The test (there is no setup for this fixture):
var container = new WindsorContainer();
container.Register(Component.For<MyInterceptor>().ImplementedBy<MyInterceptor>());
container.Register(
Component
.For<Employee>()
.ImplementedBy<Employee>()
.Interceptors(InterceptorReference.ForType<MyInterceptor>())
.SelectedWith(new DerivedClassMethodsInterceptorSelector()).Anywhere);
container.Register(Classes.FromAssembly(Assembly.GetExecutingAssembly()).Pick().WithService.FirstInterface());
var employee = container.Resolve<Employee>();
Person.PersonBaseMethodHitCount = 0;
Person.PersonSomeMethodToBeOverriddenHitCount = 0;
Employee.EmployeeCannotInterceptHitCount = 0;
Employee.EmployeeSomeMethodToBeOverriddenHitCount = 0;
MyInterceptor.HitCount = 0;
employee.BaseMethod();
Assert.That(Person.PersonBaseMethodHitCount, Is.EqualTo(1));
// The BaseMethod was not overridden in the derived class so the interceptor should not have been called.
Assert.That(MyInterceptor.HitCount, Is.EqualTo(0));
Person.PersonBaseMethodHitCount = 0;
Person.PersonSomeMethodToBeOverriddenHitCount = 0;
Employee.EmployeeCannotInterceptHitCount = 0;
Employee.EmployeeSomeMethodToBeOverriddenHitCount = 0;
MyInterceptor.HitCount = 0;
employee.SomeMethodToBeOverridden();
Assert.That(Person.PersonSomeMethodToBeOverriddenHitCount, Is.EqualTo(0));
Assert.That(Employee.EmployeeSomeMethodToBeOverriddenHitCount, Is.EqualTo(1));
Assert.That(MyInterceptor.HitCount, Is.EqualTo(1)); //The test errors out on this line
Person.PersonBaseMethodHitCount = 0;
Person.PersonSomeMethodToBeOverriddenHitCount = 0;
Employee.EmployeeCannotInterceptHitCount = 0;
Employee.EmployeeSomeMethodToBeOverriddenHitCount = 0;
MyInterceptor.HitCount = 0;
employee.CannotIntercept();
Assert.That(Employee.EmployeeCannotInterceptHitCount, Is.EqualTo(1));
Assert.That(MyInterceptor.HitCount, Is.EqualTo(0));
I added a comment to denote where the test fails.
So far as I can tell the problem is arising in the DerivedClassMethodsInterceptorSelector
Selector:
public class DerivedClassMethodsInterceptorSelector : IInterceptorSelector
{
public IInterceptor[] SelectInterceptors(Type type, MethodInfo method, IInterceptor[] interceptors)
{
return method.DeclaringType != type ? new IInterceptor[0] : interceptors;
}
}
When it makes the comparison of types, the type variable is System.RuntimeType but should be Employee (at least this is my understanding).
EDIT:
This problem was occurring using Castle.Windsor and Castle.Core 3.2.1, After making NuGet install the 3.1.0 package the code works as expected.
I am leaning towards this being a bug, but I could also just be a change in the logic.
I was able to reproduce the same issue with version 3.3.3 with this simple unit test:
[TestClass]
public class MyUnitTest
{
[TestMethod]
public void BasicCase()
{
var ProxyFactory = new ProxyGenerator();
var aopFilters = new IInterceptor[] {new TracingInterceptor()};
var ConcreteType = typeof(MyChild);
var options = new ProxyGenerationOptions { Selector = new AopSelector() };
var proxy = ProxyFactory.CreateClassProxy(ConcreteType, options, aopFilters) as MyChild;
proxy.DoIt();
}
}
public class AopSelector : IInterceptorSelector
{
public IInterceptor[] SelectInterceptors(Type runtimeType, MethodInfo method, IInterceptor[] interceptors)
{
Assert.IsTrue(runtimeType == typeof(MyChild));
return interceptors;
}
}
public class MyWay
{
public virtual void DoIt()
{
Thread.Sleep(200);
}
}
public class MyChild : MyWay
{
public virtual void DoIt2()
{
Thread.Sleep(200);
}
}
public class TracingInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
var isProperty = invocation.Method.Name.StartsWith("get_")
|| invocation.Method.Name.StartsWith("set_");
if (isProperty)
{
invocation.Proceed();
return;
}
LogMethod(invocation);
}
protected virtual void LogMethod(IInvocation invocation)
{
var target = (invocation.InvocationTarget ?? invocation.Proxy).GetType().Name;
var stopwatch = Stopwatch.StartNew();
try
{
stopwatch.Start();
invocation.Proceed();
}
finally
{
stopwatch.Stop();
var result = stopwatch.ElapsedMilliseconds;
}
}
}
I fixed it by changing Castle's source code and editing method TypeUtil.GetTypeOrNull to look like this:
public static Type GetTypeOrNull(object target)
{
if (target == null)
{
return null;
}
var type = target as Type;
if (type != null)
{
return type;
}
return target.GetType();
}
Of course this is a naive fix, because the problem is somewhere else and it is that instead of an object instance passed to this method, its Type is passed in. However checking if the passed parameter is of type Type and if so returning it instead of calling GetType on it makes it work.

How to create my own arrayAdapter for listView - Android [duplicate]

This question already has answers here:
BaseAdapter class wont setAdapter inside Asynctask - Android
(4 answers)
Closed 9 years ago.
I am trying to create my own arrayAdapter so I can place multiple textviews inside of a listview. I have searched everywhere and can not find a way to do it. I am new to this and not so sure how to handle it. So far I have an asynctask that gathers 3 strings in a JSON method. These strings are what I want placed in the textViews but I have no idea how to do so, here is my current code.
class loadComments extends AsyncTask<JSONObject, String, JSONObject> {
private ArrayAdapter<String> mAdapter = null;
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
}
protected JSONObject doInBackground(JSONObject... params) {
JSONObject json2 = CollectComments.collectComments(usernameforcomments, offsetNumber);
return json2;
}
#Override
protected void onPostExecute(JSONObject json2) {
try {
if (json2.getString(KEY_SUCCESS) != null) {
registerErrorMsg.setText("");
String res2 = json2.getString(KEY_SUCCESS);
if(Integer.parseInt(res2) == 1){
JSONArray commentArray = json2.getJSONArray(KEY_COMMENT);
final String comments[] = new String[commentArray.length()];
for ( int i=0; i<commentArray.length(); i++ ) {
comments[i] = commentArray.getString(i);
}
JSONArray numberArray = json2.getJSONArray(KEY_NUMBER);
String numbers[] = new String[numberArray.length()];
for ( int i=0; i<numberArray.length(); i++ ) {
numbers[i] = numberArray.getString(i);
}
JSONArray usernameArray = json2.getJSONArray(KEY_USERNAME);
String usernames[] = new String[usernameArray.length()];
for ( int i=0; i<usernameArray.length(); i++ ) {
usernames[i] = usernameArray.getString(i);
}
ArrayList<String> myList = new ArrayList<String>();
class MyClassAdapter extends ArrayAdapter<String> {
private Context context;
public MyClassAdapter(Context context, int textViewResourceId, ArrayList<String> items) {
super(context, textViewResourceId, items);
this.context = context;
}
public View getView(int position, View convertView) {
View view = convertView;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.list_item, null);
}
String item = getItem(position);
if (item!= null) {
// My layout has only one TextView
TextView commentView = (TextView) view.findViewById(R.id.listComment);
TextView usernameView = (TextView) view.findViewById(R.id.listPostedBy);
TextView NumberView = (TextView) view.findViewById(R.id.listNumber);
// do whatever you want with your string and long
commentView.setText(comments);
NumberView.setText(numbers);
usernameView.setText(usernames);
}
return view;
}
}
}//end if key is == 1
else{
// Error in registration
registerErrorMsg.setText(json2.getString(KEY_ERROR_MSG));
}//end else
}//end if
} //end try
catch (JSONException e) {
e.printStackTrace();
}//end catch
}
}
new loadComments().execute();
This code does not work but I think I am on the right track.
Let us say, you create a class that hold your information about the comments instead of creating three related Arrays :
class Commentary
{
public String username;
public String comment;
public int commentaryIndex;
}
The BaseAdapter can take a List as a parameter whereas the ArrayAdapter wouldn't.
class MyRealAdapter extends BaseAdapter
{
private List<Commentary> comments;
public MyRealAdapter(List<Commentary> comments )
{
this.comments = comments;
}
#Override
public int getCount() {
return comments.size();
}
#Override
public Object getItem(int index) {
return comments.get(index);
}
#Override
public long getItemId(int index) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Commentary c = (Commentary) getItem(position);
//c.username, c.comment, c.commentaryIndex
// create the view and stuff
return null;
}
}
As you can see, you again have the getView method but now you can retrieve your complete objet and not just a String.
There is a couple more method to override, but as you can see it's very simple.
You might need to pass other argument like a Context or a LayoutInflater to the constructor, but it's not mandatory.
EDIt :
JSONArray commentArray = json2.getJSONArray(KEY_COMMENT);
JSONArray numberArray = json2.getJSONArray(KEY_NUMBER);
JSONArray usernameArray = json2.getJSONArray(KEY_USERNAME);
ArrayList<Commentary> comments = new ArrayList<commentary>();
for ( int i=0; i<commentArray.length(); i++ ) {
Commentary c = new Commentary();
c.username = usernameArray.getString(i);
c.comment = commentArray.getString(i);
c.commentaryIndex = Integer.parseInt(numberArray.getString(i));
comments.add(c);
}
MyRealAdapter adapter = new MyRealAdapter(comments);