How to create a input popup in Xamarin Android - c#

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

Related

Xamarin custom keyboard. How to hide popupCharacters when touch on regular keys

I wrote custom keyboard with diacritics in popupCharacters. When I longpress on letter 'A' to show diacritics I can't dismiss it by touching anywhere on the rest of the keyboard (see image).
Image
I've implemented SetOnTouchListener() for keyboard and popup view and get MotionEvent etc. only for keyboard, but I don't know how can I detect that touch is out of bounds of popupCharacters and hide it. It looks like the whole keyboard is deactivated and ignore touches outside popups.
OnCreate
public override void OnCreate()
{
base.OnCreate();
_currentKeyboardView = (KeyboardView)LayoutInflater.Inflate(Resource.Layout.keyboard_view, null);
_popupView = (KeyboardView)LayoutInflater.Inflate(Resource.Layout.popup_view, null);
App.Init(Application);
}
Here is OnTouch() implementation
public bool OnTouch(View v, MotionEvent e)
{
Rect popupRect = new Rect();
_popupView.GetHitRect(popupRect);
if (!popupRect.Contains((int)e.GetX(), (int)e.GetY()))
{
Console.WriteLine("Outside view");
_popupView.Visibility = ViewStates.Gone;
}
else Console.WriteLine("Inside view");
_currentKeyboardView.OnTouchEvent(e);
return true;
}
Popup_view:
<?xml version="1.0" encoding="utf-8"?>
<android.inputmethodservice.KeyboardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/keyboardView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:keyBackground="#layout/key_background"
android:keyPreviewLayout="#null"
android:keyPreviewOffset="0px"
android:keyPreviewHeight="20px"
android:keyTextColor="#android:color/black"
android:background="#android:color/white"
android:shadowRadius="0.0"
android:horizontalGap="5px"
android:verticalGap="0px" >
</android.inputmethodservice.KeyboardView>

recycle view not rendering and displaying data from firebase when run on physical device but works fine on emulator

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.

Return data from DialogFragment to calling activity

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 */ };

Android ProgressBar disappears

