在我的应用中,我通过遵循this answer on SO扩展TextInputLayout进行了自定义视图。在API级别28之前,它运行良好。但是,由于现在对非SDK方法/字段施加了一些限制。由于字段名称已更改,因此抛出NoSuchFieldException。有没有其他方法可以使它在不使用非sdk方法的情况下工作。
在上述链接答案的注释中,一些建议是将字段名称更新为sdk中当前使用的名称。但这将是一个临时性修复,并可能在以后的某些版本中引起问题。有永久解决方案吗?
我的自定义视图的代码:-
public class CustomTextInputLayout extends TextInputLayout {
private Object collapsingTextHelper;
private Rect bounds;
private Method recalculateMethod;
private int hintTextAppearance;
private boolean isRequired;
protected CustomSpinner cSpinner;
public CustomTextInputLayout(Context context) {
this(context, null);
}
public CustomTextInputLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomTextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, true);
}
public CustomTextInputLayout(Context context, AttributeSet attrs, int defStyleAttr, boolean isInitView) {
super(context, attrs, defStyleAttr);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomTextInputLayout);
try {
hintTextAppearance = a.getResourceId(R.styleable.CustomTextInputLayout_hintTextAppearance,
R.style.TextLabelAppearance);
} finally {
a.recycle();
}
if (isInitView) {
cSpinner = new CustomSpinner(context, attrs);
LinearLayout.LayoutParams editTextParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
cSpinner.setHint(null);
addView(cSpinner, 0, editTextParams);
init();
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
adjustBounds();
}
protected void init() {
try {
Field cthField = TextInputLayout.class.getDeclaredField("mCollapsingTextHelper");
cthField.setAccessible(true);
collapsingTextHelper = cthField.get(this);
Field boundsField = collapsingTextHelper.getClass().getDeclaredField("mCollapsedBounds");
boundsField.setAccessible(true);
bounds = (Rect) boundsField.get(collapsingTextHelper);
recalculateMethod = collapsingTextHelper.getClass().getDeclaredMethod("recalculate");
setHintTextAppearance(hintTextAppearance);
} catch (NoSuchFieldException e) {
collapsingTextHelper = null;
bounds = null;
recalculateMethod = null;
e.printStackTrace();
} catch (IllegalAccessException e) {
collapsingTextHelper = null;
bounds = null;
recalculateMethod = null;
e.printStackTrace();
} catch (NoSuchMethodException e) {
collapsingTextHelper = null;
bounds = null;
recalculateMethod = null;
e.printStackTrace();
}
}
private void adjustBounds() {
if (collapsingTextHelper == null) {
return;
}
try {
bounds.set(getEditText().getLeft() + getEditText().getPaddingLeft(), bounds.top, bounds.right,
bounds.bottom);
recalculateMethod.invoke(collapsingTextHelper);
} catch (InvocationTargetException | IllegalAccessException | IllegalArgumentException e) {
e.printStackTrace();
}
}
}