I have extended EditTextPreference, but the Dialog Message won't display. This happens if I add the dialogMessage programatically or in the the preferences.xml.
Here is my onBindDialogView:
AutoCompleteTextView editText = mEditText;
editText.setText(getText());
ViewParent oldParent = editText.getParent();
if (oldParent != view) {
if (oldParent != null) {
((ViewGroup) oldParent).removeView(editText);
}
onAddEditTextToDialogView(view, editText);
}
Is the dialog message really absent? It's probably there but its text color might make it less (or not) visible. (Or try to dismiss software keyboard). Try experimenting with dialog messages having a number of "\n" characters and see if that affects dialog layout. If so, it means the dialog message is actually there but camouflaged too well.
EditTextPreference brings a text view (in the preference_dialog_edittext.xml) that replaces the existing one (in the alert_dialog.xml) for the dialog message, but unfortunately with different text style, which might cause a visibility problem under certain themes. Even their sizes are different.
One solution might be to obtain the text color and size from the original text view to be replaced and apply them to the new one, but I would suggest retaining the original text view instead, because it's more likely to be visually consistent if there are any future UI changes. Try adding the following overrides
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
super.onPrepareDialogBuilder(builder);
builder.setMessage(getDialogMessage()); // bring back the original text view
}
protected void onAddEditTextToDialogView(View dialogView, EditText editText) {
int id = getContext().getResources().getIdentifier("edittext_container", "id", "android");
ViewGroup container = (ViewGroup) dialogView.findViewById(id);
container.removeAllViews(); // remove the new text view
super.onAddEditTextToDialogView(dialogView, editText);
}
If you think the dialog message and the edittext view is too far apart, they can be brought together a little closer by adding another override:
protected void showDialog(Bundle state) {
super.showDialog(state);
int id = getContext().getResources().getIdentifier("message", "id", "android");
TextView message = (TextView) getDialog().findViewById(id);
message.setPadding(message.getPaddingLeft(), message.getPaddingTop(), message.getPaddingRight(), 0);
}
and add the following line in the onAddEditTextToDialogView method after calling removeAllViews:
container.setPadding(container.getPaddingLeft(), 0, container.getPaddingRight(), container.getPaddingBottom());
Related
I have a custom android widget that abstracts a forum field, RecordDataField, that is based on a RelativeLayout (basically groups a field and it's label together, and takes custom attributes to determine where the label is relative to the field, to show a drop down button for dropdown list's, ...)
public abstract class RecordDataField : RelativeLayout
{
protected TextView _tvLabel;
protected FieldLayout _rlInput;
//protected EditText _etInput;
protected FieldInput _etInput;
protected Button _btnDrop;
protected abstract FieldInput InstantiateInput();
}
FieldInput is a subclassed EditText, nothing really special.
Any child of RecordDataField implements InstantiateInput similar to as follows (_etInput ultimately ends up with the value returned by InstantiateInput)
protected override FieldInput InstantiateInput()
{
View v = _inflater.Inflate(Resource.Layout.RecordDataFields, null);
_fieldInput = ((ViewGroup)v).FindViewById<FieldInput> Resource.Id.RecordDataFieldInput);
return (FieldInput)_fieldInput;
}
This works great for all my RecordDataField variants, but they are all FieldInput (EditText) based. I now need to go even more general, and when I try changing the abstract method InstantiateInput's return type to View, I run into problems in the base class, b/c it set's gravity and other attributes on _etInput, and apparently View doesn't support gravity
public virtual void InitView()
{
_tvLabel = (TextView)_inflater.Inflate(Resource.Layout.RecordDataFieldLabel, this, false);
_tvLabel.Text = _label;
_tvLabel.Gravity = _labelGravity;
ViewGroup.LayoutParams tvLabelLayout = (ViewGroup.LayoutParams)_tvLabel.LayoutParameters;
tvLabelLayout.Width = _labelWidth;
RelativeLayout.LayoutParams lpLabel = new RelativeLayout.LayoutParams(tvLabelLayout);
lpLabel.AddRule(LayoutRules.AlignParentTop);
lpLabel.AddRule(LayoutRules.AlignParentLeft);
AddView(_tvLabel, lpLabel);
...
}
Any suggestions as to which view type I can return from InstantiateInput so this widget can support the greatest amount of view types (the motivation here is that I want to use a CheckBox in place of the EditText (FieldInput)?
Try TextView (android.widget.TextView) . Both Checkbox and EditText extends TextView which supports the gravity param to support aligning it's content
protected void texto() {
activity.runOnUiThread(new Runnable() {
public void run() {
final EditText input = new EditText(activity);
String value = input.getText().toString().trim();
input.setInputType(InputType.TYPE_CLASS_TEXT);
}
});
}
Doesn´t show me the text box on the scene maybe someone knows I'm doing wrong.
You need to at it to your View. Right now you are instantiating an EditText view but is not added to the layout View (LinearLayout, RelativeLayout, etc.) that your screen is rendering, thus making it not appearing.
To solve it, first you need to get your View using activity.findViewById, then you add the EditText view as a subview to it.
Adjust the position if needed.
I have an activity that is basically a long form of entry fields.
On each row, I want to show a TextView to serve as hint text just below each EditText and I want the TextView to remain visible at all times when the user is entering data. Unfortunately, the soft keyboard obscures the hint text and always positions itself immediately below the EditText. Is there any technique that will allow the TextView below the EditText to also be visible when the soft keyboard appears and the contents are adjusted (via windowSoftInputMode=adjustResize|adjustPan), without having the user scroll ?
Vishavjeet got me on the right track in suggesting I scrolldown to reveal the view that may be overlapped by the keyboard. Below is a function similar to what I used to solve the problem. It can be called when the EditText above the TextView receives focus:
// View targetView; // View that may be hidden by keyboard
// ScrollView scrollContainerView; // Scrollview containing hiddenView
//
void assureViewVisible (View targetView, ScrollView, scrollContainerView) {
Window rootWindow = activity.getWindow();
Rect rMyView = new Rect();
View rootview = rootWindow.getDecorView();
rootview.getWindowVisibleDisplayFrame(rMyView); // Area not taken up by keyboard
int subTextPos[] = new int[2];
targetView.getLocationInWindow(subTextPos); // Get position of targetView
int subTextHt = targetView.getHeight(); // Get bottom of target view
if ((subTextPos[1]+subTextHt) > rMyView.bottom) { // Is targetView at all obscured?
int scrollBy = (subTextPos[1]+subTextHt) - rMyView.bottom + 10; // add a small bottom margin
mMeasurementViewScrollView.smoothScrollBy(0, scrollBy); // Scroll to subtext
}
}
EDIT:
By understanding the problem more deeply, I think that you should add scroll programatically when user clicks on the Edittext. Here is the code to do that:
private final void focusOnView()
{
new Handler().post(new Runnable()
{
#Override
public void run()
{
your_scrollview.scrollTo(0, your_EditBox.getBottom());
}});
}
From my personal experience I think there is not such way to do that. The thing you can do is place the hint textview toRightOf the editext. Or Use modern Approach by using a Hint Placeholder on Edittext:
In XML, it's simply android:hint="someText"
Programatically you can use edittext.setHint(int);
pass R.string.somestring in above method.
In my activity I have the following views
TextView player1;
TextView player2;
TextView player3;
TextView player4;
EditText player1name;
EditText player2name;
EditText player3name;
EditText player4name;
Each of the TextView's has the onclick listener applied to it. and so fires the OnClick function.
When we get to the onClick this is what i am currently doing:
#Override
public void onClick(View v) {
//the v variable is the clicked textview, in this case "player1"
//hide the textview and show the resultant edittext
v.setVisibility(View.GONE);
player1name.setVisibility(View.VISIBLE);
//set focus on edit text and when focus is lost hide it and set the textview text
player1name.requestFocus();
imm.showSoftInput(player1name, InputMethodManager.SHOW_FORCED);
player1name.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View y, boolean x) {
v.setVisibility(View.VISIBLE);
player1name.setVisibility(View.GONE);
imm.hideSoftInputFromWindow(player1name.getWindowToken(), 0);
String name = player1name.getText().toString();
if (name.equals("")) {
v.setText("Player Name1");
} else {
v.setText(name);
}
}
});
}
However with this solution I will need to duplicate this code and change the view names for player2 - player2name, player3 - player3name etc
i can obviously grab the clicked TextView via v, however what i cant seem to do is grab its corresponding EditText.
i had thought of doing this:
View test = v + "name";
//then i replace all references to player1name with the test variable
but it doesnt work it wants me to convert View test; into a string
any suggestions?
EDIT: made it easier to understand my question
View test = v + "name";
will give a compile error. Because "v" is not a string type. and also even if it was String, test is not. This line is pretty wrong.
There a few options to achieve what you want,
You can use hashmap
Declare a global field for hashmap
private final HashMap<Integer,EditText> map = new HashMap<Integer,EditText>();
and in onCreate method put your textview id as key, and put your edittext variables in value.
player1name = (EditText) findViewById(R.id.player1name);
map.put(R.id.textView1, player1name);
// for the rest
in onClick method
EditText e = map.get(v.getId());
Then replace them with "e"
e.requestFocus(); //example
Will you please state your problem clearly? Currently, your language is very ambiguous and I can not figure out, exactly what are you looking for. It will help us to know your problem and in turn solve it.
In my application I have a custom view which requires some text input. As the view in itself doesn't contain any actual views (it's a Surface with custom drawing being done), I have a FrameLayout which contains the custom view and underneath it an EditText -view. When the user does a specific action, the custom view is hidden and the EditText takes over for user input. This works fine, but android:imeOptions seem to be ignored for this view. I'm currently doing this:
InputMethodManager inputMethodManager = (InputMethodManager)parent.getSystemService(Context.INPUT_METHOD_SERVICE);
EditText t = (EditText)parent.findViewById(R.id.DummyEditor);
t.setImeOptions(EditorInfo.IME_ACTION_DONE);
inputMethodManager.showSoftInput(t, 0, new ResultReceiver(mHandler) {
#Override
protected void onReceiveResult(
int resultCode, Bundle resultData) {
// We're done
System.out.println("Editing done : " +
((EditText)parent.findViewById(R.id.DummyEditor)).getText());
}
}
);
It seems that the setImeOptions(EditorInfo.IME_ACTION_DONE) has no effect. I've also tried adding the option to the layout XML with android:imeOptions="actionDone". No help.
Any ideas?
this post looks like will answer your question:
How do I handle ImeOptions' done button click?