I have an application on which I apply some resources to buttons to modify their backgrounds.
All work well, but when my application goes to onResume after onPause, I'm not able to set the background anymore.
I have a set of 18 buttons, and when I am in onResume, i call:
for (int i = 0; i < max; i++) {
Button b = l.get(i);
b.setBackgroundResource(R.color.green);
}
In l i have the list of all buttons got from findViewById().
This works only for the last element of the for, but not for the others.
Any idea?
** Edit **
This is the code I use for populating the array
btn_1 = (Button)findViewById(R.id.btn_1);
btn_1.setOnClickListener(this);
l.add(btn_1);
this is repeated for all my buttons.
** Second edit **
public void onResume() {
btn_1 = (Button)findViewById(R.id.btn_1);
btn_1.setOnClickListener(this);
l = new ArrayList<Button>();
l.add(btn_1);
...
for (int i = 0; i < max; i++) {
Button b = l.get(i);
b.setBackgroundResource(R.color.green);
}
}
The same is done in onCreate().
try the d following.. this will works fine.
List<Button> mButtonList = new ArrayList<Button>();
onCreate() {
mButtonList.add((Button) findViewById(R.id.btn_1));
mButtonList.add((Button) findViewById(R.id.btn_2));
mButtonList.add((Button) findViewById(R.id.btn_3));
....
for(Button b : mButtonList) {
b.setOnClickListener(this);
}
}
onResume() {
for(Button b : mButtonList) {
b.setBackgroundResource(R.color.green);
}
}
Simple example:
Activity
public class StackOverFlowActivity extends Activity {
private ArrayList<Button> myArray = new ArrayList<Button>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myArray.add((Button)findViewById(R.id.btn_1));
myArray.add((Button)findViewById(R.id.btn_2));
myArray.add((Button)findViewById(R.id.btn_3));
myArray.add((Button)findViewById(R.id.btn_4));
myArray.add((Button)findViewById(R.id.btn_5));
}
#Override
protected void onResume() {
super.onResume();
for (Button b : myArray) {
b.setBackgroundColor(getResources().getColor(R.color.blue));
}
}
}
XML main
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:id="#+id/btn_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 1" />
<Button
android:id="#+id/btn_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 2" />
<Button
android:id="#+id/btn_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 3" />
<Button
android:id="#+id/btn_4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 4" />
<Button
android:id="#+id/btn_5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 5" />
</LinearLayout>
My color in the Strings.xml
<color name="blue">#0099CC</color>
Use this instead:
for (int i = 0; i < max; i++) {
Button b = l.get(i);
b.setBackgroundColor(getResources().getColor(R.color.green));
}
If max is really big you might want to cache the getColor result before the loop.
EDIT:
According to the docs: setBackgroundResource is to be used with drawable ids only, and setBackgroundColor seems to be exactly what you need, so maybe another part of your code isn't working well, maybe the loop, the above line for setBackgroundColor works well on my app.
You've said:
": the ... code is the same for btn_1, just swap btn_1 with btn_2, btn_3 and so on. "
if so, than these lines are resetting your Array every time you try and add a new button.
l = new ArrayList<Button>();
l.add(btn_1);
P.S. you should avoid using a manual creation of buttons array - instead use some Parenting Layout such as LinearLayout and then fetch his button son's using getChildAt(i), It's much cleaner. Example:
// Register all the buttons in the layout to the OnClickListener
LinearLayout lin = (LinearLayout)findViewById(R.id.linear_buttons);
int childcount = lin.getChildCount();
for (int i=0; i < childcount; i++){
View v = lin.getChildAt(i);
v.setOnClickListener(this);
}
Try this --
for (int i = 0; i < l.getChildCount(); i++)
{
Button b = (Button) l.getChildAt(i);
b.setBackgroundResource(R.color.green);
}
try this. its working for me
for (int i = 0; i < count; i++) {
btn_title[i] = new Button(ActivityName.this);
btn_title[i].setText(menu.menu_title[i]);
btn_title[i].setId(i);
btn_title[i].setTextColor(Color.BLACK);
btn_title[i].setBackgroundColor(Color.parseColor(dataxml
.getMenucolor()));
btn_title[i]
.setTextSize(Integer.parseInt(dataxml.getFontsize()));
btn_title[i].setGravity(Gravity.CENTER_VERTICAL
| Gravity.CENTER_HORIZONTAL);
btn_title[i].setSingleLine();
btn_title[i].setEllipsize(TruncateAt.END);
btn_title[i].setOnClickListener(new ButtonListner());
}
hope this will help
why don't extend Button class, set its color, then use that new class?
It wont work obviously , let me explain why it has set last value of button .
you are using of one button reference (whatever u got from (Button)findViewById(R.id.btn_1) )
and untimely there is a one button reference and u just change its value using l.add(btn_1);
what you need to do is , do create a new button instance for each button and inflate it in proper view .
here is the small tick for that
for (int i==0 ; i < length; i++ ){
Button button = new Button(context);
collectionOfButton.add(button) ;
}
use that buttons collection using inflate if u try to integrate in some xml layout file .
Related
I have n CheckBox elements in my XML layout for a user registration page. My XML is as follows:
<CheckBox
android:id="#+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Option 1"/>
<CheckBox
android:id="#+id/checkBox2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Option 2" />
How can I add those elements to a LinkedList of type CheckBox in my java code? Ideally, I'd like to use a for-loop to find all elements containing ID "checkbox."
Thanks for any assistance.
You could traverse through the parent view (let's say it's called resultView).
List<CheckBox> boxes = new ArrayList<>();
for (int i = 0; i < resultView.getChildCount(); i++) {
if (resultView.getChildAt(i) instanceof CheckBox) {
// this is a check box for sure
boxes.add((CheckBox) resultView.getChildAt(i));
}
if (resultView.getChildAt(i).toString().contains("checkbox")) {
// this might be a checkbox, and may cause ClassCastException
boxes.add((CheckBox) resultView.getChildAt(i));
}
}
If your CheckBoxes are in the same parent view, you can try to loop for it's children like :
List<CheckBox> list = new LinkedList<>();
RelativeLayout layout = (RelativeLayout)findViewById(R.id.layout);
for (int i = 0; i < layout.getChildCount(); i++) {
View child = layout.getChildAt(i);
//Some condition to get the view you want
//and make sure it's a CheckBox (maybe by tag?)
list.add((CheckBox)child);
}
I have 16 Buttons in my Activity and I have to initialize those inside onCreate().
Is there any way to initialize all buttons in one single line code?(loops etc.)
Code should take all buttons R.id. from XML Layout and process....
Let's say you named your button button_0, button_1, .. button_15. You can do:
for (int i = 0; i < 16; i++) {
int id = getResources().getIdentifier("button_"+i, "id", getPackageName());
button[i] = (Button) findViewById(id);
}
Well, if all 16 of those buttons are inside one view or layout, then you could do the following.
ArrayList<View> allButtons;
allButtons = ((LinearLayout) findViewById(R.id.button_container)).getTouchables();
This assumes that your container (in this example a LinearLayout) contains no Touchable that is not a Button.
use Butterknife view injections library
Download Android ButterKnife Zelezny plugin for Android Studio or Intellij IDEA
and initialize all your views from current layout by 1 click
For xamarin android :
List<Button>() allButtons = new List<Button>();
for (int i = 1; i < 15; i++)
{
int id = this.Resources.GetIdentifier("btn" + i.ToString(), "id", this.PackageName);
Button btn = (Button)FindViewById(id);
allButtons.Add(btn);
}
This method takes all buttons inside the layout, hope it helps. Easy to implement & you can use it for almost every project, no libraries required.
public List<Button> getAllButtons(ViewGroup layout){
List<Button> btn = new ArrayList<>();
for(int i =0; i< layout.getChildCount(); i++){
View v =layout.getChildAt(i);
if(v instanceof Button){
btn.add((Button) v);
}
}
return btn;
}
Example
List<Button> btn_list = getAllButtons(myRelativeLayout);
Button my_btn = btn_list.get(0);
my_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.d("btn_test", "onClick: hello");
}
});
If you are using Kotlin, and your buttons have ids in the form of button1, button2... button16, you can do something like this:
var btn = ArrayList<Button>(16)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_game_screen)
for(i in 0 until 16) {
var id = resources.getIdentifier("button"+(i+1), "id", packageName)
btn.add(findViewById<View>(id) as Button)
btn[i].setText("something") //or do whatever now
}
}
If you only know the container id or the button ids are all different try this:
Activity(on create method before setContentView)
List<Integer> idButtons= new ArrayList<>();
//container_button is my button container
RelativeLayout containerButton = findViewById(R.id.container_button);
for(int i =0; i < containerButton.getChildCount(); i++){
View v = containerButton.getChildAt(i);
if(v instanceof Button){
idButtons.add(((Button) v).getId());
}
}
Layout
<RelativeLayout
android:id="#+id/container_button"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:layout_weight="1"
android:layout_marginEnd="0dp">
<Button
android:id="#+id/buttonac"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/red_button"
android:textColor="#android:color/white"
android:text="AC"
android:onClick="pulsacion" />
<Button
android:id="#+id/buttondel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/buttonac"
android:layout_alignBottom="#+id/buttonac"
android:background="#drawable/red_button"
android:textColor="#android:color/white"
android:text="DEL"
android:onClick="pulsacion" />
[...]
</RelativeLayout>
Hi I am working on writing my first usable android app. I have the following query , is there a way to populate values of a flied , based on value selected in a spinner.
e.g When country A is selected , 3 values are shown .
But when country B is selected, only 2 values are shown.
Is there a way to achieve this on Android screen? can someone provide some examples or point me in the right direction.
I think this example can help you not sure. I am creating a linear layout on which I will add all option. I am managing options in a hashmap. You can change according to your requirement.
Here is my main Activity:
public class MainActivity extends Activity {
HashMap <String, CheckBox> options = new HashMap<String, CheckBox>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int number_of_options = 2;
for (int i = 0; i < number_of_options; i ++) {
create_view("option " + i);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private void create_view(String option)
{
LinearLayout layout = new LinearLayout(getApplicationContext());
layout.setOrientation(LinearLayout.VERTICAL);
TextView text_option = new TextView(getApplicationContext());
text_option.setText(option);
CheckBox check_box = new CheckBox(getApplicationContext());
layout.addView(text_option);
layout.addView(check_box);
LinearLayout inner_layout = (LinearLayout) findViewById(R.id.linear_layout);
inner_layout.addView(layout);
options.put(option, check_box);
}
}
create_view will create options for you.
Here is my XML layout:
<Spinner
android:id="#+id/spinner1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginTop="28dp" />
<LinearLayout
android:id="#+id/linear_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/spinner1"
android:layout_below="#+id/spinner1"
android:orientation="horizontal" >
</LinearLayout>
I am simply creating a linear layout and adding options on it. If you are having any doubt then you may ask I will try to help.
I am not managing margin between options.
I have ten buttons in my xml layout i want to exchange the position of the 10 buttons randomly. I tried two methods to achieve it.
Method 1: I changed the background resource of the button but only the image changed. Not the button position on the layout. Here is my workings for method 1.
objects = new ArrayList<Integer>();
objects.add(R.drawable.num_one);
objects.add(R.drawable.num_eight);
objects.add(R.drawable.num_six);
objects.add(R.drawable.num_five);
objects.add(R.drawable.num_nine);
objects.add(R.drawable.num_four);
objects.add(R.drawable.num_two);
objects.add(R.drawable.num_three);
objects.add(R.drawable.num_zero);
objects.add(R.drawable.num_seven);
// Shuffle the collection
Collections.shuffle(objects);
List<Button> buttons = new ArrayList<Button>();
buttons.add((Button)findViewById(R.id.name));
buttons.add((Button)findViewById(R.id.boutton_eight));
buttons.add((Button)findViewById(R.id.boutton_six));
buttons.add((Button)findViewById(R.id.boutton_five));
buttons.add((Button)findViewById(R.id.time));
buttons.add((Button)findViewById(R.id.boutton_four));
buttons.add((Button)findViewById(R.id.boutton_two));
buttons.add((Button)findViewById(R.id.search_box));
buttons.add((Button)findViewById(R.id.boutton_zero));
buttons.add((Button)findViewById(R.id.boutton_seven));
for (int i = 0; i < objects.size(); i++) {
buttons.get(i).setBackgroundResource(objects.get(i));
}
In Method two: I shuffled the button directly but as the widget are already set in the xml layout. AddView () give an error message that the view is already set. Here is my working for the second solution.
ll = (LinearLayout)findViewById(R.id.llShuffleBox);
//create another two linear layouts which will host 5 buttons horizontally
top_compte = (LinearLayout)findViewById(R.id.top_compte);
bottom_calculator= (LinearLayout)findViewById(R.id.bottom_calculator);
buttons.add((Button)findViewById(R.id.name));
buttons.add((Button)findViewById(R.id.boutton_eight));
buttons.add((Button)findViewById(R.id.boutton_six));
buttons.add((Button)findViewById(R.id.boutton_five));
buttons.add((Button)findViewById(R.id.time));
buttons.add((Button)findViewById(R.id.boutton_four));
buttons.add((Button)findViewById(R.id.boutton_two));
buttons.add((Button)findViewById(R.id.search_box));
buttons.add((Button)findViewById(R.id.boutton_zero));
buttons.add((Button)findViewById(R.id.boutton_seven));
Collections.shuffle(buttons);
for (int i=0;i<5;i++) {
top_compte.addView(buttons.get(i));
}
//add remaining 5 to second layout
for (int i=5;i<10;i++){
bottom_calculator.addView(buttons.get(i));
}
// ll.addView(top_compte);
ll.addView(bottom_calculator);
My question is how can i exchanged the position of the buttons on my layout. Note button 0 to 4 is in a horizontal linear layout and below it is the second horizontal linear layout containing button 5 to 9. Also ll is the Main LinearLayout that contain the two horizontal layout.
You can try creating the Buttons dynamically(in code). So, you'll have a LinearLayout(vertical) and two LinearLayouts(horizontal) within it. Keep your xml file as:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/llShuffleBox"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/top_compte"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
</LinearLayout>
<LinearLayout
android:id="#+id/bottom_calculator"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
</LinearLayout>
</LinearLayout>
Now, for the activity code:
ll = (LinearLayout)findViewById(R.id.llShuffleBox);
//create another two linear layouts which will host 5 buttons horizontally
top_compte = (LinearLayout)findViewById(R.id.top_compte);
bottom_calculator= (LinearLayout)findViewById(R.id.bottom_calculator);
// Create an ArrayList to hold the Button objects that we will create
ArrayList<Button> buttonList = new ArrayList<Button>();
// Create the Buttons, set their text as numeral value of the index variable
for (int i = 0; i < 10; i++) {
Button b = new Button(this);
b.setText("" + (i+1));
b.setGravity(Gravity.CENTER_HORIZONTAL);
buttonList.add(b);
}
// Shuffle
Collections.shuffle(buttonList);
for (int i = 0; i < 10; i++) {
// Add the first five Buttons to top_compte
// Add the last five Buttons to bottom_calculator
if (i < 5) {
top_compte.addView(buttonList.get(i));
} else {
bottom_calculator.addView(buttonList.get(i));
}
}
Edit 1:
Declare and initialize this global variable:
// Global variable
int id = 1;
Add the following method to your activity. It will generate an id that is not in use elsewhere in your view tree.
// Generates and returns a valid id that's not in use
public int generateUniqueId(){
View v = findViewById(id);
while (v != null){
v = findViewById(++id);
}
return id++;
}
Change the code to set ids to buttons:
ll = (LinearLayout)findViewById(R.id.llShuffleBox);
//create another two linear layouts which will host 5 buttons horizontally
top_compte = (LinearLayout)findViewById(R.id.top_compte);
bottom_calculator= (LinearLayout)findViewById(R.id.bottom_calculator);
// Create an ArrayList to hold the Button objects that we will create
ArrayList<Button> buttonList = new ArrayList<Button>();
// Create the Buttons, set their text as numeral value of the index variable
for (int i = 0; i < 10; i++) {
Button b = new Button(this);
b.setText("" + (i+1));
b.setGravity(Gravity.CENTER_HORIZONTAL);
b.setId(generateUniqueId()); // Set an id to Button
buttonList.add(b);
}
// Shuffle
Collections.shuffle(buttonList);
for (int i = 0; i < 10; i++) {
// Add the first five Buttons to top_compte
// Add the last five Buttons to bottom_calculator
if (i < 5) {
top_compte.addView(buttonList.get(i));
} else {
bottom_calculator.addView(buttonList.get(i));
}
}
You can retrieve the ids using the getId() method. If you do not want to use the generateUniqueId() method, you can try replacing the line b.setId(generateUniqueId()); with b.setId(i + 1);. This will set the button ids from 1 to 10. But, it can be problematic if some view in your view hierarchy has the same id as any other.
Edit 2:
Here is how you can set the OnClickListeners to the Buttons you create dynamically:
for (int i = 0; i < 10; i++) {
final Button b = new Button(this);
b.setText("" + (i+1));
b.setGravity(Gravity.CENTER_HORIZONTAL);
b.setId(i + 1);
b.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
dealWithButtonClick(b);
}
});
bList.add(b);
}
And here is one possible implementation of dealWithButtonClick(Button) method. You can change it to suit your needs:
public void dealWithButtonClick(Button b) {
switch(b.getId()) {
case 1:
b.setBackground(getResources().getDrawable(R.drawable.some_drawable_1));
break;
case 2:
b.setBackground(getResources().getDrawable(R.drawable.some_drawable_2));
break;
........
........
........
case 10:
b.setBackground(getResources().getDrawable(R.drawable.some_drawable_10));
break;
default:
b.setBackground(getResources().getDrawable(R.drawable.some_drawable_for_when_no_cases_were_matched));
break; }
}
I had a same problem (shuffle buttons) and i come up with an easy solution
I just used an array of integer numbers of buttons ids and simple shufle. In my case was that enough. It's simple and u get the same result.
Integer[] a = { 0x7f090049, 0x7f09004b, 0x7f09004c, 0x7f090048};
Collections.shuffle(Arrays.asList(a));
button1 = (Button)findViewById(a[0]);
button2 = (Button)findViewById(a[1]);
button3 = (Button)findViewById(a[2]);
button4 = (Button)findViewById(a[3]);
I hope this will help.
Regards !!
(srry for my broken english)
I have created an Android RSS Reader App.I have a text marquee in my android app.Iam fetching RSS feed and store RSS title as an array.Iam setting this array as the marque text.Check the code,
String MarqueeStr="";
TextView flashnews;
for (int i = 0; i < nl.getLength(); i++) {
MarqueeStr = MarqueeStr +" | "+ Headlines.Title[i];
}
flashnews.setText(MarqueeStr);
Now I have to set an onclick listener for my marquee, so that user can view detailed description of title which they are clicked.I know how to set it.But my problem is, how can i get the array index of clicked string in the marquee text when a user click on the marquee?
here is my XML layout,
<TextView
android:id="#+id/flashs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:lines="1"
android:ellipsize="marquee"
android:layout_marginLeft="70dp"
android:fadingEdge="horizontal"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:singleLine="true"
android:textColor="#e7e7e7" />
screen shote here..
can you see that "Latest News"? its my marquee text
I think that will only be possible if you will create your textviews dynamically and set id for them. like if you are having 10 news link then use 10 textviews
TextView txt = null;
View.OnClickListener marquee_click = new View.OnClickListener() {
#Override
public void onClick(View v) {
int selected_item = v.getTag();
switch (selected_item) {
case 0:
break;
case 1:
break;
case 2:
break;
default:
break;
}
}
};
LinearLayout news_text_layout = new LinearLayout(getApplicationContext());
news_text_layout.setOrientation(LinearLayout.HORIZONTAL);
for (int i = 0; i < 10; i++) {
txt = new TextView(getApplicationContext());
txt.setTag(i); // OR txt.setId(i);
txt.setText("new " + i);
txt.setOnClickListener(marquee_click);
news_text_layout.addView(txt);
}
// ADD YOUR LINEAR LAYOUT ON WHICH YOU HAVE ADDED ALL TEXT VIEW IN YOUR LISTVIEW FOOTER.
// NOW PERFORM SAME ANIMATION OR TRICK ON LINEAR LAYOUT WHICH YOU WERE PERFORMING ON marquee text.
Hope it can help you...
You can add every FlashNews as a dynamically created TextView. And you can put all of these in
one HorizontalScrollView. And set their listeners seperatly.
For marquee function, you can programmatically scroll the horizontalView within your code.
I dont know if it's possible to make it with your idea. (Actually it can be done, but it will contain pain i guess)
for animation look at this i have just created.
Create new project then add class and xml file which i am giving.
public class Test_stflowActivity extends Activity {
LinearLayout ll = null;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final LinearLayout ll = (LinearLayout) findViewById(R.id.linearLayout1);
final TranslateAnimation ts = new TranslateAnimation(200, -100, 0, 0);
ll.setAnimation(ts);
ts.setDuration(5000);
TextView tv = new TextView(getApplicationContext());
tv.setText("*bharat sharma*");
tv.setTextSize(30);
ll.addView(tv);
ll.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ll.startAnimation(ts);
}
});
}
}
this is xml file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/RelativeLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true" >
</LinearLayout>
</RelativeLayout>
it is working for me
if you use a ListView with an adapter, (which you should), you can use the getItem(int position) function to get the specific item.