Android using Drawables in an Enum - android

I have a project that I have to design an array of coins and work with it. My GUI looks like this - http://i.imgur.com/eRzN3Sb.png
I want to be able to load the appropriate image from the coinArray for each coin. basically i want to be able to say coinView.setBackgroundResource(coinArray[x].image) i assume i need to somehow use a drawable object and i was hoping its possible to include it in my enum class. the enum class looks like
public enum Currency {
Penny(1), Nickel(5), Dime(10), Quarter(25);
private int value;
private Currency(int value) {
this.value = value;
}
}
Each coin in the array has a currency value so i can compute them. I'd like to add a drawable or some other object that will allow me to refernce the correct image for each coin.
Thank you

public enum Currency {
Penny(1,R.drawable.xxx), Nickel(5,R.drawable.yyy),...;
private int value;
private int image
private Currency(int value,int drawableId) {
this.value = value;
this.image=drawableId;
}
public int getImage(){
return image;
}
}
There are many ways you can do this. This is one of them. to use it:
coinView.setImageResource(coinArray[x].getImage());

Related

use Enum in ListPreference

I have a pretty simple Enum that I am using throughout my application for Gender and I need to have a settings page where the user can change it, but I can't find any way to use an Enum in a ListPreference. I am using a PreferenceFragment to build the Preferences Screen, but I can't find a way to use the Enum I have as the entries and entryValues for the ListPreference.
The enum is very simple, just...
public enum Gender implements EnumSpinner {
MALE("Male", 0),
FEMALE("Female", 1),
NONE("Prefer not to say", -1);
private static SparceArray<Gender> genderMap = new SparceArray<>();
static {
for(Gender gender : Gender.values()) {
genderMap.put(gender.getValue(), gender);
}
}
private String name;
private int value;
Gender(String name, int value) {
this.name = name;
this.value = value;
}
public static Gender getGender(int val) { return genderMap.get(val); }
#Override
public String toString() { return name; }
public String getName() { return name; }
public int getValue() { return value; }
}
Is it possible to use in a ListPreference or am I going to have to create 2 string arrays in the strings.xml file and just use it that way?
SideNote, EnumSpinner is just an interface that allows me to use the enum in a spinner.
Please check in the google developers youtube channel, Android Performance Matters there is a video explaining why you would prefer not using enums in Android, there are other ways to get the same functionality.
Android has a Framework for Settings/Preferences, you can find an excellent tutorial here.
Buuilding Settings Screen Android

Is this a good practice? (Class fields)

