How to make expandable listview children scrollable? - xamarin.android

I've an expandable listview. I want to put different data in child views and make them scrollable. Currently my expandable listview is scrolling rather than child scroll. How can I restrict that and meet the requirement?
gridcustom layout:
?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/item_Image"
android:layout_width="120dp"
android:layout_height="120dp"
android:src="#color/accent"
android:scaleType="centerCrop" />
<TextView
android:id="#+id/item_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="13sp"
android:text="Image"
android:gravity="center"
android:layout_below="#+id/item_Image"
android:layout_alignParentBottom="true" />
</LinearLayout>
my grid:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/container_scroll_view"
android:layout_width="match_parent"
android:layout_height="250dp">
<GridView
android:id="#+id/gridview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnWidth="120dp"
android:numColumns="auto_fit"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:gravity="center"/>
</LinearLayout>
Expandable listview adapter:
using System;
using Android.Widget;
using System.Collections.Generic;
using Android.App;
using Android.Views;
namespace Sasken
{
public class ExpandableListAdapter :BaseExpandableListAdapter
{
Activity _context;
List<GridDataClass> _lstGrdData;
ImageAdapter imageAdaptor;
LayoutInflater layoutInflater;
public ExpandableListAdapter (Activity context, List<GridDataClass> lstGridData)
{
this._context = context;
this.layoutInflater = layoutInflater;
this._lstGrdData = lstGridData;
}
public override Java.Lang.Object GetChild (int groupPosition, int childPosition)
{
return true;
}
public override long GetChildId (int groupPosition, int childPosition)
{
return childPosition;
}
public override View GetChildView (int groupPosition, int childPosition, bool isLastChild, View convertView, ViewGroup parent)
{
// string childText = (string) GetChild(groupPosition, childPosition);
// if (convertView == null) {
// convertView = _context.LayoutInflater.Inflate (Resource.Layout.ListItemCustomLayout, null);
// }
// TextView txtListChild = (TextView) convertView.FindViewById(Resource.Id.lblListItem);
// txtListChild.Text=childText;
View v = null;
if (groupPosition == 0) {
v = View.Inflate (_context, Resource.Layout.expandable_Child_Layout, null);
GridView grid = (GridView)v.FindViewById (Resource.Id.gridview);
grid.SetAdapter (new ImageAdapter (this._context, _lstGrdData));
}
if (groupPosition == 1) {
v = View.Inflate (_context, Resource.Layout.expandable_child_1_layout, null);
TextView txtView = (TextView)v.FindViewById (Resource.Id.lblListItem);
txtView.Text = "Test";
txtView.TextSize = 15f;
}
if (groupPosition == 2) {
v = View.Inflate (_context, Resource.Layout.expandable_child_2_layout, null);
TextView txtView = (TextView)v.FindViewById (Resource.Id.lblListItem);
txtView.Text = "Test";
txtView.TextSize = 15f;
}
v.Invalidate ();
return v;
}
public override int GetChildrenCount (int groupPosition)
{
return 1;
}
public override Java.Lang.Object GetGroup (int groupPosition)
{
return null;
}
public override int GroupCount {
get {
return 3;
}
}
public override long GetGroupId (int groupPosition)
{
return 0;
}
public override View GetGroupView (int groupPosition, bool isExpanded, View convertView, ViewGroup parent)
{
View v = _context.LayoutInflater.Inflate (Resource.Layout.HeaderCustomLayout, null); //infalInflater.inflate(R.layout.list_group, null);
TextView lblListHeader = (TextView)v.FindViewById (Resource.Id.lblListHeader);
if (groupPosition == 0) {
lblListHeader.Text = "QUICK ITEMS";
lblListHeader.SetTypeface (null, Android.Graphics.TypefaceStyle.Bold);
}
if (groupPosition == 1) {
lblListHeader.Text = "PRODUCT LOOKUP";
lblListHeader.SetTypeface (null, Android.Graphics.TypefaceStyle.Bold);
}
if (groupPosition == 2) {
lblListHeader.Text = "NON MARCHANDISE";
lblListHeader.SetTypeface (null, Android.Graphics.TypefaceStyle.Bold);
}
if (groupPosition == 3) {
lblListHeader.Text = "QUICK ITEMS";
lblListHeader.SetTypeface (null, Android.Graphics.TypefaceStyle.Bold);
}
v.Invalidate ();
return v;
}
public override bool HasStableIds {
get {
return false;
}
}
public override bool IsChildSelectable (int groupPosition, int childPosition)
{
return true;
}
class ViewHolderItem :Java.Lang.Object
{
}
}
}
Image custom adaptor::
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
namespace Sasken
{
[Activity (Label = "ImageAdaptor")]
public class ImageAdapter : BaseAdapter
{
Activity _context;
List<GridDataClass> _lstGridData;
ImageView imageView;
TextView textView;
public ImageAdapter (Activity c, List<GridDataClass> lstGridData)
{
_context = c;
_lstGridData = lstGridData;
}
public override int Count {
get { return _lstGridData.Count; }
}
public override Java.Lang.Object GetItem (int position)
{
return null;
}
public override long GetItemId (int position)
{
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public override View GetView (int position, View convertView, ViewGroup parent)
{
if (convertView == null) { // if it's not recycled, initialize some attributes
convertView = _context.LayoutInflater.Inflate (Resource.Layout.GridCustomLayout, parent, false);
imageView = (ImageView)convertView.FindViewById (Resource.Id.item_Image);
textView = (TextView)convertView.FindViewById (Resource.Id.item_name);
// convertView.LayoutParameters = new GridView.LayoutParams (150,150);
// //convertView.SetScale (ImageView.ScaleType.CenterCrop);
// convertView.SetPadding (2, 2, 2, 2);
}
imageView.SetImageResource (_lstGridData [position].intImgSource);
textView.Text = (_lstGridData [position].strImgName);
return convertView;
}
}
public class GridDataClass
{
public GridDataClass (int item_value = 1, string item_name = "Temporary Id")
{
strImgName = item_name;
intImgSource = item_value;
}
public string strImgName{ get; set; }
public int intImgSource{ get; set; }
}
}

Related

How to remove item from array in image adapter. Xamarin gallery

public class ImageAdapter : BaseAdapter
{
Context context;
public ImageAdapter (Context conn)
{
context = conn;
}
public override int Count { get { return thumbIds.Length; } }
public override Java.Lang.Object GetItem (int position)
{
return null;
}
public override long GetItemId (int position)
{
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public override View GetView (int position, View convertView, ViewGroup parent)
{
ImageView pic = new ImageView (context);
pic.SetImageResource (thumbIds[position]);
pic.LayoutParameters = new Gallery.LayoutParams (500, 500);
pic.SetScaleType (ImageView.ScaleType.FitXy);
return pic;
}
// references to our images
int[] thumbIds = {
Resource.Drawable.image_1,
Resource.Drawable.image_2,
Resource.Drawable.image_3,
Resource.Drawable.image_4,
Resource.Drawable.image_5,
Resource.Drawable.image_6,
Resource.Drawable.image_7
};
}
How to remove item from array
https://learn.microsoft.com/en-us/xamarin/android/user-interface/controls/gallery
Gallery
Do you want to achieve the result like following GIF?
I advice your to use List<int> to replace of int[], then you can add a method called removeItem in the ImageAdapter like following code.
public void removeItem(int numToRemove)
{
if (numToRemove < thumbIds.Count)
{
thumbIds.RemoveAt(numToRemove);
this.NotifyDataSetChanged();
}
}
Here is code about ImageAdapter.cs
using Android.Views;
using Android.Widget;
using Java.Lang;
using System.Collections.Generic;
using System.Linq;
namespace App25
{
internal class ImageAdapter : BaseAdapter
{
private MainActivity mainActivity;
public ImageAdapter(MainActivity mainActivity)
{
this.mainActivity = mainActivity;
}
public override int Count { get { return thumbIds.Count; } }
public override Java.Lang.Object GetItem(int position)
{
return thumbIds[position];
}
public override long GetItemId(int position)
{
return position;
}
// create a new ImageView for each item referenced by the Adapter
public override View GetView(int position, View convertView, ViewGroup parent)
{
ImageView pic = new ImageView(mainActivity);
pic.SetImageResource(thumbIds[position]);
pic.LayoutParameters = new Gallery.LayoutParams(500, 500);
pic.SetScaleType(ImageView.ScaleType.FitXy);
return pic;
}
public void removeItem(int numToRemove)
{
if (numToRemove < thumbIds.Count)
{
thumbIds.RemoveAt(numToRemove);
this.NotifyDataSetChanged();
}
}
// references to our images
List<int> thumbIds = new List<int> {
Resource.Drawable.faded_div,
Resource.Drawable.icon,
Resource.Drawable.faded_div1,
Resource.Drawable.icon1,
Resource.Drawable.faded_div,
Resource.Drawable.icon2,
Resource.Drawable.faded_div
};
}
}
Here is MainActivity.cs
[Activity(Label = "#string/app_name", Theme = "#style/AppTheme", MainLauncher = true)]
public class MainActivity : AppCompatActivity
{
ImageAdapter imageAdapter;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
Gallery gallery = (Gallery)FindViewById<Gallery>(Resource.Id.gallery1);
Button button1 = FindViewById<Button>(Resource.Id.button1);
imageAdapter = new ImageAdapter(this);
gallery.Adapter = imageAdapter;
button1.Click += Button1_Click;
}
int removeItem = 0;
private void Button1_Click(object sender, System.EventArgs e)
{
imageAdapter.removeItem(removeItem);
}
}
Here is my activity_main.xml.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="remove"
android:id="#+id/button1"
/>
<Gallery
android:id="#+id/gallery1"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
=============Update==================
If you want to achieve the long click ,push alert, then delete the item, you can refer to achieve a longclick event for your gallery like following code.
gallery.ItemLongClick += Gallery_ItemLongClick;
private void Gallery_ItemLongClick(object sender, AdapterView.ItemLongClickEventArgs e)
{
// throw new System.NotImplementedException();
Android.App.AlertDialog.Builder dialog = new Android.App.AlertDialog.Builder(this);
Android.App.AlertDialog alert = dialog.Create();
alert.SetTitle("Title");
alert.SetMessage("Do you want to remove this select item");
alert.SetButton("OK", (c, ev) =>
{
// Ok button click task
imageAdapter.removeItem(e.Position);
});
alert.Show();
}
Here is my running GIF.

Adding Searchview in Listview

I made an array to transfer the required data consisting of 3 elements(Heading,SubHeading, int ImageResourceId).
The data shows up well in listview but I couldn't do the research inside listview.
I want to do the research using searchview on specific SubHeading or both (Heading,SubHeading)
//on creat
listView.Adapter = new HomeScreenAdapter(this, HomeScreenAdapter.tableItems);
search.QueryTextChange += SearchV_QueryTextChange;
//filter listview
private void SearchV_QueryTextChange(object sender, SearchView.QueryTextChangeEventArgs e)
{
}
//
// 3-class listview item id
public class TableItem
{
public string Heading;
public string SubHeading;
public int ImageResourceId;
public TableItem(string Heading, string SubHeading, int ImageResourceId)
{
this.Heading = Heading;
this.SubHeading = SubHeading;
this.ImageResourceId = ImageResourceId;
}
}
}
//
//class adapter & array item
class HomeScreenAdapter : BaseAdapter<TableItem>
{
public static List<TableItem> tableItems = new List<TableItem>();
List<TableItem> items;
Activity context;
public void filldata()
{
tableItems.Add(new TableItem("hussein", "devepoer", Resource.Drawable.imaga));
tableItems.Add(new TableItem("ahmed", "admin", Resource.Drawable.imagb));
tableItems.Add(new TableItem("jasim", " manager", Resource.Drawable.imagc));
tableItems.Add(new TableItem("ahmed", "admin", Resource.Drawable.imagd));
tableItems.Add(new TableItem("jasim", " manager", Resource.Drawable.image));
tableItems.Add(new TableItem("jasim", " manager", Resource.Drawable.imagf));
}
}
According to your code, I do one sample by SubHeading to filter ListView data.
Firstly, create TableItem class:
public class TableItem
{
public string Heading { get; set; }
public string SubHeading { get; set; }
public int ImageResourceId { get; set; }
}
Then creating UI for ListView item:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView android:id="#+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<ImageView android:id="#+id/imageView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
And create Adapter and filter for data:
public class TableItemAdapter : BaseAdapter<TableItem>, IFilterable
{
private List<TableItem> _originalData;
private List<TableItem> _items;
private readonly Activity _context;
public TableItemAdapter(Activity activity, IEnumerable<TableItem> tableitems)
{
_items = tableitems.OrderBy(s => s.SubHeading).ToList();
_context = activity;
Filter = new TableItemFilter(this);
}
public override TableItem this[int position]
{
get { return _items[position]; }
}
public Filter Filter { get; private set; }
public override int Count
{
get { return _items.Count; }
}
public override long GetItemId(int position)
{
return position;
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
var view = convertView ?? _context.LayoutInflater.Inflate(Resource.Layout.TableItem, null);
var tableitem = _items[position];
var HeadingView = view.FindViewById<TextView>(Resource.Id.textView1);
var SubHeadingView = view.FindViewById<TextView>(Resource.Id.textView2);
var imageView = view.FindViewById<ImageView>(Resource.Id.imageView1);
HeadingView.Text = tableitem.Heading;
SubHeadingView.Text = tableitem.SubHeading;
imageView.SetImageResource(tableitem.ImageResourceId);
return view;
}
public override void NotifyDataSetChanged()
{
// If you are using cool stuff like sections
// remember to update the indices here!
base.NotifyDataSetChanged();
}
private class TableItemFilter : Filter
{
private readonly TableItemAdapter _adapter;
public TableItemFilter(TableItemAdapter adapter)
{
_adapter = adapter;
}
protected override FilterResults PerformFiltering(ICharSequence constraint)
{
var returnObj = new FilterResults();
var results = new List<TableItem>();
if (_adapter._originalData == null)
_adapter._originalData = _adapter._items;
if (constraint == null) return returnObj;
if (_adapter._originalData != null && _adapter._originalData.Any())
{
// Compare constraint to all names lowercased.
// It they are contained they are added to results.
results.AddRange(
_adapter._originalData.Where(
item => item.SubHeading.ToLower().Contains(constraint.ToString())));
}
// Nasty piece of .NET to Java wrapping, be careful with this!
returnObj.Values = FromArray(results.Select(r => r.ToJavaObject()).ToArray());
returnObj.Count = results.Count;
constraint.Dispose();
return returnObj;
}
protected override void PublishResults(ICharSequence constraint, FilterResults results)
{
using (var values = results.Values)
_adapter._items = values.ToArray<Java.Lang.Object>().Select(r =>r.ToNetObject<TableItem>()).ToList();
_adapter.NotifyDataSetChanged();
// Don't do this and see GREF counts rising
constraint.Dispose();
results.Dispose();
}
}
}
ObjectExtensions to implement filter:
public class JavaHolder : Java.Lang.Object
{
public readonly object Instance;
public JavaHolder(object instance)
{
Instance = instance;
}
}
public static class ObjectExtensions
{
public static TObject ToNetObject<TObject>(this Java.Lang.Object value)
{
if (value == null)
return default(TObject);
if (!(value is JavaHolder))
throw new InvalidOperationException("Unable to convert to .NET object. Only Java.Lang.Object created with .ToJavaObject() can be converted.");
TObject returnVal;
try { returnVal = (TObject)((JavaHolder)value).Instance; }
finally { value.Dispose(); }
return returnVal;
}
public static Java.Lang.Object ToJavaObject<TObject>(this TObject value)
{
if (Equals(value, default(TObject)) && !typeof(TObject).IsValueType)
return null;
var holder = new JavaHolder(value);
return holder;
}
}
Mainactivity.cs:
public class MainActivity : AppCompatActivity
{
private SearchView searchview1;
private ListView listview1;
private TableItemAdapter tableitemadapter;
private List<TableItem> tableitems;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
searchview1 = FindViewById<SearchView>(Resource.Id.searchView1);
listview1 = FindViewById<ListView>(Resource.Id.listView1);
tableitems = new List<TableItem>()
{
new TableItem(){Heading= "hussein", SubHeading="devepoer",ImageResourceId= Resource.Drawable.plu3 },
new TableItem(){Heading= "ahmed", SubHeading="admin",ImageResourceId= Resource.Drawable.plu3 },
new TableItem(){Heading= "jasim", SubHeading="manager",ImageResourceId= Resource.Drawable.plu3 },
new TableItem(){Heading= "cherry", SubHeading="admin",ImageResourceId= Resource.Drawable.plu3 },
new TableItem(){Heading= "barry", SubHeading="manager",ImageResourceId= Resource.Drawable.plu3 },
new TableItem(){Heading= "annine", SubHeading="manager",ImageResourceId= Resource.Drawable.plu3 }
};
tableitemadapter = new TableItemAdapter(this,tableitems);
listview1.Adapter = tableitemadapter;
searchview1.QueryTextChange += Searchview1_QueryTextChange;
}
private void Searchview1_QueryTextChange(object sender, SearchView.QueryTextChangeEventArgs e)
{
tableitemadapter.Filter.InvokeFilter(e.NewText);
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
The sample in github:
https://github.com/CherryBu/Searchviewsample
The screenshot:

Multi Select Spinner Xamarin Android

I am using a spinner and an arrayAdapter to populate items in spinner. I want to make the spinner multi-selectable but I just select one row.I searched in Google, solution available in Java, but i don't have any idea on how to implement it in Xamarin.
My code is as below,
adapterList= new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItemMultipleChoice);
spnMultiTest.Adapter = adapterList;
I want to make the spinner multi-selectable but I just select one row.I searched in Google, solution available in Java, but i don't have any idea on how to implement it in Xamarin.
Basically I just translate the codes from Android Spinner with multiple choice
to Xamarin codes. I have tested it and it works fine:
MultiSpinner.cs:
public interface MultiSpinnerListener
{
void onItemsSelected(bool[] selected);
}
public class MultiSpinner : Spinner, IDialogInterfaceOnMultiChoiceClickListener, IDialogInterfaceOnCancelListener
{
Context _context;
private List<String> items;
private bool[] selected;
private String defaultText;
private MultiSpinnerListener listener;
public MultiSpinner(Context context) : base(context)
{
_context = context;
}
public MultiSpinner(Context context, IAttributeSet arg1) : base(context, arg1)
{
_context = context;
}
public MultiSpinner(Context context, IAttributeSet arg1, int arg2) : base(context, arg1, arg2)
{
_context = context;
}
public void OnClick(IDialogInterface dialog, int which, bool isChecked)
{
if (isChecked)
selected[which] = true;
else
selected[which] = false;
}
public override void OnClick(IDialogInterface dialog, int which)
{
dialog.Cancel();
}
public override bool PerformClick()
{
AlertDialog.Builder builder = new AlertDialog.Builder(_context);
builder.SetMultiChoiceItems(
items.ToArray(), selected, this);
builder.SetPositiveButton("OK",this);
builder.SetOnCancelListener(this);
builder.Show();
return true;
}
public void SetItems(List<String> items, String allText,
MultiSpinnerListener listener)
{
this.items = items;
this.defaultText = allText;
this.listener = listener;
// all selected by default
selected = new bool[items.Count];
for (int i = 0; i < selected.Length; i++)
selected[i] = true;
ArrayAdapter<string> adapter = new ArrayAdapter<string>(_context,Resource.Layout.simple_spinner_item,Resource.Id.tv_item,new string[] { allText });
// all text on the spinner
//ArrayAdapter<String> adapter = new ArrayAdapter<String>(_context,Resource.Layout.simple_spinner_item, new String[] { allText });
Adapter = adapter;
}
public void OnCancel(IDialogInterface dialog)
{
Java.Lang.StringBuffer spinnerBuffer = new Java.Lang.StringBuffer();
bool someUnselected = false;
for (int i = 0; i < items.Count; i++)
{
if (selected[i] == true)
{
spinnerBuffer.Append(items[i]);
spinnerBuffer.Append(", ");
}
else
{
someUnselected = true;
}
}
String spinnerText;
if (someUnselected)
{
spinnerText = spinnerBuffer.ToString();
if (spinnerText.Length > 2)
spinnerText = spinnerText.Substring(0, spinnerText.Length - 2);
}
else
{
spinnerText = defaultText;
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(_context,Resource.Layout.simple_spinner_item,Resource.Id.tv_item,new string[] { spinnerText });
Adapter = adapter;
if (listener != null)
{
listener.onItemsSelected(selected);
}
}
}
simple_spinner_item.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/tv_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
Update:
Here is the codes for using this MultiSpinner:
Main.axml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<MultiSpinner.MultiSpinner
android:id="#+id/mSpinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
MainActivity.cs:
public class MainActivity : Activity
{
MultiSpinner mSpinner;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
mSpinner = FindViewById<MultiSpinner>(Resource.Id.mSpinner);
List<string> items = new List<string> {
"Android",
"iOS",
"UWP"
};
mSpinner.SetItems(items, "AllText", null);
}
}

