Get reference to Views in my Android Activity - android

I have a LinearLayout comprising of a few Buttons and I add this to my activity in the onCreate(..) method with setContentView(R.layout.myscreen). No surprises so far.
How do I get a reference to an iterator to these buttons? I'd like to add listeners to them but I'd rather not directly reference the Button's using their android:id.
Similar questions have been asked here and here but they don't quite answer my question.

Try something like this provide an id root_layout in xml to LinearLayout
LinearLayout mLayout = (LinearLayout) findViewById(R.id.root_layout);
for(int i = 0; i < mLayout.getChildCount(); i++)
{
Button mButton = (Button) mLayout.getChildAt(i);
mButton.setOnClickListener(this);
}
Where mLayout is object of you Linear Layout and Your activity must implements OnClickListener and here goes general listener
#Override
public void onClick(View v)
{
Button mButton = (Button)v;
String buttonText = mButton.getText().toString();
}
NOTE: For this to work properly you Linear Layout must only contains button no other views

You should take a look at my answer here.
In short. I'd assign the buttons a listener by setting the onClick attribute in the XML layout on each Button.
Inside of your Activity you'll need a public method like the one below which basically is what you want to do in your listener.
public void myFancyMethod(View v) {
// do something interesting here
}

If you want to go for accessing other elements you may try following syntax:
<ElementClass> <referencevariable> = (<ElementClass>) findViewById(R.id.<id_of_the_element>);
For Example:
TextView textView= (TextView) findViewById(R.id.t1); //I used t1 to refer my textview in the Layout.
This might work.
Then you can use these views with their inbuilt methods to perform as many as work you want.

Related

findViewById for dynamically added View

Is it possible to find the added TextView to update it with other options.
I am adding by this code new TextView with a Button. Now, I want also set a onClickListerner for the dynamically added TextViews. For this I have to find them with findViewById method. But they aren't createt yet.
Can I make this in a other way and if yes, How?
Button hinzufügenButton = (Button) findViewById(R.id.hinzufügen_Button);
hinzufügenButton.setOnClickListener(new Button.OnClickListener() {
public void onClick (View view){
EditText tischName = (EditText) findViewById(R.id.tisch_name_EditText);
TextView tisch = new TextView(getApplicationContext());
tisch.setText(tischName.getText());
tisch.setAllCaps(true);
tisch.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
tisch.setBackgroundColor(Color.parseColor("#9FA8DA"));
tisch.setTextSize(25);
tisch.setId(id);
id++;
LinearLayout tischeAnzeigen = (LinearLayout) findViewById(R.id.tische_LinearLayout);
tischeAnzeigen.addView(tisch);
}
});
Just add the onClickListener as you create your dynamic views
Example:
...
tisch.setId(id);
tisch.setOnClickListener(yourListener);
...
You can use setId to add an id. But you probably don't need to. If you're creating a view dynamically, you have a reference to it when you create it. Just set it on that reference. No need to find it.

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.

I need to get the id of the dynamically generating button

From this code it creates dynamic buttons accodring to a given value from another layout. I need to get the id of that and add another button (if dynamic button clicks then I need to add another button dynamically).
for (int i = 0; i < value1; i++) {
LinearLayout.LayoutParams paramsIButton = new LinearLayout.LayoutParams
((int) ViewGroup.LayoutParams.WRAP_CONTENT, (int) ViewGroup.LayoutParams.WRAP_CONTENT);
ibutton = new ImageButton(HomePage.this);
ibutton.setImageResource(R.drawable.add);
ibutton.setLayoutParams(paramsIButton);
paramsIButton.topMargin = -70;
paramsIButton.leftMargin = 370;
paramsIButton.bottomMargin = 30;
ibutton.setId(i);
ibutton.getPaddingBottom();
ibutton.setBackgroundColor(Color.WHITE);
ibutton.setAdjustViewBounds(true);
rR.addView(ibutton);
}
If I understood correctly from the additional information you provided on your comment, you need to know when a user clicked on a button. You could set an OnClickListener to your button.
// Somewhere in your activity . . .
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener(){
public void onClick(View v){
// The button is clicked! Do whatever you want.
}
});
}
// ...
// Rest of the code
// ...
Of course, you should replace R.id.button1 with your button's id.
Seems to me like you need to add an onClickListener for the dynamically added button.
Make your class implement OnClickListener and then add a listener for the dynamic button:
ibutton.setOnClickListener(this);
and add an onClick Listener within your class:
#Override
public void onClick(View v)
{
// do something with this ID
v.getId()
}
I don't know how you keep track of the bulbs and fans, I'd hope you don't do it via the UI elements alone. I'd probably do it a bit differently, creating a data structure to track the bulbs and fans and attach the specific bulb or fan object to the UI element as a tag.

Android calculator buttons

