Updating a textview inside a custom dialog via a button - android

So, my current issue is that I can't find an elegant way to update a dialog box when a button is pressed. I can achieve functionally the same result by dismiss() and show(), but that is ugly.
Lets say this dialog has 3 buttons, for selling widgets that the player has. Sell All, Sell 10, and Sell X (amount entered with a EditText). I'd like for the dialog to persist if the player pushes Sell 10, but also to update it's textviews with the new count of widgets.
Pertinent part of the XML layout of the custom dialog:
<LinearLayout android:id="#+id/linearLayout3" android:layout_height="wrap_content" android:layout_width="match_parent">
<TextView android:id="#+id/sell10Text" android:layout_width="wrap_content" android:text="TextView" android:layout_height="wrap_content" android:layout_weight="2"></TextView>
<Button android:text="Sell 10" android:enabled="false" android:layout_width="wrap_content" android:id="#+id/sell10Button" android:layout_height="wrap_content" android:layout_weight="1"></Button>
</LinearLayout>
Pertinent part of the dialog creation:
final Dialog alert = new Dialog(this);
alert.setTitle("Sell how many "+(masterRes.get(currentResIndex).getName())+"?");
alert.setContentView(R.layout.selldialog);
TextView tvsellAll = (TextView) alert.findViewById(R.id.sellAllText);
TextView tvsell10 = (TextView) alert.findViewById(R.id.sell10Text);
//etc etc more handles, including buttons
tvsellAll.setText("Sell All ("+String.valueOf(masterRes.get(currentResIndex).getHeld())+") - $"+String.valueOf(calcCost(masterRes.get(currentResIndex).getHeld())));
tvsell10.setText("Sell 10 - $"+String.valueOf(calcCost(10)));
// etc etc more setTexts
btnsell10.setOnClickListener( new OnClickListener() {
public void onClick(View v) {
if (v.isEnabled()) {
int y=masterRes.get(currentResIndex).getHeld();
masterRes.get(currentResIndex).setHeld(y-10);
held -= 10;
money += (calcCost(10));
updateScreen();
alert.tvsellAll.setText("Sell All ("+String.valueOf(masterRes.get(currentResIndex).getHeld())+") - $"+String.valueOf(calcCost(masterRes.get(currentResIndex).getHeld())));
alert.tvsell10.setText("Sell 10 - $"+String.valueOf(calcCost(10)));
alert.tvsellAmt.setText("Sell Amount (0-"+String.valueOf(masterRes.get(currentResIndex).getHeld())+")");
}
}
});
// etc etc other button handlers, alert.show() at the end
Now obviously the setTexts within the button can't resolve, as they can't see the alert I created, they just see OnClickListener.
I tried handling this like I did with my main activity's updater updateScreen(), which is a Runnable, that is a long list of setTexts and/or invalidates, and is runOnUiThread(updateScreen). Works great for the base activity.
I did some copypasta and tried to make a updateSellScreen(), get it to hook into the custom dialog's textviews, but it can't resolve the alert class... I'm kind of lost now.
Is this even possible without trashing everything and just creating a custom view (which I am very averse to trying to tackle this fresh into Android programming...)

Declare your TextViews as final. You'll still be able to set their texts, it just means you won't be able to reassign the variable references. Don't do alert.tv as the TextView is not an instance variable of your dialog, but rather of the method with which you are creating your dialog. This is the easy way. You could also declare your TextViews as instance variables of your Activity and then update them through a handler.
alert.setTitle("Sell how many "+(masterRes.get(currentResIndex).getName())+"?");
alert.setContentView(R.layout.selldialog);
final TextView tvsellAll = (TextView) alert.findViewById(R.id.sellAllText);
final TextView tvsell10 = (TextView) alert.findViewById(R.id.sell10Text);
//etc etc more handles, including buttons
tvsellAll.setText("Sell All ("+String.valueOf(masterRes.get(currentResIndex).getHeld())+") - $"+String.valueOf(calcCost(masterRes.get(currentResIndex).getHeld())));
tvsell10.setText("Sell 10 - $"+String.valueOf(calcCost(10)));
// etc etc more setTexts
btnsell10.setOnClickListener( new OnClickListener() {
public void onClick(View v) {
if (v.isEnabled()) {
int y=masterRes.get(currentResIndex).getHeld();
masterRes.get(currentResIndex).setHeld(y-10);
held -= 10;
money += (calcCost(10));
updateScreen();
tvsellAll.setText("Sell All ("+String.valueOf(masterRes.get(currentResIndex).getHeld())+") - $"+String.valueOf(calcCost(masterRes.get(currentResIndex).getHeld())));
tvsell10.setText("Sell 10 - $"+String.valueOf(calcCost(10)));
tvsellAmt.setText("Sell Amount (0-"+String.valueOf(masterRes.get(currentResIndex).getHeld())+")");
}
}
});

