I have an xml file called options.xml
I use it to create my AlertDialog. I also added a Done button for the AlertDialog.
When the done button is pressed, the onClick method bellow is called. However, no matter which RadioButton I have checked before clicking Done, I always get the first RadioButton as checked and the others as unchecked.
I assume that what I am doing bellow just read the xml values and not the actual run time values? Then how do I read the real run-time values?
public void onClick(DialogInterface arg0, int arg1) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE) ;
View layout = inflater.inflate(R.layout.options, null);
RadioButton a1 = (RadioButton)layout.findViewById(R.id.radio0);
RadioButton a2= (RadioButton)layout.findViewById(R.id.radio1);
RadioButton a3 = (RadioButton)layout.findViewById(R.id.radio2);
RadioButton a4 = (RadioButton)layout.findViewById(R.id.radio3);
boolean b1 = a1.isChecked();
boolean b2 = a2.isChecked();
boolean b3 = a3.isChecked();
boolean b4 = a4.isChecked();
}
EDIT: The solution I used "Thanks, I didn't check the second option but I found that AlertDialog has findViewById and it was just a matter of calling that after creating the dialog. (Not needed to be done inside onCreate or any other special function). You just need to remember to call findViewById after you called show() for the dialog, otherwise it worn't work"
You're right, you're reading the xml values of them because you're trying to findViewById on a layout inflated directly from xml.
You can either use mContext.findViewById(..) if mContext is an Activity. Failing that, define your RadioButtons somewhere in the onCreateDialog(..) rather than inside onClick(..), and then use these to determine isChecked().
This is a similar example where I had to get the value of an EditText from inside the onClick(..) method. If you need the final modifier, Eclipse should tell you. This is all in the onCreateDialog(..) method.
case FIRST_TRANSLATE:
View view = mHost.getLayoutInflater().inflate(R.layout.first_translate, null);
//Define your radiobuttons here
final EditText mLanguage = (EditText) view.findViewById(R.id.editText1);
b.setView(view)
.setTitle(R.string.dialog_first_translate_title)
.setPositiveButton(sOkay, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int arg1) {
//Retrieve their values here
mHost.getSharedPreferences(States.INTERNAL_PREFS, 0).edit().putString("deflang", mLanguage.getText().toString()).commit();
dialog.dismiss();
}
}).create();
Related
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.
this is my first question so I hope to make it clear.
I have one textView with some numerical text and next to it one button with one click listener and what I want is that when you click on the button the numerical value (>=0) of the TextView decrements in one.
Here is part of my code:
TextView Counter = new TextView(this);
if (intSeries != 0)
Counter.setText(Integer.toString(intSeries));
else
Counter.setText("0");
Counter.setId(4);
tablaContador.addView(Counter,Tr);
Button Done = new Button(this);
Done.setText("-1");
if (intSeries != 0)
Done.setVisibility(View.VISIBLE);
else
Done.setVisibility(View.GONE);
Done.setId(6);
Done.setOnClickListener(this);
And this is the onClick funcion (part of it):
#Override
public void onClick(final View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case 6:{
TextView text = (TextView)findViewById(4);
int series = Integer.parseInt(text.getText().toString());
series--;
text.setText(series);
if (series==0){
Button boton = (Button)findViewById(6);
boton.setVisibility(View.GONE);
}
}
}
}
The error is when I try to make the setText inside the onClick function, I hope it can be fixed or maybe recieve other idea to do it.
Thank you so much.
I would avoid all this hardcoding of Ids, use resources instead.
Your call to
text.setText(series)
is passing an int. The only valid setText(int resId) overload expects a resource associated with the int value, i.e. a string resource.
Convert your series value to a string.
Something like:
text.setText(Integer.toString(series));
You should setup series as an integer. And increase/descrease it as you wish. When you want to change the button's text convert the int to String.
Instead of:
text.setText(series);
use:
text.setText(String.valueOf(series));
Variablenames in java can't start with a capital letter. That is reserved for classnames.
Counter -> counter
Done -> done
I tried this and it worked:
//Create onClickListener
OnClickListener pickChoice = new OnClickListener()
{
public void onClick(View v)
{
TextView txt = (TextView) findViewById(4);
int number = Integer.valueOf(txt.getText().toString());
txt.setText(String.valueOf(number -1));
}
};
//Create layout
LinearLayout lnLayout = new LinearLayout(this);
lnLayout.setOrientation(LinearLayout.VERTICAL);
TextView txt = new TextView(this);
txt.setId(4);
txt.setText("0");
lnLayout.addView(txt);
Button Done = new Button(this);
Done.setText("-1");
Done.setId(6);
Done.setOnClickListener(pickChoice);
lnLayout.addView(Done);
setContentView(lnLayout);
Where are you creating your button inside? an activity? the part where you pass the onClickListener to the button doesn't make sense, maybe the button is getting a wrong listener and gets you an error every time you press the button ?
The code should be easy to understand, if there is anything you need me to explain please ask :)
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
}
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.
I've created an array of 5 clickable textviews using a loop, have set their parameters (size, colour, background image, to be clickable etc) and have set an onClickListener and the array is called "myArrayofTVs". Their ids have been set using the loop int (i). I have another predefined array that hold text string, and other textviews are present on the layout. Later on in the onClick method, and as all the buttons/clickable textviews do something very similar, I'd like to be able to do something like:
#Override
public void onClick(View v) {
if(v == myArrayofTVs[i]) { //using 'i' here doesn't seem to work
tv1.setText(myArray2[i]);
tv2.setText(myArray2[i+1];}
etc
etc}
I've tried various differnt ways such as using switch case statements (don't really want to use these as there will be a lot of repeated code and I'll have to add a new case statement each time I want to add new textview/buttons in the future). Is there anyway of using one statement that will handle all the buttons/clickable textviews based on the variable id given or will I have to use a separate case/tag/id statement for each one?
Many thanks in advance!
Add the views to your ViewGroup and use getChildAt(int index) and getChildCount() to create a loop. You can loop all children/views in the viewgroup and you could check with
if(child instanceof TextView)
if they are of the correct type. Then you could cast the views back to a TextView/Button/View and do the thing you want to do.
But it sounds like you want a list of something. So i would suggest using a ListView with a adapter behind it.
I really think you should use the id provided by Android instead of trying to compare objects. The reason your code wouldn't work, if it had a sufficient for loop around it, is somewhat mysterious, but I would try to parallel the switch statements you see in examples as much as possible by comparing ID's and not objects.
for( int i = 0; i < myArrayofTvs.length; i++ )
if(v.getId() == myArrayofTVs[i].getId()) {
tv1.setText(myArray2[i]);
tv2.setText(myArray2[i+1];
}
}
Also obviously you'll want to avoid an array out of bounds error in that second inner statement.
What I did was programmatically inflate my custom layout and used an onClickListener on that button from the custom layout inflated. Then to interact with a specific item I got the parent view of the view being clicked eg. your button and then used that view to change attributes of the view. This is a snippet of my code. The onClick of the alertDialog is where I go about changing values of the newly inflated view.
// if an edit button of numbers row is clicked that number will be edited
if (view.getId() == R.id.NumberRowEditButton)
{
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle("Contact edit");
alert.setMessage("Edit Number");
// Set an EditText view to get user input
final EditText input = new EditText(this);
input.setSingleLine();
alert.setView(input);
alert.setPositiveButton("Ok", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int whichButton)
{
// get input
Editable value = input.getText();
if(value.length() > 4){
View tempView = (View) view.getParent();
TextView tempTV = (TextView) tempView.findViewById(R.id.numberRowTextView);
String number = tempTV.getText().toString();
tempTV.setText(value.toString());
}
else
{
// ...warn user to make number longer
final Toast msgs = Toast.makeText(ContactEdit.this, "Number must be over 4 digits.", Toast.LENGTH_SHORT);
msgs.setGravity(Gravity.CENTER, msgs.getXOffset() / 2, msgs.getYOffset() / 2);
msgs.show();
}
}
});
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int whichButton)
{
// cancel the dialog
dialog.cancel();
}
});
alert.show();
}
Hopefully this might help you.