I am integrating Card.IO library in my android project and I wanted to know a way to change CardIOActivity header and button background colors.
I have tried following
LayoutInflater inflator = (LayoutInflater)getSystemService(CardIOActivity.LAYOUT_INFLATER_SERVICE);
I wanted to inflate a view from this inflator and change the color then.
However, I don't know the name of header xmls and button xmls.
How do I change these respective background colors?
I don't know what you are actually looking for but if you are in same activity then you can try this.
View root_view = this.findViewById(android.R.id.content).getRootView();
above statement will give you root view. Now you need to search all children in this view.
for(int i=0; i<((ViewGroup)v).getChildCount(); ++i) {
View nextChild = ((ViewGroup)v).getChildAt(i);
try {
// IF TYPECAST SUCCESS THEN YOU CAN USE BUTTON FOR YOUR PURPOSE. YOU CAN USE RECURSION FOR YOU PURPOSE.
Button button = (Button)nextChild;
// HERE YOU CAN APPLY BACKGROUND FOR YOU BUTTON.
button.setBackgroundColor(Color.GREEN);
} catch (Exception e) {
}
}
The above code is just an idea how you can try to access the button. You actually need to write recursive function to get child views for all childs till child count is 0.
Related
How can I monitor multiple views in my Android application. The reason I'm interested in this, is cause, my app has a view that has lot of fields EditTexts, Spinners, CheckBoxes, RadioButtons and some EditTexts are hidden unless a particular Spinner Item is selected or a Radio Button is checked. All I want the observer to do is to check all fields are filled before the submit Button is enabled and if any View was un-hidden it must check if the Fields have been filled too. This is where I'm stuck on what to do: I have a four boolean checks that check for the four hidden Views, but then I don't want to write a long if/else statement. Thanks
The following code will help you to check an unknown number of Views of different types contained in a single ViewGroup. In your case with just four views, I think you are likely prefer four 'if' clauses.
You could mark all Views which you want to check by adding a tag in the layout file:
android:tag="CheckMe"
Tags don't have to be unique, so you can use the same tag for all Views.
In addition to that, give an id to the ViewGroup containing your Views (this could be a LinearLayout)
android:id="#+id/myLayout"
Then in your activity you can first get the ViewGroup
ViewGroup myLayout = (ViewGroup) findViewById(R.id.mylayout);
and then cycle over the child Views:
for (int i = 0; i < myLayout.getChildCount(); i++)
{
View v = myLayout.getChildAt(i);
if (v.getTag().toString().equals("CheckMe")
{
if (v instanceof EditText)
{ // do something
}
else if (v instanceof SomeOtherView)
{ // do something else
}
}
}
In my app, I want to test button background is correct with what I expect. But I get Nullpointerexception error when try to get button background. I can not see where I wrong.
My code below:
Button btnGetStarted = (Button) getActivity().findViewById(R.id.btnGetStarted);
Drawable actual = btnGetStarted.getBackground();
Drawable expect = getActivity().getResources().getDrawable(R.drawable.btn_active_normal);
assertTrue("Wrong button background", actual==expect);
Nullpointerexception at line `Drawable actual = btnGetStarted.getBackground();
I can not solve it after 2 days so I post it on here to looking for help.
Edit:
In xml file I set button background from a picture btn_getstarted.png like this: android:background="#drawable/btn_getstarted"
Your button is null here. That's why you are not getting the drawable.
Change the code in your test case like this and try :
private View inflaterView;
LayoutInflater i=(LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflaterView=i.inflate(R.layout.you_layout_file, null);
Button btnGetStarted=(Button) inflaterView.findViewById(R.id.btnGetStarted);
Addition to this I think comparing two drawable like this is not the correct way.
If both variables contain references to objects that 'look' the same, they are two different objects instances.So two drawable objects, will not return true on equals.
As a suggestion to test two drawable objects get the constantState associated to that Drawables.
btnGetStarted.getBackground().getConstantState.getConstantState().equals
(getResources().getDrawable(R.drawable.btn_getstarted).getConstantState())
Check, that you button id in xml is "#+id/btnGetStarted". Try to inflate your layout by LayoutInflater and find your button with View.findViewById()
Lets say that I have two different types of RelativeLayouts. That is to say these 2 RelativeLayouts differ because they contain different views. One might have textviews, an image view etc and the other might have also have some textviews which mean something completely different than the other set of textviews in the other relativelayout. Lets say however that both have a Submit Button. So to make my point more clear here is some code:
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
ViewParent parent = v.getParent();
if(parent instanceof CustomRelativeLayout){
CustomRelativeLayout aRelativeLayout = (CustomRelativeLayout)parent;
for(int childrenIndex = 0; childrenIndex < r.getChildCount(); childrenIndex++){
View childView = aRelativeLayout.getChildAt(childrenIndex);
}
}
}
The problem here is is that we don't know which CustomRelativeLayout aRelativeLayout is referring to. Depending on which CustomRelativeLayout it is will depend on what specific childViews i will want to search for and what logic I implement relevant to those views. I would like to be able to have a switch statement to check which type of CustomRelativeLayout is the parent.
So the questions that i would like to ask is:
how do i get more information about which instance of CustomRelativeLayout refers to the button that was clicked? Is there a way to get the instance variable name?
Once i have found out that information how do i get specific information about the children of the parent view that i am working on? The thought is, is that i might have 30 child views in the parent but i am only interested in one specific view(i might want to get the text of one specific textview as an example). I will know to look for it specifically because i would have done a switch statement on the different instances of my CustomRelativeLayouts(the first question) and therefore i know which view i want to look at, which logic to perform or what other methods that i need to call.
Would appreciate any thoughts or help with this.
For your first question, there are couple options:
Use separate OnClickListeners for each button. Then, each button will only trigger its own listener's onClick() method.
You can give each button a different id either in XML (via the android:id property) or in code (via setId(int id)). Then in onClick() you can check the id of the View that was passed as the argument.
For your second question:
Since you have the parent ViewGroup, you can find specific views within it by using:
TextView interestingView = (TextView) parent.findViewById(R.id.interesting);
This will only search the children of the parent view.
If you need to get an unknown number of views the best strategy is probably iterating through them like you are now. You can identify groups of views by setting a tag either in XML (android:tag) or code (setTag(Object tag) and check them as you iterate. For example, if you have a set of TextViews and in each one is either a color or an animal, you might handle that like this:
// defined elsewhere
private static final String TAG_COLOR = "color";
private static final String TAG_ANIMAL = "animal";
...
int count = parent.getChildCount();
for (int i = 0; i < count; i++){
View view = parent.getChildAt(i);
if (TAG_COLOR.equals(view.getTag()) {
// handle color
} else if (TAG_ANIMAL.equals(view.getTag()) {
// handle animal
}
}
There are several ways to do this.
Use "id" to identify views. You can give different id to different views, and then it will be possible to identify them. See http://developer.android.com/reference/android/view/View.html#getId() (the API documentation of View.getId()) for more information.
Mark each view with different tags, and identify them through tags. See http://developer.android.com/reference/android/view/View.html#getTag() (the API documentation of View.getTag()) for more information.
If you want to customize more, just inherit default Android views, and use "instanceof" to identify them.
I have to create the Layout (in xml or in java) as like Below image :
But it should be repeated as per the Condition.
Suppose, if the Arraylist.size() is more then 2 then the whole layout should be repeated as such time.
is it possible?
if yes then let me know how it is possible.
I want to create such layout in verticle direction of the linear layout.
Thanks.
Edited:
with jin35 answer i have done like this:
private void doCalculationForMultipleEmployee() {
singleEmployee.setVisibility(View.GONE);
for (int i = 0; i<=tempEmployerList.size()-1; i++) {
View repeatedLayout = LayoutInflater.from(getApplicationContext()).inflate(R.layout.test);
((TextView)repeatedLayout.findViewById(R.id.list_title)).setText("Employee"+i);
// customize repeatedLayout with other data
myLinearLayout.addChild(repeatedLayout);
}
}
But i got syntex error at .inflate and at .addChild
Please help me for that.
Whats wrong with that ?
You should create xml file with LinearLayout and another xml with you "repeating" layout. Then in code for every part of data just use this:
for (Employee e : employeeList) {
View repeatedLayout = LayoutInflater.from(context).inflate(R.your_repeated_layout);
((TextView)repeatedLayout.findViewById(R.id.employee_salary)).setText(e.getSalary())
// customize repeatedLayout with other data
yourLinearLayout.addChild(repeatedLayout);
}
why dont you try scroll view and embedd image and text view inside and link onCreate() using views methods (Layout onMeasure) : http://developer.android.com/reference/android/view/View.html
i have a row of buttins created like this
i want to change the background colour at runtime in code.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout track1 = (LinearLayout)findViewById(R.id.my_toggle_container);
for (int i = 0; i<32; i++) {
ToggleButton tgl = new ToggleButton(this);
tgl.setId(i);
...
track1.addView(tgl);
this names the id of the togglebuttons 1, 2, 3... (i presume?)
i have an int variable called 'xBtn' that changes 1, 2,..
this is how i get a reference to the button using xBtn
String buttonID = ""+xBtn;
int resID = getResources().getIdentifier(buttonID, "id", "com.thing");
//find the button
ToggleButton tb = (ToggleButton) findViewById(resID);
//change its colour
tb.setBackgroundColor(Color.BLUE);
it crashes on the setBackgroundColor line.
it may be obvious to someone whats wrong and thats what im hoping
any help would be totaly ace ta
thanks
main.xml
<LinearLayout android:layout_width="wrap_content" android:layout_height="match_parent" android:id="#+id/my_toggle_container" android:orientation="vertical">
The id of your togglebuttons is gonna be a number from 1 to 32... However, trying to find the toggle button by id will return null because simply instantiating a new toggle button and giving an id wont help you. findViewById looks in the parent view for a child view with the specified id. If you havent added that toggle button with that id to the view, then findViewById will return null. I am 99.99% sure even without looking at the log, that it crashes because you are calling setBackgroundColor on a null object.
In other words, the id that you set a view to is only relevant once the view is actually added to a parent view. In your case you are probably trying to add these toggle buttons to your main content view, in which case you need grab hold of that view that you used for setContentView and call addView on that view and pass in each new toggle button. Note that this will probably not look right unless you also specify layoutparams for the togglebuttons.
EDIT
If thats your entire main.xml, then you've got other issues. Post the full xml file. In any event, you still are going to have to do what I've said, which is to grab hold of the view or a child view of that view and then add the toggle buttons to it via addView (after giving the togglebuttons their proper ids). Once the button has been added, then you can find it. Note though that if you're gonna add the toggle buttons to a child view of your main view, then you'll likely have to grab hold of that child view and call findViewById on THAT.
For example, you can do a nested call like this. findViewById(1) <--- gets you the LinearLayout or whatever inside of your main content view, then once you have that you can call addView on it. So LinearLayout ll = (LinearLayout)findViewById(someNumber); ll.addView(tb);
Try to use the method setTag() , and then you can get all your ToggleButton by using : findViewByTag();
Perhaps tb is null? Could you check that out?
To expand on what LuxuryMode said... What gets an ID INTO your java is inflating it via setContentView and setting it as content. That's why it's ok to have overlapping (duplicate) IDs in different layouts. You can have #+id/submit_button in layout1.xml and in layout2.xml and the Activity will get you the object via findViewById(R.id.submit_button) based on which one you have loaded into setContentView() at any given moment.
So, we're all guessing that you're probably not setting the content view and hoping that the code will find your object in your non inflated XML, which it won't. Which would lead (as everyone has guessed) to you now dealing with a null object, which you obviously can't set a background color on.
I know it gets confusing cause you have the XML RIGHT THERE!!! But the reality is that the xml isn't "alive". It's just stuff for you to look at until you have tasked the Application with inflating it and converting all of it into Android objects of some kind. A lot of the time this is done mostly transparently to you, so, it's easy to forget that none of these things really exist.
It's very likely that tb is null, because findViewById() didn't go as you expected.
You can verify this by surrounding the erroneous line with try.. catch block:
try {
tb.setBackgroundColor(Color.BLUE);
} catch (Exception e){
}
and watch for the message of e. It's likely to be null pointer exception.
In fact, I think you should not use getResources().getIdentifier(buttonID, "id", "com.thing") in the first place. It seems to me that all these resources are continuously numbered in R file, thus you should simply get the first id (as an integer), and then increment on that.
That is, you should do things like:
// The following code is not tested; I just wrote it here on SO.
for (int resID = R.id.button1; resID <= 32; resID++) {
ToggleButton tb = (ToggleButton) findViewById(resID);
tb.setBackgroundColor(Color.BLUE);
}
this should make all 32 buttons blue.