In activity where you creates your dialog, you can declare private variables of dialog, textviews, etc, then they will be accessible anywhere in activity.
dialogA = new Dialog(myActivity.this, android.R.style.Theme_Dialog);
dialogA.setContentView(R.layout.myDialog);
// ...
tv1 = (TextView) dialogA.findViewById(R.id.textView1);
Button b1 = (Button) dialogA.findViewById(R.id.button1);
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String s1 = tv1.getText().toString();
Toast.makeText(myActivity.this, s1, Toast.LENGTH_SHORT).show();
dialogA.cancel();
}
});
dialogA.show();

Related

Android Development - Create a menu with 3 imageButtons

First of all english is not my first language but i will try my best.
Also... i am pretty sure my title choice was not the best so sorry for that.
Basically what i wanted to do is a menu with three ImageButtons but there is a tricky part (tricky for me at least) since every time i press one button that same button changes image (to a colored version instead of a grayed out image) and the other two change as well from colored version of their respective images to grayed out ones, actually only one of the other two will change since the purpose of this is to be able to activate only one at a time so it would not be possible to have the other two active at the same time.
Notice that this is not a menu on the top right corner but just a set of three ImageButtons on a activity or Fragment.
I already tried a lot of stuff to make that happen but so far no luck but i think i know why though i can't find a workaround for this since i am actually new in android dev.
what i tried was inside the setOnClickListener of any of those buttons such as:
eventsButton.setOnClickListener(
new View.OnClickListener() {
public void onClick(View view) {
ImageButton eventsButton = (ImageButton) view.findViewById(R.id.eventsButton);
eventsButton.setBackgroundResource(R.drawable.events_icon_active);
eventsButton.setClickable(false);
}
}
);
i tried to add the functions to change the other imageButtons as well like:
eventsButton.setOnClickListener(
new View.OnClickListener() {
public void onClick(View view) {
ImageButton eventsButton = (ImageButton) view.findViewById(R.id.eventsButton);
eventsButton.setBackgroundResource(R.drawable.events_icon_inactive);
eventsButton.setClickable(false);
ImageButton contactsButton = (ImageButton) view.findViewById(R.id.contactsButton);
contactsButton.setBackgroundResource(R.drawable.contacts_icon_inactive);
contactsButton.setClickable(true);
ImageButton interestsButton = (ImageButton) view.findViewById(R.id.interestsButton);
interestsButton.setBackgroundResource(R.drawable.interests_icon_inactive);
interestsButton.setClickable(true);
}
}
);
and i repeated that three time, always setting the other buttons clickable and setting their images to the inactive one (the grayed out one), also setting the button i click as no longer clickable.
But from what i gather i cant do any references to any other buttons inside the eventsButton.setOnClickListener like the buttons interestsButton or contactsButton, it will crash the app as soon as i touch any of those three buttons with the following error message:
Attempt to invoke virtual method 'void android.widget.ImageButton.setBackgroundResource(int)' on a null object reference
And it always point to the first line where i make a reference to another button other then the one used to start the setOnClickListener.
If you can just point me in the right direction i would be tremendously grateful.
All the best
You can declare your ImageViews as final outside the scope of the listener and when the onClickListener(View v) is called you can then just call setBackground because they are final and you can reference them from inside the listener.
Something like this:
final ImageView view1 = (ImageView) findViewById(R.id.view1id);
final ImageView view2 = (ImageView) findViewById(R.id.view2id);
view1.setOnClickListener(
new View.OnClickListener() {
public void onClick(View view) {
// do whatever you want to the ImageViews
// view1.setBackground...
}
}
);
eventsButton.setOnClickListener(
new View.OnClickListener() {
public void onClick(View view) {
ImageButton contactsButton = (ImageButton) view.findViewById(R.id.contactsButton);
contactsButton.setBackgroundResource(R.drawable.contacts_icon_inactive);
contactsButton.setClickable(true);
}
}
);
Your problem is in view.findViewById(R.id.contactsButton): view here is the button being clicked (the events one), and by calling view.findViewById(contactsButton) you are implicitly saying that the contact button is a child of view, which is not.
Just use findViewById() (from Activity), getActivity().findViewById() (from Fragments), or better container.findViewById() (if you have a reference to the layout containing the three buttons).
I'm not saying that yours is the most efficient way to deal with a menu, just pointing out your error.
You can first make things simple; I suggest:
you add 3 array (Arraylist might be better) fields in your activity class, one for the buttons, one for the active resources and one for the inactive resources
initialize those arrays in the onCreate method;
define a single onClickListener object and use it for all the buttons; Use a loop in the onClick method, see bellow.
In terms of code, it looks like this:
ImageButton[] buttons;
int[] activeResources;
int[] inactiveResources;
protected void onCreate2(Bundle savedInstanceState) {
View.OnClickListener onClickListener = new View.OnClickListener(){
public void onClick(View view) {
ImageButton clickedButton = (ImageButton) view;
for(int i = 0; i<buttons.length; i++){
ImageButton bt = buttons[i];
if(clickedButton==bt){
bt.setBackgroundResource(inactiveResources[i]);
bt.setClickable(false);
}else{
bt.setBackgroundResource(activeResources[i]);
bt.setClickable(true);
}
}
}
};
buttons = new ImageButton[3];
activeResources = new int[3];
inactiveResources = new int[3];
int idx = 0;
buttons[idx] = (ImageButton) findViewById(R.id.eventsButton);
inactiveResources[idx] = R.drawable.events_icon_inactive;
activeResources[idx] = R.drawable.events_icon_active;
idx = 1;
buttons[idx] = (ImageButton) findViewById(R.id.contactsButton);
inactiveResources[idx] = R.drawable.contacts_icon_inactive;
activeResources[idx] = R.drawable.contacts_icon_active;
idx = 3;
buttons[idx] = (ImageButton) findViewById(R.id.interestsButton);
inactiveResources[idx] = R.drawable.interests_icon_inactive;
activeResources[idx] = R.drawable.interests_icon_active;
for(int i =0; i<buttons.length; i++){
buttons[i].setBackgroundResource(activeResources[i]);
buttons[i].setOnClickListener(onClickListener);
}
}
Do not expect it to run right the way, I am giving only ideas, you have to look and see if it fit for you are looking for.