I have an android ProgressBar which is indeterminate so it is simply a revolving circle animation.
It starts off displaying fine, but after I set the visibility of its parent (overlayLayout) to either gone or invisible and then set it back to visible later on, the progress bar is unseen?
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/overlayLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:gravity="center" >
<TextView
android:text=""
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_width="match_parent"
android:textAlignment="center"
android:layout_margin="10dp"
android:layout_height="wrap_content"
android:id="#+id/overlayLabelText" />
<ProgressBar
android:id="#+id/overlayProgressBar"
android:layout_below="#id/overlayLabelText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:foregroundGravity="center"
android:indeterminate="true" />
</RelativeLayout>
EDIT:
I'm unsure if the view is included but the progress bar is just not rendered or whether the ProgressBar view itself is completely excluded as I can't access the UI view hierarchy.
So far I have tried:
ProgressBar.Enabled = true;
ProgressBar.ForceLayout();
ProgressBar.Invalidate();
ProgressBar.SetProgress(0, true);
ProgressBar.Visibility = ViewStates.Visible;
But have had no breakthroughs yet.
EDIT 2:
Thankyou everyone for your help so far. I have switched to creating the layout programatically - this is my full code:
overlay = new RelativeLayout(mainActivity)
{
LayoutParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent)
};
overlay.SetBackgroundColor(Color.WhiteSmoke);
overlay.SetGravity(GravityFlags.Center);
description = new TextView(mainActivity)
{
LayoutParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent),
Gravity = GravityFlags.Center,
TextSize = 18,
Id = 1523112
};
description.Text = "Waiting for GPS";
description.SetBackgroundColor(Color.Aqua);
progressBar = new ProgressBar(mainActivity)
{
Indeterminate = true,
};
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent);
lp.AddRule(LayoutRules.Below, description.Id);
progressBar.LayoutParameters = lp;
progressBar.SetBackgroundColor(Color.Red);
container.AddView(overlay);
overlay.AddView(description);
overlay.AddView(progressBar);
With the two hiding and showing methods:
private void OnGpsUpdate()
{
overlay.Visibility = ViewStates.Gone;
}
private void NoGPS()
{
description.Text = "Waiting for GPS";
overlay.Visibility = ViewStates.Visible;
}
When the layout is first rendered, before its hidden for the first time:
(I screenshotted at a bad time, but blue drawing shows where the circle is moving around its loading animation)
After its been hidden and shown again, the progressBar loading view is there but there's no loading circle anymore:
I am starting to think it may just be a problem with my android emulator? Nope, same problem when testing on my physical phone. Text view still shows fine, its just the progress bar doesnt show?
SOLUTION
I don't fully understand it, seeing as everything else seemed to work except the progressBar, but a solution came from wrapping my visibility calls in a RunOnUIThread() call.
Few points
Based on how the problem was described, there is a need for you to show the code snippet you used for hiding/showing the overlayLayout
Recommendations
If you're only concerned with how the progress bar should behave in terms of hiding/showing, there's no need for this snippet:
ProgressBar.Enabled = true;
ProgressBar.ForceLayout();
ProgressBar.Invalidate();
ProgressBar.SetProgress(0, true);
ProgressBar.Visibility = ViewStates.Visible;
You just need to control the root layout which has the id of overlayLayout
private RelativeLayout overlayLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_example);
// Instantiate the layout
overlayLayout = findViewById(R.id.overlayLayout);
// Do the logic how you inflate/show the layout
...
// Hide the overlay layout
overlayLayout.setVisibility(View.GONE);
// Show the overlay layout
overlayLayout.setVisibility(View.VISIBLE);
}
Decide on the visibility value, for this scenario, I'd recommend View.GONE rather than View.INVISIBLE
Read more on:
https://developer.android.com/reference/android/view/View.html#GONE
https://developer.android.com/reference/android/view/View.html#INVISIBLE
http://tips.androidgig.com/invisible-vs-gone-view-in-android/
The solution was to add a RunOnUIThread like so:
private void OnNewGPS()
{
mainActivity.RunOnUiThread(() =>
{
overlay.Visibility = ViewStates.Gone; });
}
private void NoGPS()
{
mainActivity.RunOnUiThread(() =>
{
overlay.Visibility = ViewStates.Visible;
});
}
Where mainActivity is a reference to the Activity the views are running in.
I wrote a demo based on your code. And to test it, I added a button to control the show and hide of the layout.
You may try this:
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
// Instantiate the layout
overlayLayout = FindViewById<LinearLayout>(Resource.Id.overlayLayout);
progressBar = FindViewById<ProgressBar>(Resource.Id.overlayProgressBar);
description = FindViewById<TextView>(Resource.Id.textView1);
description.Text = "Waiting for GPS";
description.SetBackgroundColor(Color.Aqua);
progressBar.SetBackgroundColor(Color.Red);
switchBtn = FindViewById<Button>(Resource.Id.switchButton);
switchBtn.Click += SwitchBtn_Click;
overlayLayout.Visibility = Android.Views.ViewStates.Visible;
isShown = true;
}
private void SwitchBtn_Click(object sender, System.EventArgs e)
{
if (isShown)
{
overlayLayout.Visibility = Android.Views.ViewStates.Gone;
isShown = false;
switchBtn.Text = "Show";
}
else {
overlayLayout.Visibility = Android.Views.ViewStates.Visible;
isShown = true;
switchBtn.Text = "Hide";
}
You can download the demo from this
to hide layout:
findViewById(R.id.overlayLayout).setVisibility(View.GONE);
to display it again :
findViewById(R.id.overlayLayout).setVisibility(View.VISIBLE);

How to automatically add layout elements with c#?

I want to add elements into my layout automatically, how do I do that? For example a textview appears when a user clicks a button
To add a TextView or any other view in Android you must add the view you want to a view that support addition, one example is the LinearLayout.
If you have this layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/lnrRootView"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" />
And then in you Activity add a TextView programaticlly to your LinearLayout.
public class MainActivity : Activity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
var linearLayout = FindViewById<LinearLayout>(Resource.Id.lnrRootView);
var textView = new TextView(this);
textView.Text = "Added programaticlly";
linearLayout.AddView(textView);
}
}
You will get something like this:
Much depends on what you're trying to accomplish. You could simulate adding to layout by turning visibility of elements after certain event, eg. button click.
If you want to add elements dynamically during runtime, consider using
ObservableCollection<T>
Link: https://developer.xamarin.com/api/type/System.Collections.ObjectModel.ObservableCollection%601/
I don't know Xamarin.Android very well but I think the right way is to add controls to layout with "IsVisible = false", then set IsVisible = true.
Otherwise you can take a look to
LinearLayout principalview = FindViewById(Resource.Id.mainlayout);
LinearLayout.LayoutParams parametros = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MatchParent, LinearLayout.LayoutParams.MatchParent);
var valueB = new Button(this);
valueB.Text = "Teste";
valueB.SetBackgroundColor(Color.Aqua);
principalview.AddView(valueB, parametros);
OR
var layout = new LinearLayout (this);
layout.Orientation = Orientation.Vertical;
var aLabel = new TextView (this);
aLabel.Text = "Hello, World!!!";
var aButton = new Button (this);
aButton.Text = "Say Hello!";
aButton.Click +=(sender, e) =>
{aLabel.Text="Hello Android!";};
layout.AddView (aLabel);
layout.AddView (aButton);
SetContentView (layout);

Categories