我尝试创建自定义密码视图。我编写了代码,并且一切正常,但是在某些设备中我遇到了问题。 Edittext的requestfocus无效,我无法打开键盘。我的Google Pixel 2设备有问题 这是我的资料来源
public class CustomPinEntryView extends LinearLayout {
private int valueInPixels;
private int localTextSize;
public static final int ACCENT_NONE = 0;
public static final int ACCENT_ALL = 1;
public static final int ACCENT_CHARACTER = 2;
private int mDigits;
private int mDigitTextColor;
private int mDigitElevation;
private int textSize;
private int mAccentType;
private String mMask = "*";
CustomPinEntryView customlayout;
private LayoutInflater mInflater;
private Context mContext;
public static EditText inputValue;
private LinearLayout childContainer1;
//private LinearLayout mainContainer,childContainer1;
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public CustomPinEntryView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public CustomPinEntryView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public CustomPinEntryView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
mInflater = LayoutInflater.from(context);
customlayout = this;
mInflater.inflate(R.layout.view_pin_code_custom_container, this, true);
childContainer1 = findViewById(R.id.my_Container_child);
getAttributes(context, attrs);
}
public CustomPinEntryView(Context context) {
super(context);
}
private void getAttributes(Context context, AttributeSet attrs) {
// Get style information
TypedArray array = getContext().obtainStyledAttributes(attrs, R.styleable.PinEntryView);
mDigits = array.getInt(R.styleable.PinEntryView_numDigits, 4);
mAccentType = array.getInt(R.styleable.PinEntryView_accentType, ACCENT_NONE);
valueInPixels = (int) getResources().getDimension(R.dimen.u_widget_height);
localTextSize = (int) getResources().getDimension(R.dimen.u_common_text_size_small);
textSize = (int) getResources().getDimension(R.dimen.u_common_text_size_extra_large);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mDigitElevation = array.getDimensionPixelSize(R.styleable.PinEntryView_digitElevation, 0);
}
Resources.Theme theme = getContext().getTheme();
TypedValue background = new TypedValue();
theme.resolveAttribute(android.R.attr.windowBackground, background, true);
// Text colour, default to android:textColorPrimary from theme
TypedValue textColor = new TypedValue();
theme.resolveAttribute(android.R.attr.textColorPrimary, textColor, true);
mDigitTextColor = array.getColor(R.styleable.PinEntryView_digitTextColor,
textColor.resourceId > 0 ? getResources().getColor(textColor.resourceId) :
textColor.data);
TypedValue accentColor = new TypedValue();
theme.resolveAttribute(R.attr.colorAccent, accentColor, true);
String maskCharacter = array.getString(R.styleable.PinEntryView_mask);
if (maskCharacter != null) {
mMask = maskCharacter;
}
array.recycle();
childContainer1.removeAllViews();
addView(childContainer1);
}
@TargetApi(21)
private void addView(final LinearLayout childView) {
for (int i = 0; i < mDigits; i++) {
DigitView digitView = new DigitView(getContext());
digitView.setWidth(valueInPixels);//48do
digitView.setHeight(valueInPixels);//48do
digitView.setTextColor(Color.WHITE);
// digitView.setTextSize(pxFromDp(14, mContext));
digitView.setGravity(Gravity.CENTER);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
digitView.setElevation(mDigitElevation);
}
LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
if (i > 0) {
int value = (int) pxFromDp(8, mContext);
lp.leftMargin = value;
}
childView.addView(digitView, lp);//childview 216dp
}
inputValue = new EditText(getContext());
inputValue.setWidth(valueInPixels);
inputValue.setHeight(valueInPixels);
inputValue.setGravity(Gravity.CENTER);
inputValue.setBackgroundColor(getResources().getColor(android.R.color.transparent));
inputValue.setTextColor(getResources().getColor(android.R.color.transparent));
inputValue.setCursorVisible(false);
inputValue.setFilters(new InputFilter[]{new InputFilter.LengthFilter(mDigits)});
inputValue.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
inputValue.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI);
inputValue.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
int length = inputValue.getText().length();
for (int i = 0; i < mDigits; i++) {
childView.getChildAt(i).setSelected(hasFocus && (mAccentType == ACCENT_ALL ||
(mAccentType == ACCENT_CHARACTER && (i == length ||
(i == mDigits - 1 && length == mDigits)))));
}
if (mOnFocusChangeListener != null) {
mOnFocusChangeListener.onFocusChange(CustomPinEntryView.this, hasFocus);
}
}
});
inputValue.addTextChangedListener(textWatcher);
inputValue.requestFocus();
childView.addView(inputValue);
}
TextWatcher textWatcher = new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable s) {
int length = s.length();
for (int i = 0; i < mDigits; i++) {
if (s.length() > i) {
String mask = mMask == null || mMask.length() == 0 ?
String.valueOf(s.charAt(i)) : mMask;
((TextView) childContainer1.getChildAt(i)).setText(mask);
} else {
((TextView) childContainer1.getChildAt(i)).setText("");
}
if (inputValue.hasFocus()) {
childContainer1.getChildAt(i).setSelected(mAccentType == ACCENT_ALL ||
(mAccentType == ACCENT_CHARACTER && (i == length ||
(i == mDigits - 1 && length == mDigits))));
}
}
if (length == 0) {
if (CustomPinEntryView.inputValue != null)
CustomPinEntryView.inputValue.requestFocus();
}
if (length == mDigits) {
if (CustomPinConfirmView.mEditText != null)
CustomPinConfirmView.mEditText.requestFocus();
}
}
};
public static float pxFromDp(float dp, Context mContext) {
return dp * mContext.getResources().getDisplayMetrics().density;
}
public Editable getText() {
return inputValue.getText();
}
public String clearText() {
inputValue.setText("");
return "";
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// Make sure this view is focused
if (inputValue != null) {
inputValue.requestFocus();
// Show keyboard
InputMethodManager inputMethodManager = (InputMethodManager) getContext()
.getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.showSoftInput(inputValue, 0);
}
return true;
}
return super.onTouchEvent(event);
}
@Override
protected Parcelable onSaveInstanceState() {
Parcelable parcelable = super.onSaveInstanceState();
SavedState savedState = new SavedState(parcelable);
savedState.editTextValue = inputValue.getText().toString();
Log.e("Password", savedState.editTextValue + "tt");
return savedState;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
SavedState savedState = (SavedState) state;
super.onRestoreInstanceState(savedState.getSuperState());
inputValue.setText(savedState.editTextValue);
inputValue.setSelection(savedState.editTextValue.length());
Log.e("Password", savedState.editTextValue + "tt2");
}
static class SavedState extends BaseSavedState {
public static final Creator<SavedState> CREATOR =
new Creator<SavedState>() {
@Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
@Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
String editTextValue;
public SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel source) {
super(source);
editTextValue = source.readString();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeString(editTextValue);
}
}
@Override
public OnFocusChangeListener getOnFocusChangeListener() {
return mOnFocusChangeListener;
}
private OnFocusChangeListener mOnFocusChangeListener;
private class DigitView extends android.support.v7.widget.AppCompatTextView {
public DigitView(Context context) {
this(context, null);
}
public DigitView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public DigitView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (isSelected()) {
this.setBackgroundResource(R.drawable.pincode_background_border_select);
} else {
this.setBackgroundResource(R.drawable.pincode_background_border_unselect);
}
}
}
}
这是我的xml代码
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:id="@+id/my_Container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center"
android:layout_gravity="center"
>
<LinearLayout
android:id="@+id/my_Container_child"
android:layout_width="@dimen/pincode_skip_button_width"
android:layout_height="@dimen/u_widget_height"
android:orientation="horizontal"
>
</LinearLayout>
</LinearLayout>
正如我所说的,我在某些设备上有问题。无法打开键盘,也无法在自定义视图中输入密码。 谁能告诉我如何解决这个问题? 谢谢