Skip to content

Instantly share code, notes, and snippets.

@hesenger
Last active November 4, 2020 20:42
Show Gist options
  • Save hesenger/f14b112bba1aed08d4db79199cce3a69 to your computer and use it in GitHub Desktop.
Save hesenger/f14b112bba1aed08d4db79199cce3a69 to your computer and use it in GitHub Desktop.
Android base activity with auto bind controls to class fields, button click to method etc...
package br.com.vendas;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class BaseActivity extends AppCompatActivity implements View.OnClickListener {
public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd/MM/yyyy");
public static final DecimalFormat DECIMAL_FORMAT;
static {
DecimalFormatSymbols sym = new DecimalFormatSymbols();
sym.setDecimalSeparator(',');
DECIMAL_FORMAT = new DecimalFormat("0.00", sym);
}
protected final Map<View, String> views = new HashMap<>();
@Override
protected void onStart() {
super.onStart();
bind(findViewById(android.R.id.content));
}
protected void bind(View view) {
if (view instanceof ViewGroup) {
ViewGroup group = (ViewGroup)view;
for (int i = 0; i < group.getChildCount(); i++) {
bind(group.getChildAt(i));
}
}
if (!(view.getTag() instanceof String))
return;
String tag = (String)view.getTag();
views.put(view, tag);
// alimenta variaveis com views
try {
Field field = getClass().getDeclaredField(tag);
field.setAccessible(true);
field.set(this, view);
} catch (Exception e) {
e.printStackTrace();
}
// bind de btns para metodos da activity
if (view instanceof Button) {
Button btn = (Button)view;
btn.setOnClickListener(this);
return;
}
}
@Override
public void onClick(View view) {
try {
Method m = getClass().getDeclaredMethod(views.get(view));
m.setAccessible(true);
m.invoke(this);
} catch (Exception e) {
e.printStackTrace();
}
}
protected void updateModel(Object obj) {
iterateViews(obj, false, true);
}
protected void refreshView(Object obj) {
iterateViews(obj, true, false);
}
protected void iterateViews(Object obj, boolean refreshView, boolean updateModel) {
Field[] fields = obj.getClass().getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Field it = fields[i];
it.setAccessible(true);
String name = it.getName();
View view = null;
for (Map.Entry<View, String> entry: views.entrySet()) {
if (!entry.getValue().equals(name))
continue;
view = entry.getKey();
break;
}
if (view == null)
continue;
try {
if (refreshView)
formatModelValue(name, view, it.get(obj));
if (updateModel)
it.set(obj, parseViewValue(name, it.getType(), view));
} catch (Exception e) {
e.printStackTrace();
}
}
}
protected Object parseViewValue(String name, Class targetType, View view) throws ParseException {
if (view instanceof EditText) {
String str = ((EditText) view).getText() + "";
if (targetType == Date.class)
return DATE_FORMAT.parse(str);
if (targetType == Integer.class)
return Integer.parseInt("0" + str);
if (targetType == Long.class)
return Long.parseLong("0" + str);
if (targetType == BigDecimal.class)
return DATE_FORMAT.parse(str);
return str;
}
return null;
}
protected void formatModelValue(String name, View view, Object value) {
if (view instanceof TextView) {
TextView edit = (TextView) view;
if (value instanceof String || value instanceof Integer || value instanceof Long)
edit.setText(value + "");
if (value instanceof Date)
edit.setText(new SimpleDateFormat("dd/MM/yyyy").format(value));
if (value instanceof BigDecimal)
edit.setText(DECIMAL_FORMAT.format(value));
return;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment