Last active
October 27, 2021 21:09
-
-
Save EduardoSP6/dabc1b3b45225ff50b38c842c96e3702 to your computer and use it in GitHub Desktop.
Using Java Reflection with Andriod
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Java reflections can help us with optimizing developing time and easy maintenance of code. | |
// Let's imagine that we have an entity of checklist that have many fields to be filled by an form. | |
// 1- Create a class. | |
public class Checklist { | |
private String notes; | |
private Boolean coffeePrepeared; | |
private Boolean newsRead; | |
private Date createdAt; | |
public String getNotes() { | |
return notes; | |
} | |
private void setNotes(String notes) { | |
this.notes = notes; | |
} | |
public Boolean getCoffeePrepeared() { | |
return coffeePrepeared; | |
} | |
public void setCoffeePrepeared(Boolean coffeePrepeared) { | |
this.coffeePrepeared = coffeePrepeared; | |
} | |
public void getNewsRead() { | |
return newsRead; | |
} | |
public void setNewsRead(Boolean newsRead) { | |
this.newsRead = newsRead; | |
} | |
public Date getCreatedAt() { | |
return this.createdAt; | |
} | |
public void setCreatedAt(createdAt) { | |
this.createdAt = createdAt; | |
} | |
} | |
// 2- Add method to return an ArrayList of class properties. | |
public static ArrayList<String> getFieldNames() { | |
ArrayList<String> fields = new ArrayList<>(); | |
for (Field f: Checklist.class.getDeclaredFields()) { | |
fields.add(f.getName()); | |
} | |
return fields; | |
} | |
// 2- As premisse that our form has many checkbox corresponding each field of the entity. I created the checkboxes with id | |
// equals each name of the Checklist class. In other words, in xml layout I put the property android:id="@+id/coffeePrepeared". | |
// The checkboxes can be created dynamic programmatically too but isn't the point for now. Example: | |
/** | |
<LinearLayout | |
android:id="@+id/checklistForm" | |
android:orientation="vertical" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content"> | |
<CheckBox | |
android:id="@+id/coffeePrepeared" | |
android:text="@string/checklist_coffeePrepeared" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
/> | |
</LinearLayout> | |
**/ | |
// 3- Create a generic method that captilize strings. This will be used in the future. A trick very usefull, you can put | |
// this method in a helper class making possible access from anywhere of your project. | |
private String capitalizeString(String str) { | |
String retStr = str; | |
try { | |
// We can face index out of bound exception if the string is null | |
retStr = str.substring(0, 1).toUpperCase() + str.substring(1); | |
} catch (Exception e){ | |
e.printStackTrace(); | |
} | |
return retStr; | |
} | |
// 4- Saving data in background. | |
private void saveChecklist() { | |
// array of properties names | |
ArrayList<String> fields = Checklist.getFieldNames(); | |
Checklist checklist = new Checklist(); | |
// foreach of child elements of the linearlayout | |
for (int i = 0; i < linearLayout.getChildCount(); i++) { | |
final View mChild = linearLayout.getChildAt(i); | |
if (mChild instanceOf CheckBox) { | |
// get the ID name in xml android:id="@+id/" | |
String viewId = ""; | |
try { | |
viewId = getContext().getResources().getResourceEntryName(mChild.getId()); | |
} catch (Resources.NotFoundException e) { | |
e.printStackTrace(); | |
Log.d("DEV", "VIEW NOT FOUND"); | |
continue; | |
} | |
// search de name in arraylist | |
int index = fields.indexOf(viewId); | |
// Call the entity method according to de checkbox id | |
if (index >= 0) { | |
// build the method name | |
String methodName = "set"+ this.capitalizeString(fields.get(index)); | |
Method method = Checklist.class.getMethod(methodName, Boolean.class); | |
boolean mValue = ((CheckBox) mChild).isChecked(); | |
method.invoke(checklist, mValue); | |
} | |
} | |
} | |
// the other fields can be filled normally, for example: | |
checklist.setCreatedAt(new Date()); | |
} | |
// 5- Imagine you need to send the object to a server via API, and in the database of server, this entity has the same field names but in snake case. To solve that, this method may help for convert strings in camel case to snake case: | |
public static String camelToSnake(final String camelStr) { | |
StringBuilder stringBuilder = new StringBuilder(); | |
for (char c : camelStr.toCharArray()) { | |
if (Character.isUpperCase(c)) { | |
stringBuilder.append('_').append(c); | |
} else { | |
stringBuilder.append(c); | |
} | |
} | |
return stringBuilder.toString().toLowerCase(); | |
} | |
// Concluding, imagine that we have a checklist form with 100 fields, java reflection helps us a lot. | |
// Furthermore, my example has checkboxes as main type of element but it can be applied for any type you want. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment