Leanback GuidedStepFragment: How to get view of an action at startup - android

I have a GuidedStepFragment and I want to get view of one its actions (which is editable),cast it to EditText and hence set some of its parameters like TextColor programmatically.
So I should put this code at somewhere in the code:
View v0 = getActionItemView(0);
View v1 = v0.findViewById(R.id.guidedactions_item_title);
final GuidedActionEditText v2 = (GuidedActionEditText) v1;
v2.setTextColor(Color.RED);
I tried OnCreate , OnCreateView , ...(very trials actually) and each time I am facing to a NullPointerException saying the getActionItemView are returning Null!
At which function should I put this snippet to satisfy my need (i.e. change text color at fragment startup)?

I found the solution
Just putted above code at onGuidedActionFocused method !

Related

findViewById doesn't seem to return correct view type?

Since we don't have to cast anymore, I expected findViewById to return the correct type, but it doesn't seem to do that. I'm obviously making a very simple mistake here, can you point it out?
I have a TextView's ID (since I created it dynamically) and want to change the text size of that item, this snippet works fine:
TextView tmpView = findViewById(chain.getIngredientNameId());
tmpView.setTextSize(8);
But this one doesn't:
findViewById(chain.getIngredientNameId()).setTextSize(8);
So I assume I have to case it to TextView but none of my attempts seems to work (using () or <>), what obvious thing am I missing?
You should cast it if do not save to variable.
TextView tmpView = findViewById(chain.getIngredientNameId()); //TextVeiw
((TextView) findViewById(chain.getIngredientNameId())).setTextSize(8); // TextVeiw
findViewById(chain.getIngredientNameId()); // View

Automatically/dynamically update TextView text in Android

I have an android app that I have decided to rewrite, one of the reasons for the rewrite is because I could have 10+ TextViews with text set based on a variable in a class e.g.:
MyClass myClass = new MyClass();
myClass.myNumber = 5; // inside MyClass - public int myNumber;
LinearLayout mainLayout = (LinearLayout) view.findViewById(R.id.mainLayout);
TextView myTextView = new TextView(getActivity()); //In a fragment
myTextView.setText(String.format("myNumber currently has a value of %d", myClass.myNumber));
mainLayout.addView(myTextView);
return view;
Up until now I have been using .setOnClickListener on the buttons/views that change myNumber, to set the text of the view again when the value of myNumber changes, which then calls .invalidate() to redraw the TextView, this has worked fine, but I use this method very heavily and code is getting quite repetitive and changing one integer can affect quite a lot of views (all of which use it differently - such as different wording, or a calculation (e.g. myNumber * 2)). I guess it's because it's made an immutable string in the TextView.
I have tried to create a custom TextView that implements Observer (making MyClass extend Observable) and in the update method I can get it to invalidate itself for the refresh, but it still has the same text. I have also tried creating single element arrays, in an attempt to pass the reference not the value in the hope that when it is changed and then the view is invalidated it will pick up the new value but the text still ends up remaining the same.
How can I get a TextView that will auto update when the value of myNumber has changed? Some sort of binding?
Bindroid works perfectly for this, just a note for users, using fragments the sample application is using this from an Activity so the bind method using Activity is called, so in the fragment I was using getActivity() which caused it to not work properly, digging around in the library I found a bind method that takes a View and passed in my view which gets inflated in the fragment and it works great!!! This is super easy to integrate btw it was just me not getting it!

Adding Custom ImageButton to layout in Android causes error

I will start by saying this, while I have some Java training, is my first foray into development for Android.
What I have done is created a custom ImageButton called MapCell that is basically an ImageButton that holds a few extra pieces of information, and it compiles fine.
My problem comes when I want to procedurally create a MapCell in the relevant Activity and add it to my TableLayout which is defined in the xml and has the id 'mapTable'. The relevant bit looks like this:
Random randy = new Random();
MapCell n = new MapCell(randy.nextInt(4), this); //the random number is part of my extra info
findViewById(R.id.mapTable).addView((View)n, 20, 20); //add cell to display
I get one error out of that:
The method addView(View, int, int) is undefined for the type View
Which to me sounds like utter nonsense. I put that View cast in there as desperation after I got this same error with n sitting by itself and nothing changed (Obviously my MapCell is already a View since it extends ImageButton).
I hope a new pair of eyes can tell me what this is about, since I've checked for similar problems and I didn't find any quite like this. Let me now if you need to see more code.
The method findViewById returns a View and the View class doesn't have the method addView(this method is implemented in the ViewGroup and its subclasses). Instead you should write:
((TableLayout)findViewById(R.id.mapTable)).addView(n, 20, 20);
I've cast the return of the findViewById method in a class that actually has the addView method.
You got this problem because method findViewById(R.id.mapTable) returns View object.
In android you can't add one View to another.
You can use addView function with ViewGroup, and all LinearLayout (etc.) objects.

android setBackgroundColor in runtime and other general confusion help?

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.

TextView.setText() followed by TextView.invalidate() doesn't update text in view

I have no idea why this doesn't work. The TextView is defined from an tag in the view. The base TextView doesn't have text set and I want to set it in the View on display.
I have tried placing the below in onCreate and onStart but it doesn't seem to work. The last two lines are just for debugging. I can verify that the header does get the text. The thing is, the TextView doesn't actually get updated. Any ideas?
TextView header=(TextView) findViewById(R.id.acheader);
header.setText(R.string.accounts);
header.invalidate();
header=(TextView) findViewById(R.id.acheader);
String blah=(String) header.getText();
Try again removing the text in 4th line
header=(TextView) findViewById(R.id.acheader);
header.invalidate() is not needed.
Instead of String blah = (String) header.getText() try
String blah = heager.getText().toString();
And why are you verifying a "setText()" on text view using code? Why can't you check the
actual output?
The above code might not work the way you are trying to use it, because the redraw of text view is handled by the framework and generally it tries to group item updates (Dirty rectangles to be specific) and update them all at once. It may do it well after your function exits, Try to validate visually, thats the best way.

Categories

Resources