Альтернатива не SDK-методов на уровне API 28 - PullRequest
0 голосов
/ 30 октября 2019

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