How do I go about setting up a user interface that involves tags?

Here is what I am aiming for:
I am unsure if I am doing this correctly. There are probably better,more efficient, and cleaner ways to do it, but I need to know how.
This layout was designed in xml and inflated via an inflater. The produced view was then placed into an AlertDialog. Thus, this is seen as an AlertDialog by the user.
My concern is with the tags section at the bottom. I want this to work like how Tumblr tags work. Type a string, hit the button, and a button with that tag name will show up in the blank section below it.
Now, if you click on those buttons (with their respective tag names), they will disappear from the frame.
I have several concerns.
I have trouble implementing listeners. If the AddTag button creates more buttons in the (currently invisible, but present) LinearLayout, then what about the created buttons? How do those buttons implement onClick listeners that will remove themselves from the LinearLayout if they were created in some inner method defined from the AddTag button's onClick method?
I am afraid about having to declare some of these views as FINAL in order to reference them in button methods and inner classes. I am now stuck because of this.
Do I have to define my own layout for the tag buttons? You see, a LinearLayout displays things one after the other, yes? I want to try to recreate how some social networking sites do it. Fill the layout with buttons from top to bottom, left to right. If there is no room left in the current row, go to the next one and add the tag button there. It's basically a dynamic LinearLayout that has autowrapping.
If there are any better ways of implementing this, please let me know a general step by step of what to do. I have not learned Fragments yet, but I think it may be VERY applicable here. Also, should I be creating a class that extends ViewGroup, inflating the XML there, and adding helper methods to handle things? I suppose from a DialogFragment I could then addView(the class I just created) and work from there?
Here is my current code by the way. I am stuck and stumped.
/**
* Opens a view for the user to define their new action and add it to the
* dictionary.
*
* #param view
*/
public void defineNewAction(View view) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
LayoutInflater inflater = this.getLayoutInflater();
View viewToSet = inflater.inflate(
R.layout.define_new_action_window_layout,
null);
final EditText newActionName = (EditText) viewToSet
.findViewById(R.id.set_action_name);
final RadioGroup priorityGroup = (RadioGroup) viewToSet
.findViewById(R.id.radiogroup_set_priority);
final EditText goalTimeHours = (EditText) viewToSet
.findViewById(R.id.set_goal_time_hours);
final EditText goalTimeMinutes = (EditText) viewToSet
.findViewById(R.id.set_goal_time_minutes);
final EditText addTagsInput = (EditText) viewToSet
.findViewById(R.id.add_tags_input);
Button addTagButton = (Button) viewToSet.findViewById(R.id.btn_add_tags);
final ArrayList<String> tags = new ArrayList<String>();
final LinearLayout currentTagsLayout = (LinearLayout) viewToSet
.findViewById(R.id.current_tags);
addTagButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String tag = addTagsInput.getText().toString();
tags.add(tag);
Button newTag = new Button(builder.getContext());
int tagId = tag.hashCode();
if (tagId < 0)
tagId *= -1;
newTag.setId(tagId);
newTag.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Button toRemove = (Button) currentTagsLayout.findViewById(tagId);
currentTagsLayout.removeView(toRemove);
}
});
currentTagsLayout.addView(newTag);
}
});
builder.setTitle("Define your action.");
builder.setView(viewToSet);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
String name = newActionName.getText().toString();
int priority = priorityGroup.getCheckedRadioButtonId();
int goalHours = Integer
.parseInt(goalTimeHours.getText().toString());
int goalMinutes = Integer.parseInt(goalTimeMinutes.getText()
.toString());
}
});
builder.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
I have trouble implementing listeners
There's no trouble. For the functionality you are trying to achieve, you can keep adding buttons and setting OnClickListeners on them. You don't even need to give them an id, or track them in any way. The following code inside your OnClickListener will do:
newTag.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Use the View given to you
currentTagsLayout.removeView(v);
}
});
I am afraid about having to declare some of these views as FINAL
This is how Java works. I haven't noticed any crippling effects of this. You can also declare your variables as global to not have to define them as final. But I don't see why declaring them as final is an issue. Could you provide an example where this is a problem?
Do I have to define my own layout for the tag buttons?
This is something you will have to deal with yourself. It's a design decision. If you need auto-wrapping support, you can look at Android Flow Layout: Link. It's an extended LinearLayout that supports auto-wrap of its contents.
I have not learned Fragments yet, but I think it may be VERY
applicable here
I don't see why they would be.
Note/Aside: Some kind of a check here would be better:
String tag = "";
if (!addTagsInput.getText().toString().equals("")) {
tag = addTagsInput.getText().toString();
} else {
// handle empty string
}

