Display Xamarin Font Icons From Stored Data - web-services

What is the best way to display font icons with data being pulled from a web service? I want to store the value of the icon and display the icon similar to the rest of the information, but with a custom font icon.
I have a xamarin forms app working with data from a webservice successfully. Here is my model.
public class TypeModel
{
[PrimaryKey]
public int pType { get; set; }
public int fDepartment { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Icon { get; set; }
public string Version { get; set; }
}
I also got the font icons working successfully like the tutorial at [1]: https://montemagno.com/using-font-icons-in-xamarin-forms-goodbye-images-hello-fonts/ I got my icons stored under this class. Trying to transition to managing these values with web service or array if I have too now.
public const string IconCheckMark = "\uf12c";
public const string IconSearchGlass = "\uf349";
public const string IconQuestionMark = "\uf2d6";
public const string IconQuestionCircle = "\uf2d7";
But here is where my problem starts. My ViewModel is doing the work to create the collection. How do I assign a value that will display and match correctly.
public ObservableCollection<TypeModel> TypesCollection { get; set; }
TypesCollection.Clear();
IEnumerable<TypeModel> types = await DataSource.GetTypes();
foreach (var key in types)
{
\\Original value doesn't display correctly, shows like \U f 1 2 c when debugging on emulator
\\key.Icon = key.Icon;
\\Works and displays correctly but static data displays one icons for all
\\key.Icon = "\uf12c";
\\Works and displays correctly but static data displays one icons for all
\\key.Icon = FontClass.IconCheckMark;
TypesCollection.Add(key);
}
Nice and simple after that for the xaml files.
<ResourceDictionary>
<OnPlatform x:Key="IconFonts" x:TypeArguments="x:String">
<On Platform="iOS" Value="Material Design Icons"></On>
<On Platform="Android" Value="IconFonts.ttf#Material Design Icons"></On>
<On Platform="UWP" Value="/Assets/IconFonts.ttf#Material Design Icons"></On>
</OnPlatform>
</ResourceDictionary>
<Label FontFamily="{StaticResource IconFonts}" Text="{Binding Icon}"></Label>

What is the type of key.Icon? If it is string, you can remove the white space between the characters by:
key.Icon = key.Icon.Replace(" ", "").ToLower();

Got the answer from Microsoft Dev Community. First to explain what was happening: When you put the following in C# code:
Icon = "\uf2d6"
The “\uf2d6” is not actually a literal string, but rather it ends up being a single character (the one represented by that UTF code) at compile time. In other words the “\u” means that what follows is a hex code for a character and that whole “string” will end up just being that one character. If you inspect the Icon property after the above assignment, you will see that the property only contains a single character, not the “\uf2d6” string.
So when you get “2d6” from your web service in the Icon property, and then try to add “\uf” before it, you are not creating the escape sequence for the character but rather adding to the string literal. So what you need to do is parse the string for the hex number into an int and then cast it to a char and then assign that character to your Icon property. You can do this as follows (put this in the foreach loop in the sample you sent me):
string utfCode = $"f{key.Icon}"; // Adds the leading “f” to make it a correct hex number for the desired UTF code.
int character = int.Parse(utfCode, System.Globalization.NumberStyles.HexNumber); // parses that string literal into an int
key.Icon = ((char)character).ToString(); // casts that int to a char and then gets the string representation for that character and assigns it back to your Icon property
TypesCollection.Add(key);

Related

Osmdroid 5.6, offline MBTiles

I'm trying to use MBtiles offline with osmdroid,
I took code sample from here https://github.com/osmdroid/osmdroid/blob/master/OpenStreetMapViewer/src/main/java/org/osmdroid/samplefragments/tileproviders/SampleOfflineOnly.java
But always empty map shown, is there problem with my code?
my code is:
public class OSMDroid extends AppCompatActivity {
private MapView mapView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_osmdroid);
mapView = (MapView) findViewById(R.id.map);
String name = "map.mbtiles";
File f = new File(Environment.getExternalStorageDirectory() + "/osmdroid", name);
if (f.exists()) {
try {
//ok found a file we support and have a driver for the format, for this demo, we'll just use the first one
//create the offline tile provider, it will only do offline file archives
//again using the first file
OfflineTileProvider tileProvider = new OfflineTileProvider(new SimpleRegisterReceiver(this),
new File[]{f});
//tell osmdroid to use that provider instead of the default rig which is (asserts, cache, files/archives, online
mapView.setTileProvider(tileProvider);
//this bit enables us to find out what tiles sources are available. note, that this action may take some time to run
//and should be ran asynchronously. we've put it inline for simplicity
String source = "";
IArchiveFile[] archives = tileProvider.getArchives();
if (archives.length > 0) {
//cheating a bit here, get the first archive file and ask for the tile sources names it contains
Set<String> tileSources = archives[0].getTileSources();
//presumably, this would be a great place to tell your users which tiles sources are available
if (!tileSources.isEmpty()) {
//ok good, we found at least one tile source, create a basic file based tile source using that name
//and set it. If we don't set it, osmdroid will attempt to use the default source, which is "MAPNIK",
//which probably won't match your offline tile source, unless it's MAPNIK
source = tileSources.iterator().next();
mapView.setTileSource(FileBasedTileSource.getSource(source));
} else {
mapView.setTileSource(TileSourceFactory.DEFAULT_TILE_SOURCE);
}
} else {
mapView.setTileSource(TileSourceFactory.DEFAULT_TILE_SOURCE);
}
mapView.setUseDataConnection(false);
mapView.setBuiltInZoomControls(true);
IMapController mapController = mapView.getController();
mapController.setZoom(10);
GeoPoint startPt = new GeoPoint(61.5797,51.5997);
mapController.setCenter(startPt);
mapView.invalidate();
return;
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
MBTilesFileArchive getTileSources always returns empty string, here is implementation:
public Set<String> getTileSources(){
//the MBTiles spec doesn't store source information in it, so we can't return anything
return Collections.EMPTY_SET;
}
In order to make a offline map you should add tiles first. You can use Maperitive app to make your map tiles(zip is easier to manage than sql). Name the zip MapquestOSM. After you have done it create a folder "osmdroid" in phones memory(Directly into the internal memory or sd card) and add your map tiles in it.
Parameters of the XYTileSource changes related to the map tiles you have created. This code handles everything about map tiles itself. I hope it helps you
mapView.setUseDataConnection(false);
mapView.setTileSource(new XYTileSource("MapquestOSM", 2, 15, 256, ".png", new String[]{}));

display a text from a list

I'm trying to display several lines into a Text area from a string list. But it's only displaying the last one of the list, and i would like to display them all. Thanks for your help !
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class contenuTexte : MonoBehaviour {
public List <string> montexte;
public GameObject zoneAffichage;
// Update is called once per frame
void Start ()
{
foreach ( string lines in montexte)
zoneAffichage.GetComponent<Text>().text = "\n"+lines;
}
}
Your problem is that you are resetting the string on every loop to the last string. At the end of the loop you are going to only have the last string in the text.
First let's join all the strings together as one (using .ToArray() because of .NET 3.5), and then set them all at once:
var completeText = String.Join("\n", montexte.ToArray());
zoneAffichage.GetComponent<Text>().text = completeText;

Card not showing; goes straight to home card

I am trying to show a card so I know everything up to that point works. However, when I try to display the card, it just goes straight to the home card. The card I was trying to show was just going to display what was said in the voice recognizer before but that didn't work so I just put plain text and that didn't work either. Application goes - voice trigger --> voice recognizer --> this service:
public class MedMinderService extends Service {
public String MedName;
public String voiceResults;
private static final String TAG = "ShowData";
private static final String LIVE_CARD_ID = "showdata";
public static final String PREFS_NAME = "MyPreferencesFile";
private TimelineManager mTimelineManager;
private LiveCard mLiveCard;
#Override
public void onCreate() {
super.onCreate();
mTimelineManager = TimelineManager.from(this);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
public int onStartCommand(Intent intent, int flags, int startId) {
String voiceResults = intent.getExtras()
.getString(RecognizerIntent.EXTRA_RESULTS);
String MedName = voiceResults; //MedName declared
SharedPreferences MedInfo = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = MedInfo.edit();
editor.putString("MedName", MedName.toString());
editor.commit();
mLiveCard = mTimelineManager.getLiveCard(LIVE_CARD_ID);
Intent i = new Intent(this, ShowDataActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
return START_STICKY;
}
}
The intent at the bottom goes to this activity:
public class ShowDataActivity extends Activity {
private LiveCard mLiveCard;
public static final String PREFS_NAME = "MyPreferencesFile";
private GestureDetector mGestureDetector;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences MedInfo = getSharedPreferences(PREFS_NAME, 0);
Card ShowDataCard = new Card(this);
ShowDataCard.setText("IT WORKS!");
//ShowDataCard.setText(MedInfo.getString("MedName", "your medication"));
View ShowDataCardView = ShowDataCard.toView();
setContentView(ShowDataCardView);
}
The "ShowDataCard" that has been commented out is what I was origonally trying to do with the voice recognition but it wouldn't even work with the text "IT WORKS!"
Again: I am just trying to show a card with the text "IT WORKS"
thanks
The easiest way to get a live card to appear with just text is using widgets that are compatible with RemoteViews. You can find a list of them in the GDK documentation here:
https://developers.google.com/glass/develop/gdk/ui/live-cards
under the Creating low-frequency live cards section.
Here is some sample code (based on your code above) that can get that working quickly:
final String LIVE_CARD_ID = "showdata";
mLiveCard = mTimelineManager.getLiveCard(LIVE_CARD_ID);
RemoteViews remoteViews =
new RemoteViews(getPackageName(), R.layout.layout_helloglass);
mLiveCard.setViews(remoteViews);
// Make sure Glass navigates to LiveCard immediately
mLiveCard.setNonSilent(true);
mLiveCard.publish();
The layout file can look like this for layout_helloglass.xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="Hello, Glass!" />
</FrameLayout>
If you still want to navigate to another Activity from your LiveCard, you need to associate the Activity with a PendingIntent and then associate that PendingIntent with the LiveCard's action. This would happen immediately before the LiveCard.publish() method:
Intent i = new Intent(this, ShowCardActivity.class);
mLiveCard.setAction(PendingIntent.getActivity(this, 0, i, 0));
That should get you up and running! Hopefully this will help.
There was a bug in the GDK Sneak Peek that prevented voice prompts from creating Services. If one inserted a Log.d() call in a Service's onStartCommand() override, they would discover that it were never called.
This bug has been fixed in the GDK Preview. This behavior should not appear again.
This question was rewritten after the GDK Preview launch to remove this outdated answer. Thanks to user Falcon for notifying me.

WICKET: Updating a self-made Panel

ive got the following Problem:
my self-made video-class (extending Panel) doesnt get updated, if its model changes.
Thats the current state:
I got a Class "A" with a ListChoice. This Class creates the Panel "descrPanel", which gets a Model, containing the current selected Item of the ListChoice. It is updated, when the User selects something in the ListChoice (The ListChoice got an AjaxBehaviour, updating the descrPanel via target.add(descrPanel)):
Class A:
PropertyModel<Exercise> currExerciseModel = new PropertyModel<Exercise>(this,"selectedExercise");
final ExerciseDescriptionPanel descrPanel = new ExerciseDescriptionPanel("descrPanelTag", currExerciseModel);
descrPanel.setOutputMarkupId(true);
In Class ExerciseDescriptionPanel, i inserted my self-made Video-Class (extending Panel). Also i inserted a MultiLineLabel:
Class ExerciseDescriptionPanel
public class ExerciseDescriptionPanel extends Panel {
private IModel<Exercise> model;
private Exercise exercise;
public ExerciseDescriptionPanel(String id, IModel<Exercise> model) {
super(id, model);
this.model = model;
MultiLineLabel mll = new MultiLineLabel("mll", new Model() {
#Override
public String getObject() {
if (ExerciseDescriptionPanel.this.getModel().getObject() != null){
return ExerciseDescriptionPanel.this.getModel().getObject().getDescription();
}
else return "";
}
});
add(mll);
Video video = new Video("myVideo", new Model<Exercise>(){
#Override
public Exercise getObject() {
if (ExerciseDescriptionPanel.this.getModel().getObject() != null){
return ExerciseDescriptionPanel.this.getModel().getObject();
}
else return new Exercise();
}
});
add(video);
}
Well, what i dont understand is: While the Description is updated based on the current selection of the ListChoice, the Video-Class just ignores it and keeps returning the "new Exercise()", which schould only be returned at the first load of the ListChoice, when no selection is made.
I also provide you the Video-Class:
Class Video
public class Video extends Panel{
private IModel<Exercise> model;
public Video(String id, IModel<Exercise> model) {
super(id, model);
String src = ((Exercise)model.getObject()).getVideo();
String startPicDest = ((Exercise)model.getObject()).getPicture();
WebMarkupContainer flashSrc = new WebMarkupContainer("flashSrcTag");
flashSrc.add(new AttributeModifier("value", "config={'playlist':['" +
startPicDest +"',{'url':'"+ src +"','autoPlay':false}]}"));
this.add(flashSrc);
setOutputMarkupId(true);
}
}
Ive been searching through the internet for hours now, without finding anything helpful.
Hope you guys are able to give me some solution to this problem. Thanks in regard.
Greetings
You're pulling the exercise out of the model once only:
public Video(String id, IModel<Exercise> model) {
super(id, model);
String src = ((Exercise)model.getObject()).getVideo();
...
}
How is this supposed to be up-to-date when the exercise changes later on?
You have to get the actual value for each render:
WebMarkupContainer flashSrc = new WebMarkupContainer("flashSrcTag") {
public void onComponentTag(ComponentTag tag) {
Exercise temp = (Exercise)model.getObject();
String src = temp.getVideo();
String startPicDest = temp.getPicture();
tag.put("value", String.format("config={'playlist':['%s',{'url':'%s','autoPlay':false}]}", startPicDest, src));
}
};
NOTE: Please ignore this humble try to help you, svenmeier's answer is way better than mine.
I'm not 100% sure if this is true, but could it be related to the difference between your Video being a MarkupContainer and the MultiLineLabel being a WebComponent?
Both the Video and the MultiLineLabel are added to the ExerciseDescriptionPanel in its constructor. If I understand the Wicket documentation correctly, as long as the surrounding Page and thus the ExerciseDescriptionPanel stay the same instance, the markup of the Video will not be regenerated. It says:
A Page renders itself by rendering its associated markup (the html file that sits next to the Page). As MarkupContainer (the superclass for Page) iterates through the markup stream for the associated markup, it looks up components attached to the tags in the markup by id. Since the MarkupContainer (in this case a Page) is already constructed and initialized by onBeginRequest(), the child for each tag should be available in the container. Once the Component is retrieved, it's render() method is called.
Maybe you calling modelChanged() on your Video once you change the Model of your ExerciseDescriptionPanel could indicate that the markup has to be refreshed.

How can I change the width of a column from a child band Infragistics.UltraGrid

public class Ticket
{
public bool Selected { get; set; }
public string TicketID { get; set; }
public List<TicketHistory> History {get;set;}
}
public class TicketHistory
{
public string Status {get;set;}
}
I have an Infragistics ultragrid with multi bands.
ultragrid.DisplayLayout.ViewStyle = ViewStyle.MultiBand;
ultragrid is bound to a List of Ticket (1st band) 2nd band is History with a List of TicketHistory
The problem is that the column Status from the 2nd band is shown with the same size as Selected column (checkbox column) from 1st band.
How can I change the width of the column (Status) from the child band?
1. I tried to change the width in the InitializeLayout handler but it didnt work.
2. I tried PerformAutoresize on ultragridcolumn and didnt work.
You should set the property AllowColSizing to AllowColSizing.Free
You can set this property using the UltraGrid Designer or in code using this line:
grid.DisplayLayout.Override.AllowColSizing =
Infragistics.Win.UltraWinGrid.AllowColSizing.Free;
This will give to each child band in your grid the ability to resize its columns indipendently from the size of the column in the corresponding position on the parent band.