Skip to content

Instantly share code, notes, and snippets.

@EduardoSP6
Last active October 27, 2021 21:09
Show Gist options
  • Save EduardoSP6/dabc1b3b45225ff50b38c842c96e3702 to your computer and use it in GitHub Desktop.
Save EduardoSP6/dabc1b3b45225ff50b38c842c96e3702 to your computer and use it in GitHub Desktop.
Using Java Reflection with Andriod
// 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