removeView() on the child's parent - android

I'm getting
E/AndroidRuntime(855): Caused by: java.lang.IllegalStateException:
The specified child already has a parent. You must call removeView()
on the child's parent first.
The code I'm running, the error happens on linearLayout.addView(view);
view = getFieldControl(field);
linearLayout.addView(view);
Where getFieldControl looks like this(simplified):
private android.view.View getFieldControl(ControlTemplate control)
{
View view =null;
view = (EditText)findViewById(R.id.edit_message);
((EditText) view).setHint(control.getName());
((EditText) view).setText(control.getValue());
return view;
}
I don't understand what the views parent could be, where should I remove it from?

Create your EditText programmatically as below
private android.widget.EditText getFieldControl(ControlTemplate control)
{
EditText edittext = new EditText(this);
edittext.setHint(control.getName());
edittext.setText(control.getValue());
return edittext;
}
Note : If the EditText is in XML which is set as Content View modify the code as below by removing the line linearLayout.addView(view); because already the EditText is added in the layout through XML.
EditText edittext = (EditText) findViewById(R.id.edit_message);;
getFieldControl(edittext, field);
private void getFieldControl(EditText edittext, ControlTemplate control)
{
edittext.setHint(control.getName());
edittext.setText(control.getValue());
}

If you call the getFieldControl(field) method more than once, you are trying to get the EditText of R.id.edit_message from XML and adding that more than once to the layout. Hence it's giving this error. Make sure that you add this EditText only once to any of the layouts.

Your EditText R.id.edit_message must be in an .xml file or say layout, that layout is the parent of the EditText.
Create a dynamic EditText instead.

Related

Emoji keyboard crashing

I'm a fairly new developer, so please go easy on me.
I'm making a chat app, and I'm planning on adding support for custom emojis, similar to how Discord manages custom emojis. However, my app is crashing once I tap on the emoji button. I want it to inflate my layout (emoji_keyboard_layout.xml) and view that in a LinearLayout in ChatActivity.
I've tried adding the view itself to the layout (yeah that didn't work in my case, but if that is the only solution possible, then I will try it again) and I've also tried modifying my onClick, modifying the actual method, but whatever I did, nothing would fix it.
My openEmojiKeyboard method:
private void openEmojiKeyboard(Boolean EMOJI_STATE, Boolean GIF_STATE)
{
View emojiKey = getLayoutInflater().inflate(R.layout.emoji_keyboard_layout, llEmojiKeyboard);
llEmojiKeyboard.addView(emojiKey);
llEmojiKeyboard.setVisibility(View.VISIBLE);
hideKeyboard(etMessage);
final LinearLayout llSelectContent = emojiKey.findViewById(R.id.llSelectContent);
final LinearLayout llSelectToolbar = emojiKey.findViewById(R.id.llSelectToolbar);
final LinearLayout llEmoji = emojiKey.findViewById(R.id.llEmoji);
final LinearLayout llGif = emojiKey.findViewById(R.id.llGif);
final LinearLayout llEmojiSelected = emojiKey.findViewById(R.id.llEmojiSelected);
final LinearLayout llGifSelected = emojiKey.findViewById(R.id.llGifSelected);
final TextView tvEmptyContent = emojiKey.findViewById(R.id.tvEmptyContent);
final TextView tvEmptyContent1 = emojiKey.findViewById(R.id.tvEmptyContent1);
if (EMOJI_STATE && !GIF_STATE) // The emoji keyboard is open, gif keyboard is closed
{
llEmojiSelected.setVisibility(View.VISIBLE);
llGifSelected.setVisibility(View.GONE);
tvEmptyContent1.setText(R.string.add_emoji);
tvEmptyContent.setText(R.string.empty_emoji_content);
}
else if (GIF_STATE && !EMOJI_STATE) // The gif keyboard is open, emoji keyboard is closed
{
llGifSelected.setVisibility(View.VISIBLE);
llEmojiSelected.setVisibility(View.GONE);
tvEmptyContent1.setText(R.string.retry);
tvEmptyContent.setText(R.string.empty_gif_content);
}
}
My activity's onClick event:
case R.id.ivEmoji:
openEmojiKeyboard(EMOJI_STATE, GIF_STATE);
break;
The emoji keyboard functionality is not ready yet, just preparing the layout
Stack Trace
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
Crashing on lines llEmojiKeyboard.addView(emojiKey); and openEmojiKeyboard(EMOJI_STATE, GIF_STATE);
The error you have indicated in the logs is telling you that the view (emojiKey) already has a parent (root) view. This is because you passed llEmojiKeyboard as a root view via the second argument in LayoutInflater.inflate(). Since this is already the root view, you don't need to call .addView() after inflating, or if the .addView() call is necessary, you can pass a boolean as a third argument to .inflate() to control whether the newly inflated view gets attached to the root ViewGroup (here is the documentation for that version of the .inflate() method):
View emojiKey = getLayoutInflater().inflate(R.layout.emoji_keyboard_layout, llEmojiKeyboard, false);