Retrieving Value from EditText in DialogFragment

I'm going through Google's Android Developer page on Dialogs, specifically this section. However, instead of creating the DialogFragment's message programmatically, I made a pre-set layout named layout_newpayperiod.xml with the following elements:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Spinner
android:id="#+id/spinner_payperiod"
android:layout_width="fill_parent"
android:layout_height="48dp"
android:padding="8dp"
android:entries="#array/pay_periods"
/>
<EditText
android:id="#+id/edittext_savepercent"
android:layout_width="fill_parent"
android:layout_height="48dp"
android:padding="8dp"
android:inputType="number"
android:hint="Percent to Save"
/>
<EditText
android:id="#+id/edittext_payment"
android:layout_width="fill_parent"
android:layout_height="48dp"
android:padding="8dp"
android:inputType="numberDecimal"
android:hint="Total Payment"
/>
</LinearLayout>
When I call the DialogFragment it shows up as normal, with the Spinner having the proper values. I filled in the entries and hit "OK", but when I try to retrieve the values from the Spinner and two EditText fields, the app forces close with a NumberFormatException: Invalid double "". I get the feeling I'm not retrieving the Views properly. Can anyone help me figure this out please? Thanks!
public class StartPayperiodDialogFragment extends DialogFragment {
/* The activity that creates an instance of this dialog fragment must
* implement this interface in order to receive event callbacks.
* Each method passees the DialogFragment in case the host needs to query it.
*/
public interface StartPayperiodDialogListener{
public void onDialogPositiveClick(DialogFragment dialog);
public void onDialogNegativeClick(DialogFragment dialog);
}
// Use this instance of the interface to deliver action events
StartPayperiodDialogListener listener;
// Override the Fragment.onAttach() method to instantiate the StartPayperiodDialogListener
#Override
public void onAttach(Activity activity){
super.onAttach(activity);
// Verify that the host activity implements the callback interface
try{
// Instantiate the NoticeDialogListener so we can send events to the host
listener = (StartPayperiodDialogListener) activity;
}catch(ClassCastException e){
// The activity doesn't implement the interface, throw exception
throw new ClassCastException(activity.toString() + " must implement StartPayperiodDialogListener");
}
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState){
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
View transactionLayout = View.inflate(getActivity(), R.layout.layout_newpayperiod, null);
builder.setView(transactionLayout)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// Send the positive button event back to the calling activity
listener.onDialogPositiveClick(StartPayperiodDialogFragment.this);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// Send the negative button event back to the calling activity
listener.onDialogNegativeClick(StartPayperiodDialogFragment.this);
}
});
return builder.create();
}
}
In MainActivity.class, the callback method:
#Override
public void onDialogPositiveClick(DialogFragment dialog) {
// User pressed OK, so we need to grab the values from the
// dialog's fields and apply them to the Views in the Main
// Activity
View transactionLayout = View.inflate(this, R.layout.layout_newpayperiod, null);
// Start with the payment amount
EditText paymentEt = (EditText) transactionLayout.findViewById(R.id.edittext_payment);
TextView paymentTv = (TextView) findViewById(R.id.text_paycheck);
paymentTv.setText(moneyFormat.format(Double.parseDouble(paymentEt.getText().toString())));
// Next, the percent to save
EditText savingsEt = (EditText) transactionLayout.findViewById(R.id.edittext_savepercent);
TextView savingsTv = (TextView) findViewById(R.id.text_savings);
savingsTv.setText(savingsEt.getText().toString() + "%");
// Then, the pay period
Spinner periodSp = (Spinner) transactionLayout.findViewById(R.id.spinner_payperiod);
TextView periodTv = (TextView) findViewById(R.id.text_payperiod);
periodTv.setText(periodSp.getSelectedItem().toString());
// Finally, let's update the daily allowance amount and clear
// the adapter
adapter.clear();
adapter.notifyDataSetChanged();
TextView allowanceTv = (TextView) findViewById(R.id.text_allowance);
Double allowanceValue;
switch(periodSp.getSelectedItemPosition()){
case(0): // Daily
allowanceValue = Double.parseDouble(paymentTv.getText().toString());
break;
case(1): // Weekly
allowanceValue = Double.parseDouble(paymentTv.getText().toString()) / 7;
break;
case(2): // 2 Weeks
allowanceValue = Double.parseDouble(paymentTv.getText().toString()) / 14;
break;
case(3): // 30 Days
allowanceValue = Double.parseDouble(paymentTv.getText().toString()) / 30;
break;
default: // Debugging purposes only
allowanceValue = 42.0;
break;
}
allowanceTv.setText(Double.toString(allowanceValue));
}
Try this:
#Override
public void onDialogPositiveClick(DialogFragment dialog) {
// User pressed OK, so we need to grab the values from the
// dialog's fields and apply them to the Views in the Main
// Activity
// Start with the payment amount
Dialog dialogView = dialog.getDialog();
EditText paymentEt = (EditText) dialogView.findViewById(R.id.edittext_payment);
... etc. (Retrieve any other views from the dialog by querying the dialogView in the same way.)
Your inflate code "inflates" a brand new version of that view. You want to access the one that was created in the dialog.
I think that this line View transactionLayout = View.inflate(this, R.layout.layout_newpayperiod, null); messes everything. Maybe it's not messing, but you're getting address of freshly created layout and assign it to transactionLayout reference. Then you're getting Views from that layout EditText paymentEt = (EditText) transactionLayout.findViewById(R.id.edittext_payment); which are certainly uninitialisted. It has value empty string value -> "";
I think you should use findViewById to get reference to your EditText's as you do with your TextView's. But as you are in your MainActivity which layout is probably not a parent view to your R.layout.layout_newpayperiod, you must find a way to do that properly.
You've got your DialogFragment as parameter in this onDialogPositiveClickcallback method. So you can obtain it's View and the layout you're looking for - that contains your EditText's
Sorry for editing this post so many times.

how to implement onclicklistener to a dynamically creating textview?

Currently i am having some problem with implementing onclicklistener to a dynamically creating textview. I will explain the problem more detailed. What i need to do is, i need to create textviews when i click a button in an activity and when i click on that textview it should get removed. but i am not able to set onclicklistener to each textview. Since, set onclicklistener of textviews are written inside the onclick function of the above said button(button used for creating the textview), its scope get over when it exits from onclick function of the button(i think this is the problem). So i tried using visible and invisible feature, which will create the textviews before hand and make them invisible and they are made visible only when the button(button used for creating the textview)is clicked. But here even though it is invisible the space will be allocated(ie, blank space will be availabe).
Here is my code
This button addphone will dynamically create textview by inserting the value present in the edittext phoneno
addphone.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(phoneno.getText().toString().length() > 0 && counter < MAX)
{
addphoneno[counter] = phoneno.getText().toString();
phoneno.setText("");
final TextView mybox = new TextView(getApplicationContext());
mybox.setText(addphoneno[counter]);
mybox.setPadding(5, 5, 5, 5);
mybox.setBackgroundColor(Color.rgb(99, 99, 99));
contactbox[counter] = mybox;
contactbox[counter].setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
contactbox[counter].setId(100+counter);
contactbox[counter].setText(addphoneno[counter]+" "+"X");
contactbox[counter].setClickable(true);
contactbox[counter].setOnClickListener(this); //This doesn't work!!!!!
counter = counter+1;
}
}
});
But the setOnClickListener in the above line is not working
So can anyone pls help me with this problem. I hope you are clear with my question.
Thank You!
You can try this:
private OnClickListener phoneViewClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
// your code
}
};
and use that listener in your TextViews:
contactbox[counter].setOnClickListener(phoneViewClickListener);
You will have to actually define a onClickListener instead of simply setting it as a boolean value.
contactbox[counter].setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//this is where you would handle your click event
}
});
Good luck!
If your button was defined on the xml layout you can do that.
In your xml layout you can define which method will be called when a user click on your button:
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/add_phone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_send"
android:onClick="addTextView" /> // This is most imporant line
Your activity must have a method with the same name with a View parameter, like that:
/** Called when the user touches the button */
public void addTextView(View view) {
// Do something in response to button click
if(phoneno.getText().toString().length() > 0 && counter < MAX)
{
addphoneno[counter] = phoneno.getText().toString();
phoneno.setText("");
final TextView mybox = new TextView(getApplicationContext());
mybox.setText(addphoneno[counter]);
mybox.setPadding(5, 5, 5, 5);
mybox.setBackgroundColor(Color.rgb(99, 99, 99));
contactbox[counter] = mybox;
contactbox[counter].setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
contactbox[counter].setId(100+counter);
contactbox[counter].setText(addphoneno[counter]+" "+"X");
contactbox[counter].setClickable(true);
contactbox[counter].setOnClickListener(this); //This will work \o/
counter = counter+1;
}
}
}
On this method you should put your code to addViews.
As the behavior of all added textview must to be the same( i understood in that way), be removed when a user clicked on it, you can make your activity implements onClickListener and with that you just need to implement correctly the onClick method of your activity.

