Error : the specified child already has a parent - android

I'm trying to keep on creating my application, (to create a list of name when you click on the add button). But I have this exception and i don't succeed in removing it;
That's my code :
mageButton addButton = null;
RelativeLayout menuactivitylayout=null;
int j=0;
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu);
final LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
menuactivitylayout=(RelativeLayout)findViewById(R.id.Relativelayoutacitivtymenu);
addButton = (ImageButton) findViewById(R.id.buttonaddplayer);
addButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Create custom dialog object
final Dialog dialog = new Dialog(MenuActivity.this);
dialog.setTitle(getResources().getString(R.string.addperson));
// Include dialog.xml file
dialog.setContentView(R.layout.dialoglayout);
// Set dialog title
// dialog.setTitle("Custom Dialog");
// set values for custom dialog components - text, image and button
final EditText text = (EditText) dialog.findViewById(R.id.editTextdialog);
dialog.show();
final ImageButton validButton = (ImageButton) dialog.findViewById(R.id.imageButtonvalid);
// if decline button is clicked, close the custom dialog
validButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final LinearLayout ll = new LinearLayout(MenuActivity.this);
ll.setOrientation(LinearLayout.HORIZONTAL);
ImageView person = new ImageView(MenuActivity.this);
person.setImageDrawable(getResources().getDrawable(R.drawable.person));
person.setMaxHeight(50);
person.setMaxWidth(50);
ll.addView(person);
final TextView name = new TextView(MenuActivity.this);
name.setText(text.getText().toString());
ll.addView(name);
final ImageButton edit = new ImageButton(MenuActivity.this);
edit.setId(j+1);
edit.setImageDrawable(getResources().getDrawable(R.drawable.edit));
edit.setLayoutParams(params);
j++;
edit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final Dialog editDialog = new Dialog(MenuActivity.this);
editDialog.setTitle("Editer");
dialog.setContentView(R.layout.edtidialoglayout);
final EditText edititextdialog = (EditText) dialog.findViewById(R.id.editTexteditDialog);
dialog.show();
ImageButton validButton = (ImageButton) dialog.findViewById(R.id.imageButtonvalideditdialog);
validButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
name.setText(edititextdialog.getText().toString());
dialog.dismiss();
}
});
}
});
ll.addView(validButton);
menuactivitylayout.addView(ll);
dialog.dismiss();
}
});
This is the logcat
01-31 22:33:49.587 20692-20692/com.example.guillaume.drinkwithfriends E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
at android.view.ViewGroup.addViewInner(ViewGroup.java:3439)
at android.view.ViewGroup.addView(ViewGroup.java:3310)
at android.view.ViewGroup.addView(ViewGroup.java:3255)
at android.view.ViewGroup.addView(ViewGroup.java:3231)
at com.example.guillaume.drinkwithfriends.MenuActivity$1$1.onClick(MenuActivity.java:107)
at android.view.View.performClick(View.java:4162)
at android.view.View$PerformClick.run(View.java:17082)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4867)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
at dalvik.system.NativeStart.main(Native Method)
I have understood that ll has dialog for parents, but i don't succed in removing it !
I know that using a Listview with an inflater and an adapter would be better, but i'm a beginner and i don't really understand what is "Inflater" and "Adapter" ..
Thank you very much

This is line that must be causing the problem.
ll.addView(validButton);
you can't add validButton to the layout because it is already in the dialog box which means it has a parent.
Remove this line and see if it works.

Related

Progress Bar not showing in screen but showing in debugger

