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!
Related
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
I am attempting to set a Preference layout in code using setLayoutResource() . But this method requires an int id. I have a preset RelativeLayout that I want to pass as an argument, but I get an error saying Preference cannot be applied to RelativeLayout. I suspect it is because I am not passing an R.layout.id. I need this to work because I will addPreferences dynamically using instances of the same layout with different attribute setting. How can I make this work? Thank you. Sample code below.
rLay=(RelativeLayout)View.inflate(Context,R.layout.account_item, null);
nameView =(TextView) rLay.findViewById(R.id.account_name);
numberView =(TextView) rLay.findViewById(R.id.number_name);
pView = new Preference(Context);
pView.setLayoutResource(rLay); ///ERROR HAPPENS HERE///
If you use same layout with dynamically-changing data,
you can create AwesomePreference extends Preference,
then override onBindView(View) to changing TextView's text or something like that.
This is working like ListView's adapter#getView().
Also don't forget to call Preference#notifyChanged() if you changed bound data.
hope this will help.
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.
I'm fairly new to Java & Android, so I have little idea what I am doing.
My test program successfully creates view objects, so now I am trying to organize my code.
I want to make a separate class to manage my GUI, but it always fails.
Basic info about my gui class:
package horc.gui;
...
public class GUI{
private Context context;
From my main activity, I constructed that gui class with the app context.
gui=new GUI(getApplicationContext()); // gui is a var of type GUI, & this sets the context of the class
The problem is when I make/modify a view object that is in the class from outside, it throws an exception.
My main activity...
package horc.test;
...
GUI gui;
LinearLayout test=gui.newLinear("ff", "v"); // <-- this sets fill parent for width/height
// & vertical orientation of the vertical layout.
// Doesnt work for the reason stated above.
// I cannot manage any view objects from a separate class.
gui.lastText.setText("##########"); // <-- a variable in the class to hold the view object I am manipulating
setContentView(t);
...calls this class function:
public TextView newText(String text){
TextView test=new TextView(context);
lastLinear.addView(test);
return test;
}
I tested this similar body within the main activity & it worked fine. It only fails when I do anything from outside that gui class.
Is there a common issue that people run into when managing view objects in separate classes? I have absolutely no idea what I am doing at this point. Coming from C++, java seems like a nutty language. I cannot plan things the way I would in C++.
instead of
gui=new GUI(getApplicationContext());
try
gui=new GUI(MyActivity.this);
Please put your activity name instead of MyActivity
I want to have a class "Utils", that will have several methods used all over my code. For example, I have a top bar with a textview and two ImageButtons that must display different texts and icons on different activities.
I find myself writing stuff like this on every activity:
(TextView) topBarText = (TextView) findViewById(R.id.topBarText);
topBarText.setText(R.id.mytextForThisView);
I'd like to findViewById once in my whole app, and call a method setupTopBar(String text, R.id.iconForImageButton1, R.id.iconForImageButton2), or even pass the current Activity's id and let the method figure out what to show in the text and images.
I created the class Util, but it doesn't extend Activity. The problem is that if it doesn't, findViewById isn't accessible, so I can't use it.
What's the pattern to do something like this in Android?
Your helper methods should look like
public static void setTopBarText(Activity act, int textId){
(TextView) topBarText = (TextView)act.findViewById(R.id.topBarText);
topBarText.setText(textId);
}
Then you can do a static import from Activity and call
setTopBarText(this, R.id.mytextForThisView);
The Answer is not good for some situation.
This is my method:
In your Activity:
YouCustomClassObject.passView((View)findViewById(R.id.aview));
Using parameter passing can solve this kind of problem.