In my register activity there are a few custom EditText views set in a vertical LinearLayout. Top to down.
Because I need some extra functionality for each EditText, I created a custom EditText class that provides that extra functionality. That class relies on some custom attributes that were added in attrs.xml and are retrieved in the class and then set to the inflated EditText.
Everything works fine except for one thing that I can't seem to solve. I can't seem to get NextFocusDown to work on my custom EditText views. When using standard EditText views, it works fine. When I switch to my custom EditText, it ignores it. All other attributes function normally except this one.
What am I missing? Has anyone managed to use that attribute in a custom edit text view ?
Thank you!
EDIT:
This is part of the custom EditText class:
public class CustomEditText extends RelativeLayout {
private LayoutInflater mInflater = null;
private EditText mEditText;
private TextView mHintQuestionMark;
private TextView mHintText;
private Button mButtonClear;
private boolean isExpandView = false;
private boolean clearButtonEnabled = false;
private boolean hintEnabled = false;
public CustomEditText(Context context) {
super(context);
initViews();
}
public CustomEditText(Context context, AttributeSet attrs) {
super(context, attrs);
initViews();
getCustomAttributes(context, attrs);
}
public CustomEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initViews();
getCustomAttributes(context, attrs);
}
private void initViews() {
mInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mInflater.inflate(R.layout.custom_edit_text, this, true);
mHintText = (TextView) findViewById(R.id.theHint);
mEditText = (EditText) findViewById(R.id.theEditText);
mEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
if (clearButtonEnabled){
if (charSequence.length() > 0){
mButtonClear.setVisibility(VISIBLE);
} else {
mButtonClear.setVisibility(INVISIBLE);
}
}
}
@Override
public void afterTextChanged(Editable editable) {
}
});
mHintQuestionMark = (TextView) findViewById(R.id.hintQuestionMark);
mHintQuestionMark.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (isExpandView) {
collapseHeight(mHintText);
} else {
// Expand the HINT view downwards
expandHeight(mHintText);
}
}
});
mButtonClear = (Button) findViewById(R.id.buttonClear);
mButtonClear.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
mEditText.setText("");
}
});
}
private void getCustomAttributes(Context ctx, AttributeSet attrs){
TypedArray typedArray = ctx.getTheme().obtainStyledAttributes(attrs, R.styleable.edittext_attrs, 0, 0);
int firstNameId = 0;
int lastNameId = 0;
try{
mEditText.setInputType(typedArray.getInt(R.styleable.edittext_attrs_android_inputType, EditorInfo.TYPE_TEXT_VARIATION_NORMAL));
mEditText.setHint(typedArray.getString(R.styleable.edittext_attrs_android_hint));
mEditText.setNextFocusDownId(typedArray.getInt(R.styleable.edittext_attrs_android_nextFocusDown, -1));
clearButtonEnabled = typedArray.getBoolean(R.styleable.edittext_attrs_add_clear_button, false);
hintEnabled = typedArray.getBoolean(R.styleable.edittext_attrs_add_hint_icon, false);
} finally {
typedArray.recycle();
}
if (hintEnabled){
mHintQuestionMark.setVisibility(VISIBLE);
} else {
mHintQuestionMark.setVisibility(GONE);
}
}
This is the custom edit text xml I'm inflating in that class:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/editTextGroup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1">
<EditText
android:id="@+id/theEditText"
android:layout_width="match_parent"
android:layout_height="52dp"
android:layout_weight="1"
android:background="@drawable/edit_text_rectangle"
android:maxLength="53"
android:padding="12dp"
android:visibility="visible" />
<Button
android:id="@+id/buttonClear"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="@drawable/remove_text_x"
android:layout_marginLeft="5dp"
android:visibility="gone" />
</RelativeLayout>
<TextView
android:id="@+id/hintQuestionMark"
android:layout_width="36dp"
android:layout_height="52dp"
android:text="\?"
android:textColor="#eeeeee"
android:textSize="30sp"
android:gravity="center"
android:layout_gravity="right"
android:background="#288abf"
android:visibility="gone" />
</LinearLayout>
<TextView
android:id="@+id/theHint"
android:layout_width="match_parent"
android:layout_height="120dp"
android:padding="8dp"
android:text="@string/txtEmailHintText"
android:textColor="#eeeeee"
android:textSize="15sp"
android:gravity="left"
android:background="#288abf"
android:layout_alignLeft="@+id/editTextGroup"
android:layout_below="@+id/editTextGroup"
android:visibility="gone" />
</RelativeLayout>
This is the attrs.xml file I use to get the values in the custom edittext class:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="edittext_attrs">
<attr name="android:inputType" />
<attr name="android:hint" />
<attr name="android:nextFocusDown" />
<attr name="add_clear_button" format="boolean" />
<attr name="add_hint_icon" format="boolean" />
</declare-styleable>
</resources>
And this is a tiny part of the layout xml I use for the register activity with its two views that should use the NextFocusDown:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="16dp">
<com.name.view.customViews.CustomEditText
android:id="@+id/registerTxtFirstName"
android:layout_width="133dp"
android:layout_height="52dp"
android:nextFocusDown="@+id/registerTxtLastName"
android:layout_alignParentLeft="true"
android:inputType="textPersonName"
custom:add_clear_button="true"
android:hint="@string/first"
android:visibility="visible" />
<com.name.view.customViews.CustomEditText
android:id="@+id/registerTxtLastName"
android:layout_width="133dp"
android:layout_height="52dp"
android:layout_alignParentRight="true"
custom:add_clear_button="true"
android:hint="@string/last"
android:inputType="textPersonName"
android:visibility="visible" />
</RelativeLayout>
I hope there's enough information here to see what the problem is.
Thanks!
Old post but I'm submitting this answer in case anyone else runs into the same problem.
In my case, I found using setOnClickListener()
on the CustomEditText in question causes the android:nextFocusDown=""
xml property to not function properly.
For example:
myxml.xml
<com.view.MyCustomEditText
android:id="@+id/username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:hint="@string/email_username"
android:inputType="textEmailAddress"
android:nextFocusDown="@+id/password"/>
<EditText
android:id="@+id/password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="@string/password_hint"
android:inputType="textPassword"
android:imeOptions="actionDone"/>
MainActivity.java:
mUserEditText = (EditText) findViewById(R.id.username);
mPasswordEditText = (EditText) findViewById(R.id.password);
// Instead of using this
mEditText.setOnClickListener(this)
// Use
mEditText.setOnTouchListener(this)
You can copy imeOptions attribute from system attrs.xml file to your custom view attributes
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<declare-styleable name="CustomEditText">
<attr name="imeOptions">
<flag name="normal" value="0x00000000" />
<flag name="actionUnspecified" value="0x00000000" />
<flag name="actionNone" value="0x00000001" />
<flag name="actionGo" value="0x00000002" />
<flag name="actionSearch" value="0x00000003" />
<flag name="actionSend" value="0x00000004" />
<flag name="actionNext" value="0x00000005" />
<flag name="actionDone" value="0x00000006" />
<flag name="actionPrevious" value="0x00000007" />
<flag name="flagNoPersonalizedLearning" value="0x1000000" />
<flag name="flagNoFullscreen" value="0x2000000" />
<flag name="flagNavigatePrevious" value="0x4000000" />
<flag name="flagNavigateNext" value="0x8000000" />
<flag name="flagNoExtractUi" value="0x10000000" />
<flag name="flagNoAccessoryAction" value="0x20000000" />
<flag name="flagNoEnterAction" value="0x40000000" />
<flag name="flagForceAscii" value="0x80000000" />
</attr>
</declare-styleable>
</resources>
Then when you use your custom EditText use imeOptions attribute with your 'custom'(or name it whatever you like) namespace
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="16dp">
<com.name.view.customViews.CustomEditText
android:id="@+id/registerTxtFirstName"
android:layout_width="133dp"
android:layout_height="52dp"
android:nextFocusDown="@+id/registerTxtLastName"
android:layout_alignParentLeft="true"
android:inputType="textPersonName"
custom:add_clear_button="true"
custom:imeOptions="actionNext"
android:hint="@string/first"
android:visibility="visible" />
<com.name.view.customViews.CustomEditText
android:id="@+id/registerTxtLastName"
android:layout_width="133dp"
android:layout_height="52dp"
android:layout_alignParentRight="true"
custom:add_clear_button="true"
custom:imeOptions="actionDone"
android:hint="@string/last"
android:inputType="textPersonName"
android:visibility="visible" />
</RelativeLayout>
And the last step is parse this attribute in your custom EditText and set it to the system one.
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CustomEditText);
int imeOptions = array.getInt(R.styleable.CustomEditText_imeOptions, EditorInfo.IME_NULL);
systemEditText.setImeOptions(imeOptions);
array.recycle();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With