Checked checkboxes is unchecked when i scroll listview in xamarin android - xamarin

Below is my GetView() method in adapter class, when I scroll the list view by selecting one checkbox. After scrolling back to initial position checked checkbox is getting unchecked.
public override View GetView (int position, View convertView, ViewGroup parent)
{
View view = convertView;
var item = mMyList [position];
//View holder
MyViewHolder holder = null;
if (view == null) {
holder = new MyViewHolder ();
view = mcontext.LayoutInflater.Inflate (Resource.Layout.listview_layout, null);
holder.mChecked = view.FindViewById<CheckBox> (Resource.Id.chkBox);
holder.Name = view.FindViewById<TextView> (Resource.Id.Name);
holder.StartDate = view.FindViewById<TextView> (Resource.Id.startDate);
holder.EndDate = view.FindViewById<TextView> (Resource.Id.endDate);
holder.Desc = view.FindViewById<TextView> (Resource.Id.Desc);
view.SetTag (holder);
} else {
holder = (MyViewHolder)view.Tag;
}
holder.Name.SetText (item.Name, TextView.BufferType.Normal);
holder.StartDate.SetText (item.StartDate, TextView.BufferType.Normal);
holder.EndDate.SetText (item.EndDate, TextView.BufferType.Normal);
holder.Desc.SetText (item.Description, TextView.BufferType.Normal);
return view;
}

It's simple!
You just need to store this "states" of checkboxes,because everytime when you scroll your listview, GetView method will be called(to draw hided items, Android reuses rows).
In your DataContext, for e.g. List<MyClass> , where MyClass represents:
public class MyClass
{
public string Name {get;set;}
public string SecondName {get;set;}
public bool IsChecked {get;set;}
}
try to add bool property(in this case IsChecked) for state of Checkbox.
And after this,in your GetView method write something likes this:
holder.mChecked.Checked = MyList [position].#YourBoolProperty#;
Btw i just write that on the fly.
Also,if something isn't clear for you, try to check this or this.
Hope that helps!

Related

How to set a default value for MvxSpinner

I am trying to modify the MvxSpinner to set a default value saying
"Select a Value".
I referred this solution to override the methods, but I am
not able to override the methods.
How to achieve this in a elegant way
XML
<Mvx.MvxSpinner
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30dp"
android:background="#drawable/dropdown"
local:MvxBind="ItemsSource Cruise; SelectedItem CruiseLineSelected; Visible CruiseAndShipSelectionVisibility"
local:MvxItemTemplate="#layout/spinner_cruise_list"
local:MvxDropDownItemTemplate="#layout/spinner_cruise_list"
android:text="Select a cruise"
android:layout_marginBottom="20dp"
android:id="#+id/mvxSpinnerCruise" />
I find a simple solution to set a default text for Spinner and it works fine, I think you can use Mvvm to implement this function by yourself, here is the
code :
public class MySpinnerAdapter<T> : ArrayAdapter<T>
{
private Context mContext;
private int mTextResourceId;
public MySpinnerAdapter(Context context, int textViewResourceId):base(context,textViewResourceId)
{
mContext = Context;
mTextResourceId = textViewResourceId;
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
View view = base.GetView(position, convertView, parent);
if (position == Count)
{
TextView a = (view.FindViewById<TextView>(Android.Resource.Id.Text1));
a.Text = "";
TextView b = (view.FindViewById<TextView>(Android.Resource.Id.Text1));
b.Hint = GetItem(Count).ToString(); //"Hint to be displayed"
}
return view;
}
public override int Count => (base.Count - 1);
}
When use the it :
spinner = FindViewById<Spinner>(Resource.Id.spinner);
var adapter = new MySpinnerAdapter<string>(this, Android.Resource.Layout.SimpleSpinnerDropDownItem);
adapter.Add("php");
adapter.Add("java");
adapter.Add("C++");
adapter.Add("C");
adapter.Add("Select a cruise");
spinner.Adapter = adapter;
spinner.SetSelection(adapter.Count); //display hint
Here is the Spinner.

Xamarin.Android: Click event on Textview inside list view cell called multiple times

I have a list view in which inside each cell I have two textview, I need to handle the click event for one of the textview element. But when I put the click event inside the GetView() of the adapter, it is called multiple times.
public override View GetView(int position, View convertView, ViewGroup parent)
{
var item = tableItems[position];
ViewHolder holder;
View view = convertView;
if (view == null)
{
LayoutInflater layoutInflator = LayoutInflater.From(mContext);
view = layoutInflator.Inflate(Resource.Layout.myListViewCell, null);
holder = new ViewHolder();
holder.tvEmpName = view.FindViewById<TextView>(Resource.Id.tv_EmpName);
holder.tvEmpPhone = view.FindViewById<TextView>(Resource.Id.tv_EmpPhone);
view.Tag = holder;
}
else
{
holder = (ViewHolder)view.Tag;
}
holder.tvEmpName.Text = item.FullName;
holder.tvEmpPhone.Text = item.Phone;
holder.tvEmpPhone.Click += (sender, e) => {
// Click event to launch the Popup menu
// This event is being called multiple times, as Get view() being called multiple times.
};
return view;
}
I gone through this similar thread, but didn't find any solution.
The event is called multiple times because evertime when the metod getview is called you add a click event with +=.
In this case you can put the click event inside the if, like that:
if (view == null)
{
LayoutInflater layoutInflator = LayoutInflater.From(mContext);
view = layoutInflator.Inflate(Resource.Layout.myListViewCell, null);
holder = new ViewHolder();
holder.tvEmpName = view.FindViewById<TextView>(Resource.Id.tv_EmpName);
holder.tvEmpPhone = view.FindViewById<TextView>(Resource.Id.tv_EmpPhone);
view.Tag = holder;
holder.tvEmpPhone.Click += (sender, e) => {
// Code here
};
}
But the recyclerview is better than listview for this.