I am adding a Progress Bar when the user does a search query, and it will not show up in the screen. Here are the snippets:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button searchButton = (Button) findViewById(R.id.searchButton);
setContentView(R.layout.activity_main); //main layout, which has a child layout called resultsLayout
searchButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
EditText searchString = (EditText) findViewById(R.id.searchString);
search(searchString.getText().toString());
}
});
protected void search(String searchString){
LinearLayout resultLayout = ((LinearLayout) findViewById(R.id.resultsLayout));
resultLayout.addView(DisplayResults.getLoadBar(getApplicationContext()));
//do search
resultLayout.removeAllViews();
}
public static ProgressBar getLoadBar(Context context){
ProgressBar loadBar = new ProgressBar(context);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
loadBar.setLayoutParams(params);
loadBar.setVisibility(View.VISIBLE);
return loadBar;
}
I know some of it might not be needed, like the setVisibility right when creating, but I have tried several things and it not works. Perhaps there wasn't enough time to show up the bar?(It takes about 1.5sec for the search)
I have also debugged the application, and it shows the ProgressBar as a child of the layout, but I still cannot see it in the screen.
ProgressDialog progressDialog; //Create a prog dialog object
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button searchButton = (Button) findViewById(R.id.searchButton);
progressDialog=new ProgressDialog(this); //init it
searchButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
progressDialog.show(); //show it when needed
EditText searchString = (EditText) findViewById(R.id.searchString);
search(searchString.getText().toString());
}
});
protected void search(String searchString){
progressDialog.dismiss();//dismiss it when the search is complete
LinearLayout resultLayout = ((LinearLayout) findViewById(R.id.resultsLayout));
resultLayout.addView(DisplayResults.getLoadBar(getApplicationContext()));
//do search
resultLayout.removeAllViews();
}
You could try this ProgressDialog object implementation.
https://developer.android.com/reference/android/app/ProgressDialog.html
add setContentView(resultLayout); at the end of search() method
I realized that android does not update the screen for every instruction in the code, apparently it does so only when a function ends. That being said, I had to do my search in a separate thread in order for the loading to appear between the time the searched started and before it ended.

android.view.WindowManager$BadTokenException: Unable to add window

I'm adding popup window in fragment when a user clicks on floating action button, in popup window I have added AutoComplete Edit field when I clicked the floating action button, the popup window shows successfully but when I click the edit field it gave an error.
The error is
Here is complete error.
Process: com.example.mubtadanaqvi.stunexus, PID: 7252
android.view.WindowManager$BadTokenException: Unable to add window -- token android.view.ViewRootImpl$W#4234e238 is not valid; is your activity running?
at android.view.ViewRootImpl.setView(ViewRootImpl.java:769)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:278)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
at android.widget.PopupWindow.invokePopup(PopupWindow.java:1067)
at android.widget.PopupWindow.showAsDropDown(PopupWindow.java:966)
at android.widget.ListPopupWindow.show(ListPopupWindow.java:635)
at android.widget.AutoCompleteTextView.showDropDown(AutoCompleteTextView.java:1119)
at android.widget.AutoCompleteTextView.updateDropDownForFilter(AutoCompleteTextView.java:973) at android.widget.AutoCompleteTextView.onFilterComplete(AutoCompleteTextView.java:955)
at android.widget.Filter$ResultsHandler.handleMessage(Filter.java:285)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:548)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(Native Method)
Here is my code
floatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(LAYOUT_INFLATER_SERVICE);
final View customView = inflater.inflate(R.layout.add_new_skill, null);
mPopupWindow = new PopupWindow(
customView,
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
true
);
ImageButton cancel = (ImageButton) customView.findViewById(R.id.close_button);
cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mPopupWindow.dismiss();
}
});
skillListAdapter = new ArrayAdapter<>(getContext(),android.R.layout.simple_dropdown_item_1line, skillsList);
skillInputField = (AutoCompleteTextView) customView.findViewById(R.id.skill_input);
skillInputField.setThreshold(1);
skillInputField.setAdapter(skillListAdapter);
skillListAdapter.addAll(skillsList);
skillListAdapter.notifyDataSetChanged();
Button saveButton = (Button) customView.findViewById(R.id.save_skill);
saveButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String skillText = skillInputField.getText().toString();
if (skillText.isEmpty())
makeToast("EMPTY");
else {
if (ConnectivityListener.isNetwork(getContext())) {
// progressDialog.show();
mPopupWindow.dismiss();
makeToast(skillText);
list.add(new Skill_Item(skillText, 0));
adapter.notifyDataSetChanged();
} else
makeToast("connection error!");
}
}
});
mPopupWindow.showAtLocation(rootLayout, Gravity.CENTER, 0, 0);
}
});
Reason of Exception:
Activity has finished but you are trying to display a dialog with a context of the finished activity. Since there is no window for the dialog to display the android runtime throws this exception.
Solution of Exception:
Please use isFinishing() method which is called by Android to check whether this activity is in the process of finishing:
private final WeakReference<MainActivity> mainActivityWeakRef;
mainActivityWeakRef =new WeakReference<MainActivity>(this);
if (mainActivityWeakRef.get() != null && !mainActivityWeakRef.get().isFinishing()) {
// Your Code
}

PopupWindow not triggering sytem context dialog on EditText long-press