Listview Filter with SearchView Using Base Adapter in Xamarin android Error

I am try to filter listview with searchview using Base Adapter in in xamarin Android, My listView Bind in sql server using restfull web service i am stuck in PublishResults which is given an error
Here Is My Code:-
GetHospNames.cs
public class GetHospNames
{
public string HospID { get; set; }
public string HospName { get; set; }
public GetHospNames(string HospID, string HospName)
{
this.HospID = HospID;
this.HospName = HospName;
//this.HospLogo = HospLogo;
}
}
ContListViewHospNameClass.cs
using System.Collections.Generic;
using Android.App;
using Android.Views;
using Android.Widget;
using System;
using Android.Graphics;
using Android.Graphics.Drawables;
using System.IO;
using Android.Content;
using Java.Lang;
using Android.Text;
using Java.Util;
using Oject = Java.Lang.Object;
namespace HSAPP
{
public class ContListViewHospNameClass : BaseAdapter<GetHospNames>, IFilterable
{
public List<GetHospNames> objList;
Activity objActivity;
List<GetHospNames> filterList;
public ContListViewHospNameClass(Activity objMyAct, List<GetHospNames> objMyList) : base()
{
this.objActivity = objMyAct;
objList = objMyList;
this.filterList = objList;
Filter = new CustomFilter(this);
}
public override GetHospNames this[int position]
{
get
{
return objList[position];
}
}
public override int Count
{
get
{
return objList.Count;
}
}
public Filter Filter { get; set; }
public override void NotifyDataSetChanged()
{
base.NotifyDataSetChanged();
}
//This is Inner Class
public class CustomFilter : Filter
{
ContListViewHospNameClass CustomAdapter;
public CustomFilter(ContListViewHospNameClass adapter) : base()
{
this.CustomAdapter = adapter;
}
protected override FilterResults PerformFiltering(ICharSequence constraint)
{
FilterResults result = new FilterResults();
if (constraint != null && constraint.Length() > 0)
{
//Contraint To Upper
List<GetHospNames> filter = new List<GetHospNames>();
foreach (GetHospNames name in CustomAdapter.objList)
{
if (name.HospName.ToUpper().Contains(constraint.ToString().ToUpper()))
{
filter.Add(name);
}
}
Oject[] Name;
Name = new Oject[filter.Count];
for (int i = 0; i < filter.Count; i++)
{
Name[i] = filter[i].HospName.ToString();
}
result.Count = filter.Count;
result.Values = Name;
}
return result;
}
protected override void PublishResults(ICharSequence constraint, Filter.FilterResults result)
{
List<GetHospNames> filteredList = new List<GetHospNames>();
for (int i = 0; i < ((Oject[])result.Values).Length; i++)
{
filteredList.Add((Oject[])result.Values[i]);//Here Is An Error *****Cannot apply indexing with [] to an expression of type 'Object'****
}
CustomAdapter.objList = filteredList;
CustomAdapter.NotifyDataSetChanged();
}
}
public override long GetItemId(int position)
{
return position;
}
public Bitmap getBitmap(byte[] getByte)
{
if (getByte.Length != 0)
{
return BitmapFactory.DecodeByteArray(getByte, 0, getByte.Length);
}
else
{
return null;
}
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
var item = objList[position];
if (convertView == null)
{
convertView = objActivity.LayoutInflater.Inflate(Resource.Layout.ContListViewHospName, null);
}
convertView.FindViewById<TextView>(Resource.Id.tvHospID).Text = item.HospID;
convertView.FindViewById<TextView>(Resource.Id.tvHospName).Text = item.HospName;
return convertView;
}
}
public static class ObjectTypeHelper
{
public static T Cast<T>(this Java.Lang.Object obj) where T : class
{
var propertyInfo = obj.GetType().GetProperty("Instance");
return propertyInfo == null ? null : propertyInfo.GetValue(obj, null) as T;
}
}
}
This is my MainActivity Code
private void BindControl_BindHospCompleted(object sender, BindControl.BindHospCompletedEventArgs e)
{
jsonValue = e.Result.ToString();
try
{
if (jsonValue == null)
{
Toast.MakeText(this, "No Data For Bind", ToastLength.Long).Show();
return;
}
JArrayValue = JArray.Parse(jsonValue);
list = new List<GetHospNames>();
int count = 0;
while (count < JArrayValue.Count)
{
GetHospNames getHospName = new GetHospNames(JArrayValue[count]["HospID"].ToString(), JArrayValue[count]["HospName"].ToString());
list.Add(getHospName);
count++;
}
if (count == 0)
{
Toast.MakeText(this, "No List Of Hospitals", ToastLength.Long).Show();
}
adapter = new ContListViewHospNameClass(this, list);
listView.Adapter = adapter;
search.QueryTextChange += (s, e) =>
{
adapter.Filter.InvokeFilter(e.NewText);
};
listView.ItemClick += ListView_ItemClick;
pBar.Dismiss();
}
catch (Java.Lang.Exception ex)
{
pBar.Dismiss();
//Toast.MakeText(this, ex.ToString(), ToastLength.Long).Show();
Finish();
Intent intent = new Intent(this, typeof(ChkIntConnActivity));
StartActivity(intent);
}
}
Please Help...Thank You