I am trying to make a calculator for Android. Here is the code for my buttons:
int[] button_ids = {
R.id.BtnNum0, R.id.BtnNum1, R.id.BtnNum2, R.id.BtnNum3, R.id.BtnNum4, R.id.BtnNum5, R.id.BtnNum6,
R.id.BtnNum7, R.id.BtnNum8, R.id.BtnNum9, R.id.BtnAdd, R.id.BtnSub, R.id.BtnDiv, R.id.BtnMult,
R.id.BtnClear, R.id.equals
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EditTextValue = (EditText) findViewById(R.id.editText1);
TVValue = (TextView) findViewById(R.id.textView1);
buttons = new ArrayList<Button>();
for(int id : button_ids) {
Button button = (Button)findViewById(id);
button.setOnClickListener(this);
buttons.add(button);
}
}
How I can change this part to a block of code where I won't have to declare the IDs of the buttons? (e.g. R.id.BtnNum0)
int[] button_ids = {
R.id.BtnNum0, R.id.BtnNum1, R.id.BtnNum2, R.id.BtnNum3, R.id.BtnNum4, R.id.BtnNum5, R.id.BtnNum6,
R.id.BtnNum7, R.id.BtnNum8, R.id.BtnNum9, R.id.BtnAdd, R.id.BtnSub, R.id.BtnDiv, R.id.BtnMult,
R.id.BtnClear, R.id.equals
};
I have been searching for an answer, but I still can't find a solution.
What you can do, since this code seems to only set a single OnClickListener for all Buttons, is to do it in xml
For each Button set
android:onClick="functionName"
then in your code you can do away with all of the id's and your for loop. In Java just create a function like
public void functionName(View v)
{
switch (v.getId())
{
case R.id.buttonId:
// do work for this Button
break;
...
}
The way you are doing it is fine but this is how I prefer to handle this situation. You just have to give all of the Buttons the same function name in xml then use that name as your function name in Java. You also just have to be sure to declare the function with a void return type and make sure it takes a View as its one and only parameter as in my example.
The Button Docs also have an example of this
in your layout file add this to every button
<Button
...
android:onClick="btnClicked"
.../>
then in your code add this method and check for each button in this method
public void btnClicked(View v)
{
switch(v.getId())
{
case R.id.BtnNum0:
// your code
break;
....
}
}
That is likely the best solution unfortunately, unless you use some sort of annotation framework which still doesn't cut down much on the boilerplate.
edit:
You could try to get a pointer to whatever ViewGroup is holding the Button views and then getting all of its children, and then looping through them while casting them to Buttons as you go.
For example: If your Button objects in XML are housed in a LinearLayout, you could get the pointer to that and do something like this:
for(int i=0; i < ((ViewGroup)v).getChildCount(); ++i) {
Button nextChild = (Button) ((ViewGroup)v).getChildAt(i);
}
Of course, I recommend against this, but it is still a possibility.
As trevor-e suggested, you can give an annotation processor a try. Android Annotations can simplify your code to:
#Click
public void BtnNum0() {
// Button 0 clicked
}
#Click
public void BtnNum1() {
// Button 1 clicked
}
// etc.
If you go this route, please do try to use names following the Java convention as the button names correspond with function names.

I need to add onClickListener to a bunch of ImageButtons

I have created a bunch of ImageButtons programmatically while in a for loop. They have worked fine as the data displayed in a HorizontalScrollView. Now I need each one to go dim or bright when clicked. First click will setAlpha(45); second click will setAlpha(255);.
I don't think I fully understand how the Views and onClickListener works yet. It seems the onClick function examples I find take a View. How would that function know which button is clicked? Perhaps there is an easier way to do what I want?
Here are the ImageButtons.
TableRow tr0 = new TableRow(this);
tr0.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
for(int but=0; but<ClueList.size(); but++){
ImageButton clueBut = new ImageButton(this);
clueBut.setBackgroundResource(0);
clueBut.setImageBitmap(ClueList.get(but).btmp);
//clueBut.setOnClickListener(this);
tr0.addView(clueBut);
}
Is there something I need to do to make the buttons identifiable? And how would that pass in through into the onClick function to be used?
-: Added Information :-
I am starting to wonder if the problem isn't with the buttons, but with the way I built the screen. More information added.
The Game activity is the main game, which uses the PuzzleView for the upper part of the screen holding the game grid. The lower part is where the ImageButtons are and I built them in place in the Game class.
public class Game extends Activity{
//various variables and stuff
private PuzzleView puzzleView; // The PuzzleView is from another .java file
// public class PuzzleView extends View
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
LinearLayout mainPanel = new LinearLayout(this);
mainPanel.setOrientation(LinearLayout.VERTICLE);
puzzleView = new PuzzleView(this);
mainPanel.addView(puzzleView);
HorizontalScrollView bottom = new HorizontalScrollView(this);
mainPanel.addView(bottom);
TableLayout clues = new TableLayout(this);
bottom.addView(clues);
TableRow tr0 = new TableRow(this);
for(int but=0; but<ClueList.size(); but++){
ImageButton clueBut = new ImageButton(this);
clueBut.setImageBitmap(ClueList.get(but).btmp);
tr0.addView(clueBut);
}
When I try to add the ClickListener(this) I get errors about this not being able to be a Game. I have similar problems in the onClick(View v) function referencing the View. Are these problems because I am building the buttons in the Game Activity instead of a View class?
Thanks
When you set up an OnClickListener and implement the onClick(View v) callback, it's the Dalvik VM the one that will call that method each time the View is clicked, and it will pass the View instance as a parameter. Thus, the code you write inside that method will be applied only to the View that received the click and not to any other View. Add something like this to your loop:
clueBut.setOnClickListener(new OnClickListener() {
public void onClick (View v) {
if (v.getAlpha() == 1f)
v.setAlpha(0.2f);
else
v.setAlpha(1f);
}
});
In the onClick event:
public void onClick(View currentView)
{
Button currentButton = (Button)CurrentView;
//Do whatever you need with that button here.
}
To identify each view uniquely use the property
View. setId(int)
In your case the code would look something like this
for(int but=0; but<ClueList.size(); but++){
ImageButton clueBut = new ImageButton(this);
clueBut.setBackgroundResource(0);
clueBut.setImageBitmap(ClueList.get(but).btmp);
clueBut.setId(but);
//clueBut.setOnClickListener(this);
tr0.addView(clueBut);
}
Inside the onclick listener match the id of the view using findViewByID()

Categories

Resources