AppCompatEditText.getpParent() inside TextInputLayout returns FrameLayout

I am creating simple AppCompatEditText adding OnFocusChangeListener and putting it in the simple TextInputLayout.
When AppCompatEditText loosing focus it's content should be validate by isValidParam method.
It worked till yesterday, when I used rev.23.0.3
But now, when I used rev.24.0.2, it gives error as below on the 1st row of isValidParam method.
java.lang.ClassCastException: android.widget.FrameLayout cannot be
cast to android.support.design.widget.TextInputLayout
I checked in debugging mode. AppCompatEditText.getpParent() really returns Framelayout instead TextInputLayout.
LinearLayout llParams = new LinearLayout(context);
llParams.setOrientation(LinearLayout.VERTICAL);
// Create label for param
final TextInputLayout tilParam = new TextInputLayout(context);
// Add label into layout
llParams.addView(tilParam);
// Create Editor for param
final AppCompatEditText etParam = new AppCompatEditText(context);
edParam.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus)
if (isValidParam(etParam)) {
do some thing;
} else {
do other thing;
}
}
});
tilParam.addView(etParam);
// validation method
boolean isValidParam(AppCompatEditText editText) {
TextInputLayout til = (TextInputLayout) editText.getParent();
String text = editText.getText().toString().trim();
if (!text.equls("some criteria") {
till.setError("Error text")
return false;
}
return true;
}
Update:
Use the widget TextInputEditText instead of EditText inside a TextInputLayout.
old answer
TextInputLayout textInputLayout = (TextInputLayout) editText.getParent().getParent();
That seems to work as a quick fix. Far from ideal.
getParentForAccessibility() worked for me
You can check if EditText is inside TextInputLayout using following method:
public static <ParentClass> ParentClass getFirstParent(View view, Class<ParentClass> parentClass) {
if (view.getParent() instanceof View) {
if (parentClass.isInstance(view.getParent())) {
return (ParentClass) view.getParent();
} else {
return getFirstParent((View) view.getParent(), parentClass);
}
} else {
return null;
}
}
Example of use:
TextInputLayout textInputLayout = getFirstParent(editText, TextInputLayout.class)
Just extracts from Android official documents:
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/form_username"/>
</android.support.design.widget.TextInputLayout>
Note: The actual view hierarchy present under TextInputLayout is NOT
guaranteed to match the view hierarchy as written in XML. As a result,
calls to getParent() on children of the TextInputLayout -- such as an
TextInputEditText -- may not return the TextInputLayout itself, but
rather an intermediate View. If you need to access a View directly,
set an android:id and use findViewById(int).
Therefore, to resolve the issue you have to turn to findViewById instead of getParent due to an extra layout in between introduced in version 24.
You can check the code of the TextInputLayout v24.x.x.
Now it works with a FrameLayout.
#Override
public void addView(View child, int index, final ViewGroup.LayoutParams params) {
if (child instanceof EditText) {
mInputFrame.addView(child, new FrameLayout.LayoutParams(params));
//...
} else {
// Carry on adding the View...
super.addView(child, index, params);
}
}
where mInputFrame is a FrameLayout.
It is the reason of your issue (the parent is a FrameLayout).
Just pass the tilParam as parameter , instead of using getParent() if you need to use it.
TextInputLayout has a method called getEditText(). This may be an alternate way to solve your problem. Instead of starting from the EditText itself and getting the parent TextInputLayout, you can start with the TextInputLayout and simply get the EditText child view. For xml generated views, the following code is an example:
TextInputLayout someInputLayout = findViewById(R.id.some_input_layout);
EditText someEditText = someInputLayout.getEditText();
String text = someEditText.getText().toString();
This could possibly be a more desired solution as it does not require any external methods, though this would not solve your problem if it is required that you start from EditText for some reason. I know this has been answered a long time ago, but I was using #sylwano's solution, until I found for my particular problem it was better to do as above.

Clicking twice on a radiobutton generates illegalstateexception

I am getting an object of RadioButton by using findViewById() and then setting an `onclicklistener' for it.The code goes like :
final EditText editTextView = (EditText)findViewById(2001);
RadioButton rb = (RadioButton) findViewById(R.id.radio3);
rb.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.editTextGroupLayout);
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);
editTextView.setLayoutParams(params);
editTextView.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL| InputType.TYPE_NUMBER_FLAG_SIGNED);
editTextView.setId(2001);
linearLayout.addView(editTextView);
}
});
When i click Once on the radiobutton it works fine.But when i click it twice,it generates
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
By clicking it twice why this exception occurs?
What i tried
I tried to remove the line final EditText editTextView = (EditText)findViewById(2001);
and add this line inside the onClick(),EditText editTextView = (EditText)findViewById(2001);.But by doing this it doesn't get executed even once.It shows exception too.
It is beacouse you got only one instance of edittext which alerady has a parent after first click. Try to remove view from parent and than place it again.
Or maybe try to show/hide it?
You should propably do something like this.
linearLayout.removeAllViews(); or linearLayout.removeView(editTextView);
...
linearLayout.addView(editTextView);

Android : Setvisibility to visible causes nullpointerexception on button

This seems to have been asked in stackoverflow a bit before with no convincing answers for most questions. anyways, i attempt again.
I have an Android App where am displaying a list where each row has an Edittext and Button component as seen below
The Edittext is non-editable when the view appears. I do this with the code below:
private void setNameAsEditable (View rowView, boolean setToEditable) {
EditText textView = (EditText) rowView
.findViewById(R.id.edittext_name);
textView.setFocusableInTouchMode(setToEditable);
textView.setFocusable(setToEditable);
ImageButton button = (ImageButton) rowView
.findViewById(R.id.button_save_name);
if ( setToEditable ) {
button.setVisibility (View.VISIBLE); // nullpointerexception here
} else {
button.setVisibility (View.GONE);
}
When I long-press, and setToEditable is true, it throws nullpointerexception in the line indicated above. it doesn't seem to find the button component. However, 'button.setVisibility (View.GONE);' is executed when setToEditable is false without any issue.
Can someone please help?
rowView appears to be your EditText while you actually want the parent view that has the button inside of it. If you call findViewById and the id doesn't exist inside of that view, it will return null.
I think issue is initialization of view control. You should initialize EditText & ImageButton at the top.
EditText textView;
ImageButton button ;
...
...
...
EditText textView = (EditText) rowView.findViewById(R.id.edittext_name);
ImageButton button = (ImageButton) rowView.findViewById(R.id.button_save_name);
And next thing is try to write your code in try & catch block so you get exact idea what is wrong and where is bug.

Android NULL pointer Exception when trying to add a view

I am 2 days old to Android Programming. I may be comitting a mistake at the core level. If this is the case, pardon.
I am trying to add a text box to a Relative Layout. When a button is clicked.
The method is bound to the button by the attribute android:onClick="method"
By doing the below.
public method (View view){
RelativeLayout vRL = (RelativeLayout)findViewById(R.layout.rLayout);
TextView vET = new TextView(this);
vET.setText("Text added to view.");
vET.setId(1);
vRL.addView(vET);
setContentView(R.layout.rLayout);
}
But I am getting a null pointer exception at vRL.addView(vET);
what is it that I am doing wrong? -OR-
Am I not adding the TextView element properly?
in below line
RelativeLayout vRL = (RelativeLayout)findViewById(R.layout.rLayout);
change the R.layout.rLayout to R.id.rLayout
setContentView(R.layout.rLayout);
put this line in onCreate() of Activity..
and this line from method()
RelativeLayout vRL = (RelativeLayout)findViewById(R.id.rLayout);
Replace below line with
`RelativeLayout vRL = (RelativeLayout)findViewById(R.id."id name of relative layout");`
Change like this:
public method (View view){
RelativeLayout vRL = (RelativeLayout)findViewById(R.id.rLayout);
TextView vET = new TextView(this);
vET.setText("Text added to view.");
vET.setId(1);
vRL.addView(vET);
setContentView(R.layout.rLayout);
}
change the R.layout.rLayout to R.id.rLayoutR.layout.rLayout);

Categories

Resources