I have a DialogFragment that is working and need to return the selected item from a spinner. I've tried many methods that I've found on Stack Overflow and other places but they are all using java which doesn't (apparently) translate well to c# in Xamarin for Visual Studio 2017. To date, nothing has worked My DialogFragment layout is:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="300dp"
android:minHeight="75dp">
<TextView
android:text="Select the department you are registering for."
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:textStyle="bold"
android:id="#+id/textView2" />
<Spinner
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:id="#+id/department_spinner" />
<Button
android:text="Ok"
android:layout_width="200px"
android:layout_gravity="center"
android:layout_height="34.5dp"
android:id="#+id/button_ok" />
</LinearLayout>
The class code is:
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 MyProject
{
class selectDepartment : DialogFragment
{
static Spinner department;
public string selection = "";
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
base.OnCreateView(inflater, container, savedInstanceState);
View view = inflater.Inflate(Resource.Layout.selectDepartment, container, false);
Button ok = view.FindViewById<Button>(Resource.Id.button_ok);
department = view.FindViewById<Spinner>(Resource.Id.department_spinner);
List<string> list = new List<string>();
list.Add("Select Department");
list.Add("Dept. A");
list.Add("Dept. B");
var adapter = new ArrayAdapter<string>(this.Activity, Android.Resource.Layout.SimpleSpinnerItem, list.ToArray());
department.Adapter = adapter;
ok.Click += (sender, args) =>
{
selection = string.Format("{0}", department.GetItemAtPosition(department.SelectedItemPosition));
};
return view;
}
}
}
This is the code that shows the dialog:
FragmentTransaction getdepartment = FragmentManager.BeginTransaction();
selectDepartment getDept = new selectDepartment();
getDept.Show(getdepartment , "Select Department");
// Here I attempt to read a property which contains the selection
string selection = getDept.selection;
In my last attempt, I assigned the spinner selection to a property and I attempt to read that property to get the value selected, but the dialog is (apparently) displayed on a different thread and the selection isn't chosen when that line of code is executed. I tried making my method async and await the dialog, but that just made matters worse. What am I missing?
use a custom event
public class DialogEventArgs : EventArgs
{
public string Selection { get; set; }
}
and then in selectDepartment add:
public delegate void DialogEventHandler(object sender, DialogEventArgs args);
public event DialogEventHandler Dismissed;
Finally in the button's click handler add:
if (null != Dismissed)
Dismissed(this, new DialogEventArgs { Selection = selection });
when you create the dialog, attach an event handler
selectDepartment getDept = new selectDepartment();
getDept.Dismissed += (s, e) => { /* do something with e.Selection here */ };
Related
I am trying to build a native android app in xamarin where users can sign in and upload post to the feed page and also view posts from other users on their feed. The feed page has a recycler view which renders posts from the firebase and also has an upload option for users to upload posts to firebase, which then will be retrieved back to the app and be displayed in the feed page. everything works fine on the emulator (user sign-in->user view feeds->user upload posts etc). But when I build the release file and install it on my android 10 phone, only the sign in functionality works which uses validation from firebase. The feeds recycler view does not work anymore and does not display posts from firebase, and also every time a user tries to upload a posts to firebase, the app crashes, shows the splash screen, and then finally exits. I have looked up everywhere for an answer but could not find any so I decided to seek help here. Below are some code snippets:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout 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="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/drawerLayout"
android:fitsSystemWindows="true"
>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
layout="#layout/include_main"/>
</LinearLayout>
<com.google.android.material.navigation.NavigationView
android:id="#+id/navview"
android:layout_width="300dp"
android:layout_height="match_parent"
android:background="#color/white"
android:layout_gravity="start"
app:headerLayout="#layout/navheader"
app:menu="#menu/navmenu"
/>
</androidx.drawerlayout.widget.DrawerLayout>
include_main.xml
<?xml version="1.0" encoding="utf-8"?>
<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">
<androidx.appcompat.widget.Toolbar
android:theme="#style/AppTheme.ToolBarOverlay"
app:popupTheme="#style/AppTheme.PopupOverlay"
android:id="#+id/toolbar"
android:background="#color/colorPrimary"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize">
<RelativeLayout
android:layout_height="match_parent"
android:layout_width="match_parent">
<ImageView
android:id="#+id/userIcon"
android:src="#drawable/account"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentRight="true"
android:layout_marginRight="15sp"
android:layout_centerVertical="true"/>
<TextView
android:text="Feed"
android:textSize="20sp"
android:textColor="#color/white"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textStyle="bold"/>
</RelativeLayout>
</androidx.appcompat.widget.Toolbar>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="65dp"
android:background="#color/white"
android:clickable="true"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:id="#+id/layStatus"
android:elevation="4dp">
<RelativeLayout
android:layout_width="240dp"
android:layout_height="36dp"
android:layout_centerInParent="true"
android:background="#drawable/roundedges">
<TextView
android:text="What's on your mind?"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:gravity="center"
android:layout_centerInParent="true"/>
</RelativeLayout>
<ImageView
android:id="#+id/userIcon"
android:src="#drawable/add"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"/>
<ImageView
android:src="#drawable/photo"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"/>
</RelativeLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/postRecycleView"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:scrollbars="vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingBottom="16dp"
/>
</LinearLayout>
MainActivity.cs
using Android.App;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using AndroidX.AppCompat.App;
using AndroidX.RecyclerView.Widget;
using System;
using System.Collections.Generic;
using TransGlobal.Adapter;
using TransGlobal.DataModels;
using TransGlobal.Activities;
using TransGlobal.Actvities;
using TransGlobal.EventListeners;
using System.Linq;
using TransGlobal.Helpers;
using Firebase.Storage;
using TransGlobal.Fragments;
using Android.Content;
namespace TransGlobal
{
[Activity(Label = "#string/app_name", Theme = "#style/AppTheme", MainLauncher = false)]
public class MainActivity : AppCompatActivity
{
AndroidX.AppCompat.Widget.Toolbar toolbar;
RecyclerView postRecyclerView;
PostAdapter postAdapter;
List<Post> ListOfPost;
RelativeLayout layStatus;
//ImageView cameraImage;
AndroidX.DrawerLayout.Widget.DrawerLayout drawerLayout;
Google.Android.Material.Navigation.NavigationView navigationView;
PostEventListener postEventListener;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
toolbar = (AndroidX.AppCompat.Widget.Toolbar)FindViewById(Resource.Id.toolbar);
SetSupportActionBar(toolbar);
drawerLayout = (AndroidX.DrawerLayout.Widget.DrawerLayout)FindViewById(Resource.Id.drawerLayout);
navigationView = (Google.Android.Material.Navigation.NavigationView)FindViewById(Resource.Id.navview);
navigationView.NavigationItemSelected += NavigationView_NavigationItemSelected;
//this block of code is new since git upload
AndroidX.AppCompat.App.ActionBar actionBar = SupportActionBar;
actionBar.SetHomeAsUpIndicator(Resource.Drawable.menuaction);
actionBar.SetDisplayHomeAsUpEnabled(true);
postRecyclerView = (RecyclerView)FindViewById(Resource.Id.postRecycleView);
layStatus = (RelativeLayout)FindViewById(Resource.Id.layStatus);
layStatus.Click += LayStatus_Click;
//cameraImage = (ImageView)FindViewById(Resource.Id.camera);
//cameraImage.Click += LayStatus_Click;
// Retreives fullname on Login
FullnameListener fullnameListener = new FullnameListener();
fullnameListener.FetchUser();
// CreateData();
FetchPost();
}
private void NavigationView_NavigationItemSelected(object sender, Google.Android.Material.Navigation.NavigationView.NavigationItemSelectedEventArgs e)
{
if (e.MenuItem.ItemId == Resource.Id.navFunds)
{
Intent intent = new Intent(this, typeof(FundsActivity));
// intent.PutExtra("topic", "History");
StartActivity(intent);
drawerLayout.CloseDrawers();
}
else if (e.MenuItem.ItemId == Resource.Id.navHealth)
{
Intent intent = new Intent(this, typeof(HealthActivity));
// intent.PutExtra("topic", "History");
StartActivity(intent);
drawerLayout.CloseDrawers();
}
else if (e.MenuItem.ItemId == Resource.Id.navProfile)
{
Intent intent = new Intent(this, typeof(ProfileActivity));
intent.PutExtra("topic", "History");
StartActivity(intent);
drawerLayout.CloseDrawers();
}
else if (e.MenuItem.ItemId == Resource.Id.navLogout)
{
postEventListener.RemoveListener();
AppDataHelper.GetFirebaseAuth().SignOut();
StartActivity(typeof(LoginActivity));
Finish();
drawerLayout.CloseDrawers();
}
}
private void LayStatus_Click(object sender, EventArgs e)
{
StartActivity(typeof(CreatePostActivity));
}
void FetchPost()
{
postEventListener = new PostEventListener();
postEventListener.FetchPost();
postEventListener.OnPostRetrieved += PostEventListener_OnPostRetrieved;
}
private void PostEventListener_OnPostRetrieved(object sender, PostEventListener.PostEventArgs e)
{
ListOfPost = new List<Post>();
ListOfPost = e.Posts;
if (ListOfPost != null)
{
ListOfPost = ListOfPost.OrderByDescending(x => x.PostDate).ToList();
}
SetupRecyclerView();
}
void CreateData()
{
ListOfPost = new List<Post>();
ListOfPost.Add(new Post { PostBody = "The United States has been lobbying for months to prevent its western allies from using Huawei equipment in their 5G deployment, and on Wednesday, Washington made it more difficult for the Chinese telecom ", Author = "Uchenna Nnodim", LikeCount = 12 });
ListOfPost.Add(new Post { PostBody = "TE Connectivity is a technology company that designs and manufactures connectivity and sensor products for harsh environments in a variety of industries, such as automotive, industrial equipment, ", Author = "Johan Gasierel", LikeCount = 34 });
ListOfPost.Add(new Post { PostBody = "Singapore-based startup YouTrip thinks consumers of Southeast Asia deserve a taste of the challenger bank revolution happening in the U.S. and Europe, and it has raised $25 million in new funding to bring its app-and-debit-card service to more parts in the region.", Author = "Kylie Jenna", LikeCount = 6 });
ListOfPost.Add(new Post { PostBody = "TE Connectivity is a technology company that designs and manufactures connectivity and sensor products for harsh environments in a variety of industries, such as automotive, industrial equipment, ", Author = "Johan Gasierel", LikeCount = 78 });
}
void SetupRecyclerView()
{
postRecyclerView.SetLayoutManager(new AndroidX.RecyclerView.Widget.LinearLayoutManager(postRecyclerView.Context));
postAdapter = new PostAdapter(ListOfPost);
postRecyclerView.SetAdapter(postAdapter);
postAdapter.ItemLongClick += PostAdapter_ItemLongClick;
postAdapter.LikeClick += PostAdapter_LikeClick;
}
private void PostAdapter_LikeClick(object sender, PostAdapterClickEventArgs e)
{
Post post = ListOfPost[e.Position];
LikeEventListener likeEventListener = new LikeEventListener(post.ID);
if (!post.Liked)
{
likeEventListener.LikePost();
}
else
{
likeEventListener.UnlikePost();
}
}
private void PostAdapter_ItemLongClick(object sender, PostAdapterClickEventArgs e)
{
string postID = ListOfPost[e.Position].ID;
string ownerID = ListOfPost[e.Position].OwnerId;
if (AppDataHelper.GetFirebaseAuth().CurrentUser.Uid == ownerID)
{
AndroidX.AppCompat.App.AlertDialog.Builder alert = new AndroidX.AppCompat.App.AlertDialog.Builder(this);
alert.SetTitle("Edit or Delete Post");
alert.SetMessage("Are you sure");
// Edit Post on Firestore
alert.SetNegativeButton("Edit Post", (o, args) =>
{
EditPostFragment editPostFragment = new EditPostFragment(ListOfPost[e.Position]);
var trans = SupportFragmentManager.BeginTransaction();
editPostFragment.Show(trans, "edit");
});
// Delete Post from Firestore and Storage
alert.SetPositiveButton("Delete", (o, args) =>
{
AppDataHelper.GetFirestore().Collection("posts").Document(postID).Delete();
StorageReference storageReference = FirebaseStorage.Instance.GetReference("postImages/" + postID);
storageReference.Delete();
});
alert.Show();
}
}
public override bool OnOptionsItemSelected(IMenuItem item)
{
switch (item.ItemId)
{
case Android.Resource.Id.Home:
drawerLayout.OpenDrawer((int)GravityFlags.Left);
return true;
default:
return base.OnOptionsItemSelected(item);
}
}
}
}
If you need anymore code snippets of a particular class or xml, you can add a comment stating so. I will be more than happy to provide as much code snippets as I can or even provide you with the full source code. Your help will be highly appreciated.
Looking to create a popup where the user must type 'CONFIRM' to continue. I know how to develop a popup with 'CONTINUE' or 'CANCEL' on it but unsure of how to implement one that checks/validates the users input.
Using native Xamarin on Android with C#.
This is what I have so far. I just need some way of comparing what the user has input to the word CONFIRM
EditText et = new EditText(this);
AlertDialog.Builder ad = new AlertDialog.Builder (this);
ad.setTitle ("Type text");
ad.setView(et); // <----
ad.show();
Create a layout with EditText named CustomDialog.xml.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="#+id/editText_Name"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
Code in MainActivity.cs OnCreate method.
var editText = LayoutInflater.Inflate(Resource.Layout.CustomDialog, null);
var ad = (new AlertDialog.Builder(this)).Create();
ad.SetTitle("Type text");
ad.SetView(editText); // <----
ad.SetButton("Confirm", ConfirmButton);
ad.Show();
The code of ConfirmButton.
void ConfirmButton(object sender, DialogClickEventArgs e)
{
var dialog = (AlertDialog)sender;
var username = (EditText)dialog.FindViewById(Resource.Id.editText_Name);
var name = username.Text;
if (name=="hello")
{
}
}
You could get the text of EditText now.
Updated:
In Xamarin.forms, when you want to display a prompt, you could use DisplayPromptAsync.
protected override void OnAppearing()
{
base.OnAppearing();
PopUp();
}
public async void PopUp()
{
string s = await DisplayPromptAsync("Pop up Window", "Type text:", "Confirm", keyboard: Keyboard.Text);
if (s == "hello")
{
//do something here...
}
}
Display Pop-ups: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/pop-ups
I'm still fairly new to Visual Studio/Xamarin but I had a simple OpenStreetMap sample running awhile ago for Android that did display a map but that doesn't seem to display map anymore though I haven't changed the code for this sample in awhile as far as I recall. I'm not sure if some Visual Studio/Xamarin or MacOS update might have caused it to not work anymore.
I'm using Visual Studio for Mac community 8.4.4 (build 91) on macOS Mojava 10.14.6 and the following Packages:
Mapsui 1.4.8
OsmSharp 6.2.0
Xamarin.Android.Support.Core.Utils 28.0.0.1
Xamarin.Android.Support.CustomTabs 28.0.0.1
Xamarin.Android.Support.Design 28.0.0.1
Xamarin.Essentials 1.2.0
My MainActivity.cs file contains the following code:
using System;
using Android.App;
using Android.OS;
using Android.Runtime;
using Android.Support.Design.Widget;
using Android.Support.V7.App;
using Android.Views;
using Android.Widget;
using Mapsui;
using Mapsui.Geometries;
using Mapsui.Projection;
using Mapsui.Styles;
using Mapsui.Utilities;
using Mapsui.UI.Android;
using Mapsui.Widgets.ScaleBar;
using Mapsui.Widgets.Zoom;
using Xamarin.Essentials;
namespace mvp_android
{
[Activity(Label = "#string/app_name", Theme = "#style/AppTheme.NoActionBar", MainLauncher = true)]
public class MainActivity : AppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
SetContentView(Resource.Layout.Main);
var mapControl = FindViewById<MapControl>(Resource.Id.mapcontrol);
var map = new Mapsui.Map();
map.Layers.Add(OpenStreetMap.CreateTileLayer());
map.Widgets.Add(
new ZoomInOutWidget(map) {
HorizontalAlignment = Mapsui.Widgets.HorizontalAlignment.Left,
VerticalAlignment = Mapsui.Widgets.VerticalAlignment.Top,
Orientation = Mapsui.Widgets.Zoom.Orientation.Horizontal,
}
);
var centerOfLondonOntario = new Point(-81.2497, 42.9837);
map.NavigateTo(SphericalMercator.FromLonLat(centerOfLondonOntario.X, centerOfLondonOntario.Y));
map.NavigateTo(map.Resolutions[9]);
mapControl.Map = map;
}
public override bool OnCreateOptionsMenu(IMenu menu)
{
MenuInflater.Inflate(Resource.Menu.menu_main, menu);
return true;
}
public override bool OnOptionsItemSelected(IMenuItem item)
{
int id = item.ItemId;
if (id == Resource.Id.action_settings)
{
return true;
}
return base.OnOptionsItemSelected(item);
}
private void FabOnClick(object sender, EventArgs eventArgs)
{
View view = (View)sender;
Snackbar.Make(view, "Replace with your own action", Snackbar.LengthLong)
.SetAction("Action", (Android.Views.View.IOnClickListener)null).Show();
}
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);
}
}
}
And my Main.xml contains the following code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Mapsui.UI.Android.MapControl
android:id="#+id/mapcontrol"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Originally, this sample showed the OpenStreetMap's map centering on the London, Ontario location with zoom in/out buttons, but now it just shows a white where the map should be, still shows the zoom in/out buttons and does display the (c)OpenStreetMap watermark.
What am I missing here?
Update 2021-03-23: Since last week the "BruTile Tile Library" user agent is blocked by OpenStreetMap. This is the default of BruTile's KnownTileSource.Create. This method has a parameter to pass in your own user agent. The fix is to provide a string that is specific to your app.
The version of BruTile used in Mapsui 1.4.8 did not send the user-agent as part of it's request and at some point the openstreetmap server started blocking requests for this reason.
As a workaround you could create a custom ITileSource as described here by Matt Schneeberger:
https://github.com/Mapsui/Mapsui/issues/668#issuecomment-497947690
I'd create a xamarin android project on visual studio who take a photo from the camera, but I have a problem, I can take the photo but I don't know how I can make to the project after take the photo send the photo to the drawable folder of the project, how can I make this?
The XAML Code
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="10">
<ImageView
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:background="#c1cdcd"
android:layout_weight="9"
android:id="#+id/imgvw1" />
<Button
android:text="Take a Photo"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/btnCamera" />
</LinearLayout>
The MainAcivity
using Android.App;
using Android.Widget;
using Android.OS;
using Android.Content;
using Android.Provider;
using Android.Runtime;
using Android.Graphics;
using System;
namespace Droid_Camera
{
[Activity(Label = "Droid_Camera", MainLauncher = true, Icon =
"#drawable/icon")]
public class MainActivity : Activity
{
ImageView imgView1;
Button btnCamera;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.Main);
btnCamera = FindViewById<Button>(Resource.Id.btnCamera);
imgView1 = FindViewById<ImageView>(Resource.Id.imgvw1);
btnCamera.Click += BtnCamera_Click;
}
protected override void OnActivityResult(int requestCode,
[GeneratedEnum] Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
Bitmap bitmap = (Bitmap)data.Extras.Get("data");
imgView1.SetImageBitmap(bitmap);
}
private void BtnCamera_Click(object sender, System.EventArgs e)
{
Intent intent = new Intent(MediaStore.ActionImageCapture);
StartActivityForResult(intent, 0);
}
}
You can't do this unfortunately, the Drawables folder is a compile time resource that you cannot add to in run time. Otherwise, the R.java file would not be valid.
As the comments and answers mentioned you cannot add a file at runtime to your Drawable. As a matter of fact you cannot add any file to the bundle itself in runtime.
What you can do is add your file to the filesystem. If you want the file to be 'visible' only to your app use getFilesDir(). This returns a folder path present in your application sandbox. If it's meant to be a sort of temporary file and is less than 1MB use getCacheDir()
If the file is meant to be publicly visible use getExternalStoragePublicDirectory() but for this you would need WRITE_EXTERNAL_STORAGE permission.
Check out the documentation for details
When my activity starts and I initially load my ListView with items, I want to be able to set some of those items to checked however that doesn't seem to be working.
I'm using the simple_list_item_multiple_choice layout so the items are CheckedTextView.
Here's the adapter. Text displays properly however the Checked property doesn't seem to be doing anything visually despite it being set to true/false.
public class VehicleSubListAdapter : BaseAdapter<string>
{
// ...
public override View GetView(int position, View convertView, ViewGroup parent)
{
View view = convertView ?? _context.LayoutInflater.Inflate(Android.Resource.Layout.SimpleListItemMultipleChoice, parent, false);
var checkedTextView = view.FindViewById<CheckedTextView>(Android.Resource.Id.Text1);
checkedTextView.Text = _items[position].Name;
// This doesn't seem to do anything
checkedTextView.Checked = _items[position].Checked;
// I've even tried this with no change visually
//checkedTextView.Checked = true;
return view;
}
}
Here's the activity which can be closed and re-opened but needs to resume from where it left off (some items checked, some items not). That is why things are stored in a global static variable.
If the global list is empty, manually update the lists. Else, load from the global list. It successfully loads from the global list and successfully stores the Checked property of that list as modified in the item click event. However, the checked items aren't shown as checked when the activity loads.
Also I've tried putting the call to FillList() in both OnCreate and OnResume and neither have worked.
public class VehicleConditionSubActivity : ListActivity
{
private List<VehicleConditionItemDTO> _items;
private VehicleSubListAdapter _vehicleAdapter;
//...
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetTheme(Resource.Style.MyAppTheme);
SetContentView(Resource.Layout.VehicleConditionItem);
// Set up action bar
ActionBar.SetDisplayHomeAsUpEnabled(true);
// Set up list view
ListView.ChoiceMode = ChoiceMode.Multiple;
_items = new List<VehicleConditionItemDTO>();
_vehicleAdapter = new VehicleSubListAdapter(this, _items);
ListAdapter = _vehicleAdapter;
ListView.ItemClick += ListView_ItemClick;
//...
// Fill list view
FillList();
}
private void FillList()
{
AddFluidItems();
_vehicleAdapter.NotifyDataSetChanged();
}
private void AddFluidItems()
{
// I've checked that this is being called correctly
if (Global.Conditions.FluidLevels.Count > 0)
{
foreach (var item in Global.Conditions.FluidLevels)
{
_items.Add(item);
}
}
else
{
_items.Add(new VehicleConditionItemDTO("1", "Engine oil"));
// ...
foreach (var item in _items)
{
Global.Conditions.FluidLevels.Add(item);
}
}
}
// ...
private void ListView_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
{
// Items already check/uncheck properly when tapped
// So I just update the global list items checked property
Global.Conditions.FluidLevels[e.Position].Checked = !Global.Conditions.FluidLevels[e.Position].Checked;
}
}
The layout for the activity is
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:minWidth="25px"
android:minHeight="25px"
android:background="#color/background">
<ListView
android:minWidth="25px"
android:minHeight="25px"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#android:id/list" />
</LinearLayout>
Selecting Items Programmatically
Manually setting which items are ‘selected’ is done with the
SetItemChecked method (it can be called multiple times for multiple
selection)
Customizing A List View's Appearance
Note that SetItemChecked is on the ListView.
You can remove the code in GetView that sets Checked.
Then, after (or during the call to FillList) for each item that should be initially checked, call:
ListView.SetItemChecked (position, true);