Create a Layout Item for ListView in Xamarin Android

I have a problem and It's 10 days that I am working and can't solve it.I made a layout for each row for ListView.This Layout Contains a linearLayout that there is a TextView and a WebView inside it.Now I Need a C# Project that I can add a new Row to the ListView with new text and url whenever I want.For Example: button.click { ListView.add(Resource.Layout.Items, "Text","Url")}..I know this command is wrong. Just I wanted to clear the problem for you.
I khnow it's custom Row layout and I read manny examples at this site other sites and Xamarin site about that,adapters,... but I can't do it. :(
Please answer me correctly.
It is very important for me.
Thanks a lot.
You need to create an adapter that can work with you custom objects as items. It could look like the following sample:
public class MyAdapter : BaseAdapter<MyItem>
{
readonly LayoutInflater inflater;
List<MyItem> myItemList;
public MyAdapter(Context context)
{
inflater = LayoutInflater.FromContext(context);
myItemList = YOUR_DATASOURCE.GetMyItems();
}
public override MyItem this [int index]
{
get { return myItemList[index]; }
}
public override int Count
{
get { return myItemList.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.MyItemLayout, parent, false);
var item = myItemList[position];
var viewHolder = view.Tag as MyViewHolder;
if (viewHolder == null)
{
viewHolder = new MyViewHolder();
viewHolder.Web = view.FindViewById<WebView>(Resource.Id.MyItemLayout_Icon);
viewHolder.Name = view.FindViewById<TextView>(Resource.Id.MyItemLayout_Title);
view.Tag = viewHolder;
}
viewHolder.Web.Url = item.Url; //You need to check how you have to set the url for a WebView
viewHolder.Name.Text = item.Text;
return view;
}
public override void NotifyDataSetChanged()
{
myItemList = YOUR_DATASOURCE.GetMyItems();
base.NotifyDataSetChanged();
}
}
class MyViewHolder : Java.Lang.Object
{
public WebView Web { get; set; }
public TextView Name { get; set; }
}
You apply the adapter to your ListView with ListView.Adapter = new MyAdapter(Activity);. Each time you change an item in you button click event, you tricker (ListView.Adapter as MyAdapter).NotifyDataSetChanged(); which will force the adapter to reload and refresh the data.
YOUR_DATASOURCE represents the point in your code where you store the informations like the url or text of all your items. This could typically be a database or something similar. While GetMyItems() is a method for example to query your database.
Hope this clears things up.

listview asyncimage mismatch

i used the Android-Universal-Image-Loader(https://github.com/nostra13/Android-Universal-Image-Loader) for my project,but i get a strange problem:
the image loaded from the website was dismatch with the listview item when i scroll fast or fling fast...
i mean the listview item will load the wrong image sometimes,here is the code:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Map<String, Object> item = mDatasource.get(position);
View view = convertView;
final ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
view = mInflater.inflate(R.layout.block_list_item, null);
holder.account_name = (TextView) view.findViewById(R.id.author_name);
holder.account_avatar = (ImageView) view.findViewById(R.id.view_header);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.account_name.setText(StringUtils.convertSafeString(item.get("account_name")));
String avatarUrl = UrlHelper.HOST + item.get("account_avatar");
if (!avatarUrl.endsWith(Constants.NO_AVATAR)) {
holder.account_avatar.setTag(avatarUrl);
imageLoader.displayImage(avatarUrl,holder.account_avatar, mOptions);
}
return view;
}
Well, I don't know this is going to help or not
I had a similar problem but I was using Parse, meaning I am getting my images from parse server
I managed to solve the problem when I discovered that the method I am using to get the image was meant to open a new thread rather than the UI thread and get the image in background (getParseFile().getDataInBackGround), when I changed it to another method which doesn't use another thread(getParseFile().getData()), it worked without problems.

Windows phone user control change pivot selecteditem

I created my own UserControl, I added Button to it. Also I have Pivot where I added this UserControl. How can I change Pivot selecteditem in Button_Click event in my UserControl.
Binding:
Binding binding = new Binding("SelectedIndex");
binding.Source = historyControls[i].SelectedIndex;
Pivot_Second.SetBinding(Pivot.SelectedIndexProperty, binding);
void Button_Click()
{
SelectedIndex = desiredindex;
}
Make a property
private int _SelectedIndex;
public int SelectedIndex
{
get
{
return _SelectedIndex;
}
set
{
_SelectedIndex = value;
RaisedPropertyChanged("SelectedIndex");
}
}
then bind this property with selected index of your pivot.
I hope it will work.

Resources