Button not clicking in Portrait Mode

I have a button to which I attach an onClickListener via code. I have to to this through code because it's in a fragment.
The listener works fine when in landscape mode, but when it's in portrait it doesn't. There's no "click" sound even.
In my xml file, I set the initial visibility of the button to invisible and then make it visible later when the user clicks a radio button in the same Viewgroup as the button. The onclicklisteners of the radiobuttons are working just fine in both portrait and landscape mode.
Now if I remove the "android:visibility="invisible" code in xml, the onclickstener works fine in portrait mode! But of course I need it invisible till the user clicks a radiobutton otherwise the UI doesn't make sense. Very weird indeed.
Here's my code:
private void setOnClickForSaveButton(View v) {
Button changeFundsSave = (Button) v.findViewById(R.id.change_funds_save);
changeFundsSave.setOnClickListener(saveListener);
}
Button.OnClickListener saveListener = new Button.OnClickListener() {
#Override
public void onClick(View v) {
//Get the rootview
View rootView = v.getRootView();
EditText changeFundsEdit = (EditText) rootView.findViewById(R.id.change_funds_edit);
if(changeFundsEdit.getText().toString().equals("")) {
new AlertDialog.Builder(getActivity())
.setTitle( "" )
.setMessage( "Enter the number of units" )
.setPositiveButton( "Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
})
.show();
return;
}
}
};
private void setOnClicksForRadioButtons(View v) {
RadioButton rb1 = (RadioButton)v.findViewById(R.id.add_units);
RadioButton rb2 = (RadioButton)v.findViewById(R.id.remove_units);
RadioButton rb3 = (RadioButton)v.findViewById(R.id.set_units);
rb1.setOnClickListener(addRemoveSetButtonListener);
rb2.setOnClickListener(addRemoveSetButtonListener);
rb3.setOnClickListener(addRemoveSetButtonListener);
}
OnClickListener addRemoveSetButtonListener = new OnClickListener() {
#Override
public void onClick(View v) {
// Since we only have the radiobutton view, we need to get the parent
View rootView = v.getRootView();
//Make the controls visible
TextView changeFundsText = (TextView) rootView.findViewById(R.id.change_funds_text);
EditText changeFundsEdit = (EditText) rootView.findViewById(R.id.change_funds_edit);
Button changeFundsSave = (Button) rootView.findViewById(R.id.change_funds_save);
changeFundsText.setVisibility(View.VISIBLE);
changeFundsEdit.setVisibility(View.VISIBLE);
changeFundsSave.setVisibility(View.VISIBLE);
}
};
}
Solved the problem! In portrait mode, like everyone else I load one fragment in a separate activity. Out of habit I was calling setContentView(something) before loading the fragment! So ultimately the two layouts were overlapping each other and the visible and invisible buttons were overlapping each other and things must have gotten messed up. Damn, I'm not sure if I like the concept of fragments at all. My first time using them. But maybe I just need to learn how to wire them up properly before I get used to them :) Thank you so much for your help
my guess is that
1) do you findViewById again for the view you passed in setOnClickForSaveButton? since the old view will be destroyed and a view will be created when you change screen orientation
2) do you have multiple ids for R.id.change_funds_save
3) add a log at the first line of onclick(v) to see if it is called but goto another branch you didnt expect.
Unless you are loading two separate xml layout files from layout-land and layout-port, there shouldn't be much difference between landscape mode and portrait mode. That being said, I'm going to take a wild guess and say that your app is probably not working correctly due to configuration changes. Let me know if this is actually true... i.e. does your app work at first, but stops working when you rotate the screen?
If this is true, you should look into how the Activity lifecycle is affecting your views and onClickListeners.

Categories

Resources