I need to have a relatively large number of categories defined (about 30 at start, we'll be adding more). Consider this code:
public class Category {
public static final Category DRESS = new Category("Dress");
public static final Category SKIRT = new Category("Skirt");
...
private static final List<Category> CATEGORIES = Arrays.aslist(DRESS, SKIRT, ...);
private String name;
public Category(String name) {
this.name = name;
}
//Some static public method to iterate over categories
...
I need to have the categories declared and also need a way to iterate over them. I discard reflection because I think it's not a very good practice.
Is declaring a large name of static final fields of the same class and also having them inside a list a good practice? As an alternative, I thought about having a Map<Integer, Category> instead the list, and the fields were integers that would identify each category, so you would get the categories by getting them inside the map. Would this be better in terms of time and space performance?
PS: It's for an android project, if it changes something
Consider this code:
public class Category {
public static final Category DRESS = new Category("Dress");
public static final Category SKIRT = new Category("Skirt");
Yeah this is literally what enums do in the background, so
public enum Category {
DRESS("Dress"),
SKIRT("Skirt"),
...;
private String name;
private Category(String name) {
this.name = name;
}
// Category.values() returns the elements as an array
You should use enum instead of creating an object with new Category("Dress"); because creating an object is expensive than using enum. Java enums are implemented more like classes, so you can change your code seamlessly:
public enum Category {
DRESS("Dress"), SKIRT("Skirt");
private final String name;
Category(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
Note:
The constructor for an enum type must be package-private or private access. It automatically creates the constants that are defined at the beginning of the enum body. You cannot invoke an enum constructor yourself.
Read more about enum at Enum Types
I would say using a List is good enough.
You should consider a Map only if you have to look up a
particular Category very frequently via some key property (like an int your case).
If There are no properties or methods in the Category class consider replace them with just Strings.
If new Categories are created at runtime and you want to persist them consider using a DB or File to save the Categories.
Edit: Answering the question in the comment
That would depend on the Category class. If its only purpose is to enumerate all the categories and the class itself does not have any other instance methods or properties then in terms of space complexity an Integer and your Category class is similar (since in a Map integer will be boxed in the Integer class object)
I would still suggest that you use a class called Category and a list if the purpose is only iterating over them and/or using specific instances of the Category class elsewhere in your application eg. Category.SOME_CATEGORY.
The following example is a good use-case
someMethod(Category category) {
// do something
}
versus
someMethod(int category) {
// before doing anything
// lookup this category by an int key
// in the the Map<Integer, Category>
}
The problem with the latter is that you could pass any int which may or may not be a valid key for a category. Using a class gives some bit for extra compile time check. Though you could always use an int def too. But again I would repeat that it all boils down to whether Category class has any instance methods or properties.
For small list, it is okay to use List or Map.
But for a large list, you may want to store them in a database.
Also ArrayList of String will be slightly efficient than using ArrayList of Category

When is it good to use Enum in Android?

I saw the video(https://www.youtube.com/watch?v=Hzs6OBcvNQE) posted from google about price of enum and I'm convinced that enum cost more and has performance issue.
However, what about when I need to contain multiple information in an enum? Do I have to create intdef and stringdef to map the message?
Ie.
public enum Error{
NETWORK(1, "Network error!"),
STACK_OVER_FLOW(2, "Stack over flow error!");
final int mValue;
final String mMessage;
Error(int value, String message){
mValue = value;
mMessage = message;
}
public void getMessage(){
return mMessage;
}
public void getValue(){
return mValue
}
}
It is true that enums have that memory footprint, but just if are heavily using them, or sub using them, like comparisions or else, but if you're using such functionality like the one in your code, it's more than justified to work with them, in case you want to totally avoid enums, you can change this to a class.

is there anyway i can have listarray<string,int,int> in android?

is there anyway i can have multi dimensional array ex: listarray string,int,int in android??
it is quite possible with Map & Set in Java/C++.
Make your own container with fields good explaining its purpose:
class PersonData {
public int age;
public int id;
public String name }
And make list of it:
List<PersonData> dataList = new ArrayList<PersonData>();
Acces your fields by:
dataList.get(5).age = 11;
As Egor said in comment, a good practice will be set those field as protected and create setters and getters, if you don't need extreme performance in this specific case.

sorting custom object array on two fields

I'm sorting an array of custom objects (ListData[]) on two fields. I want it to be sorted by theme, and them by name. I thought i made a nice comparator in the custom object class and that i could use Arrays.sort(ld) to make my code working and sorting my array. But apparently im doing something wrong...
my custom object:
public class ListData implements Comparable<ListData>{
public int venueID;
public String name;
public String photoUrl;
public String tip;
public String theme;
#Override
public int compareTo(ListData ld0) {
return this.venueID- ld0.venueID;
}
public static Comparator<ListData> ListDataThemeAndNameComparator = new Comparator<ListData>() {
#Override
public int compare(ListData ld1, ListData ld2) {
String compareTheme1 = ld1.theme.toUpperCase();
String compareTheme2= ld2.theme.toUpperCase();
String compareName1 = ld1.name.toUpperCase();
String compareName2= ld2.name.toUpperCase();
//ascending
int comp = compareTheme1.compareTo(compareTheme2); // comp themes
if(comp==0){ // same theme
comp= compareName1.compareTo(compareName2); // compare names
}
return comp;
}
};
}
And in my main activity i have:
ListData ld[]= new ListData[jsonResponse.size()];
(some code filling my ListData array)
Arrays.sort(ld, ListData.ListDataThemeAndNameComparator); // compare by theme and then by name
Does anyone know what i'm doing wrong?
I edited my code But still it fails, now on a nullpointerexception on the compareTheme1 = ld1.theme.toUpperCase();. But i am sure my array is not empty, i logged it the line before sorting it and its filled with about 500 items.
Your ListData object should implements Comparable not Comparator interface.
EDIT:
To make things clear, you can sort an array by Array.sort(). To make custom sort, you can specify your comparator in Array.sort(), if you don't do that, array will be sorted in natural order which you can define by implementing Comparable interface. So you have two options how to custom sort:
by using custom comparator and specifying it in Array.sort()
by implementing Comparable interface to your items
I would suggest you to go with implementing Comparable. You save memory by not creating new comparator objects and Comparator is useful if you are comparing objects of different types which is not your case.

Categories

Resources