Sorry if the title was a bit vague.
I'm developing an app on Freelancer and I almost have it finished except for a complaint from the customer after some testing.
I use a PopupWindow in place of a dialog to edit contextual settings, if that makes any sense. I don't want to be too specific and risk giving the app concept away, which I'm sure the customer wouldn't be too pleased about.
The PopupWindow is given a Content View of a layout inflated from XML. In that layout are several EditText widgets. The issue is that those EditTexts will not trigger the default contextual dialog on long press that presents options for text/IME selection, and cut/copy/paste.
I saw a similar question trying to get the TouchTrigger or something and it not working without setBackgroundDrawable(), which I've tried with a simple new ColorDrawable(). It still doesn't work.
Is there any easy way to trigger the system-default long-press dialog in an OnLongPressListener, or will I have to move Heaven and Earth to implement it myself? Because if that's the case, I'll just write a Fragment for it and swap it out in a transaction. I know that'll work.
The relevant code:
Inside the initiating fragment:
RulesDialog dialog;
PopupWindow window;
public void showAddRuleDialog(){
dialog = new RulesDialog();
View view = getView();
window = new PopupWindow(dialog.initViews(this, null), view.getWidth(), view.getHeight(), true);
window.setBackgroundDrawable(new ColorDrawable());
dialog.setRulesDialogListener(new rulesDialogListener(){
#Override
public void onSave(ViewHolder holder) {
addRule(holder);
window.dismiss();
}
#Override
public void onCancel() {
window.dismiss();
}});
int[] location = {0,0};
view.getLocationOnScreen(location);
window.showAtLocation(view, 0, location[0], location[1]);
In RulesDialog:
public class ViewHolder{
public ViewHolder(View dialogView){
name = (TextView) dialogView.findViewById(R.id.name);
response = (TextView) dialogView.findViewById(R.id.response);
senders = (TextView) dialogView.findViewById(R.id.senders);
sendersAdd = (Button) dialogView.findViewById(R.id.sendersAdd);
sendersEdit = (Button) dialogView.findViewById(R.id.sendersEdit);
timeFrom = (TextView) dialogView.findViewById(R.id.from);
timeFromEdit = (Button) dialogView.findViewById(R.id.timeBeforeEdit);
timeTo = (TextView) dialogView.findViewById(R.id.to);
timeToEdit = (Button) dialogView.findViewById(R.id.timeAfterEdit);
keywords = (TextView) dialogView.findViewById(R.id.keywords);
matchCase = (CheckBox) dialogView.findViewById(R.id.matchCase);
matchAlone = (CheckBox) dialogView.findViewById(R.id.matchAlone);
matchPlural = (CheckBox) dialogView.findViewById(R.id.matchPlural);
cancel = (Button) dialogView.findViewById(R.id.cancel);
save = (Button) dialogView.findViewById(R.id.save);
}
TextView name;
TextView response;
TextView senders;
Button sendersAdd;
Button sendersEdit;
TextView timeFrom;
Button timeFromEdit;
TextView timeTo;
Button timeToEdit;
TextView keywords;
CheckBox matchCase;
CheckBox matchAlone;
CheckBox matchPlural;
Button cancel;
Button save;
}
Activity activity;
ViewHolder holder;
Fragment fragment;
public View initViews(Fragment mFragment, Rule rule){
fragment = mFragment;
activity = fragment.getActivity();
View dialogView = LayoutInflater.from(activity).inflate(R.layout.rules_dialog, null);
holder = new ViewHolder(dialogView);
final TextView senders = holder.senders;
holder.sendersAdd.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
showContacts();
}});
holder.sendersEdit.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
editSenders(senders);
}
});
final TextView timeFrom = holder.timeFrom;
holder.timeFromEdit.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
showTimePickerDialog(timeFrom);
}
});
final TextView timeTo = holder.timeTo;
holder.timeToEdit.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
showTimePickerDialog(timeTo);
}
});
holder.cancel.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
mListener.onCancel();
}});
holder.save.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
mListener.onSave(holder);
}});
if(rule == null)
rule = new Rule();
holder.name.setText(rule.name);
holder.response.setText(rule.response);
holder.senders.setText(rule.senders.toString());
holder.senders.setTag(rule.senders);
holder.keywords.setText(rule.keywords);
holder.matchCase.setChecked(rule.matchCase);
holder.matchAlone.setChecked(rule.matchAlone);
holder.matchPlural.setChecked(rule.matchPlural);
holder.timeFrom.setTag(rule.timeFrom);
holder.timeFrom.setText(Rules.formatTime(rule.timeFrom));
holder.timeTo.setTag(rule.timeTo);
holder.timeTo.setText(Rules.formatTime(rule.timeTo));
return dialogView;
}
So I tried rewriting RulesDialog as a fragment, and it didn't work out too well. Had issues with making Fragment Transactions work right when called from the Fragments they're operating on.
(I know this isn't the point to fragments. I'm not really aiming to write a completely modular app right now. I just want to come out with a product the customer will be happy with.)
I ended up rewriting RulesDialog as an Activity instead, and using startActivityForResult() from the calling fragment. Then passing the edited data back with setResult(). It all works nicely in concert.

