В моем приложении я создал собственное представление, расширив TextInputLayout, выполнив этот ответ на SO . Он прекрасно работал до уровня 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();
}
}
}