Create a custom Spinner

I am trying to customize the MvxSpinner to add some additional controls, here is my code:
public class ChamSpinner : LinearLayout
{
public Spinner Spinner{ get; private set; }
public EventHandler<AdapterView.ItemSelectedEventArgs> ItemSelected;
public ChamSpinner (Context context, IAttributeSet attrs) : this (context, attrs, new ChamSpinnerAdapter (context))
{
}
public ChamSpinner (Context context, IAttributeSet attrs, IMvxAdapter adapter) : base (context, attrs)
{
((Activity)Context).LayoutInflater.Inflate (Resource.Layout.ChamSpinnerLayout, this);
Spinner = FindViewById<Spinner> (Resource.Id.ChamSpinnerSpinner);
int itemTemplateId = MvxAttributeHelpers.ReadListItemTemplateId (context, attrs);
int dropDownItemTemplateId = MvxAttributeHelpers.ReadDropDownListItemTemplateId (context, attrs);
adapter.ItemTemplateId = itemTemplateId;
adapter.DropDownItemTemplateId = dropDownItemTemplateId;
Adapter = adapter;
SetupHandleItemSelected ();
}
public new IMvxAdapter Adapter
{
get { return Spinner.Adapter as IMvxAdapter; }
set
{
var existing = Adapter;
if (existing == value)
return;
if (existing != null && value != null)
{
value.ItemsSource = existing.ItemsSource;
value.ItemTemplateId = existing.ItemTemplateId;
}
Spinner.Adapter = value;
}
}
[MvxSetToNullAfterBinding]
public IEnumerable ItemsSource
{
get
{
return Adapter.ItemsSource;
}
set
{
Adapter.ItemsSource = value;
}
}
public int ItemTemplateId
{
get { return Adapter.ItemTemplateId; }
set { Adapter.ItemTemplateId = value; }
}
public int DropDownItemTemplateId
{
get { return Adapter.DropDownItemTemplateId; }
set { Adapter.DropDownItemTemplateId = value; }
}
public ICommand HandleItemSelected { get; set; }
private void SetupHandleItemSelected ()
{
Spinner.ItemSelected += (sender, args) =>
{
var position = args.Position;
HandleSelected (position);
if (ItemSelected != null)
ItemSelected (sender, args);
};
}
protected virtual void HandleSelected (int position)
{
var item = Adapter.GetRawItem (position);
if (this.HandleItemSelected == null
|| item == null
|| !this.HandleItemSelected.CanExecute (item))
return;
this.HandleItemSelected.Execute (item);
}
}
And I am using it like this:
<cross.android.ChamSpinner
android:layout_width="fill_parent"
android:layout_height="wrap_content"
local:MvxDropDownItemTemplate="#layout/myspinneritemdropdown"
local:MvxItemTemplate="#layout/myspinneritem"
local:MvxBind="ItemsSource MyItemsSource; SelectedItem MyItem; Mode TwoWay" />
The spinner is always empty, I tried to add a custom binding on ItemsSource property but the result stilll the same.
How can I do to show my items in my spinner?
Thank you in advance.
I think using BindingInflate instead of Inflate should fix it or even points you in the right direction. https://github.com/MvvmCross/MvvmCross/blob/v3.1/Cirrious/Cirrious.MvvmCross.Binding.Droid/BindingContext/IMvxAndroidBindingContext.cs
((IMvxBindingContextOwner)Context).BindingInflate(Resource.Layout.ChamSpinnerLayout, this);
I found this error in my log
MvxBind:Error: 32,12 View type not found - cross.android.ChamSpinner
My custom control is in another assembly so I added it to MvvmCross View assemblies is my Setup class like this
protected override IList<Assembly> AndroidViewAssemblies
{
get
{
var assemblies = base.AndroidViewAssemblies;
assemblies.Add(typeof(ChamSpinner).Assembly);
return assemblies;
}
}
Thank you Stuart for your advices and for your great Framework.

Resources