Add delete option with dynamically generated editText

I'm new in android and i have created editText dynamically with the following code while clicking add new button.Is it possible to add a delete button near editText so that each while clicking the delete respective editText will be removed?
btnAddNew.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
LinearLayout rAlign = (LinearLayout)findViewById(R.id.lId);
EditText newPass = new EditText(getApplicationContext());
allEds.add(newPass);
newPass.setHint("Name of Label");
newPass.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
newPass.setWidth(318);
newPass.setTextColor(Color.parseColor("#333333"));
newPass.setId(textb);
rAlign.addView(newPass);
MY_BUTTON ++;
addSpinner();
}
});
Yes, create your remove button at the same time as your EditText and use the removeView() method just like the addView() method, maybe like this:
btnAddNew.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
...
rAlign.addView(newPass);
MY_BUTTON ++;
addSpinner();
Button btnRemoveOld = new Button(this);
btnRemoveOld.setId(32); // arbitrary number
btnRemoveOld.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
LinearLayout rAlign = (LinearLayout)findViewById(R.id.lId);
rAlign.removeView(findViewById(textb));
}
});
// You will need to set parameters to define how the button looks
// and where it is in relation to the EditText here
rAlign.addView(btnRemoveOld);
}
});

Displaying custom dialog

Alright, so I would like to have a custom dialog, but I cannot figure out for the life of me how to make it appear when the function is called.
public void addHomework() {
final Dialog alert = new Dialog(this);
alert.setTitle("Add Homework");
alert.setContentView(R.layout.homework_item_entry);
Button add_button = (Button) findViewById(R.id.add_homework_button);
Button cancel_button = (Button) findViewById(R.id.cancel_homework_button);
add_button.setOnClickListener( new OnClickListener() {
public void onClick(View v) {
Toast.makeText(ClassHomeworkList.this, "Adding homework", Toast.LENGTH_SHORT).show();
}
});
cancel_button.setOnClickListener( new OnClickListener() {
public void onClick(View v) {
alert.dismiss();
}
});
alert.show();
}
What could I do?
I know this is an old thread, but even after reading the Android docs it also was not obvious to me how to display a custom dialog using the standard Dialog class. Basically you can call:
this.showDialog(MANAGE_PASSWORD); // MANAGE_PASSWORD static final int
from your activity. Then instantiate the custom dialog in the onCreateDialog method:
protected Dialog onCreateDialog(int id) {
Dialog dialog;
switch(id) {
case MANAGE_PASSWORD:
dialog= getInstancePasswordDialog();
break;
case DIALOG_ABOUT:
// do the work to define the About Dialog
dialog= getInstanceAlertDialog(); // called "the first time"
break;
default:
dialog = null;
}
return dialog;
}
The code to instantiate the dialog is in getInstancePasswordDialog(). Here is the code sample.
I think you have the problem that your two buttons cannot be found by their ID's like this (as you are trying to find them in your main activity, but they are in the layout for the dialog)
Button add_button = (Button) findViewById(R.id.add_homework_button);
Button cancel_button = (Button) findViewById(R.id.cancel_homework_button);
But instead need to do:
Button add_button = (Button) alert.findViewById(R.id.add_homework_button);
Button cancel_button = (Button) alert.findViewById(R.id.cancel_homework_button);
Have you read the following document: http://developer.android.com/guide/topics/ui/dialogs.html#ShowingADialog ?
You should override your Activity's onCreateDialog(int) method as described there and then use showDialog(int)
LayoutInflater factory = LayoutInflater.from(this);
View view = factory.inflate(R.layout.dialog, null);
//the id is your root layout
LinearLayout layout = (LinearLayout) view.findViewById(R.id.layout);
alert.setContentView(layout);

Categories

Resources