Why is this code giving me an error? - android

The following code gave me an error
public class SuperImage3Activity extends Activity
{
ImageView image1, image2;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
image1 = (ImageView)findViewById(R.drawable.sourceimage1); // error here
image2 = (ImageView)findViewById(R.drawable.sourceimage2); // error here
}
I indeed created a directory named drawable and placed sourceimage1.jpg and sourceimage2.jpg in the directory.
the recommendation given by Eclipse is,
"As of ADT 14, the resource fields (such as doraemon) are no longer constants when defined in library objects.
This is necessary to make library projects resuable without recompiling them.
One consequence of this is that you can no longer use the fields directinly in switch statements.
You must use an if-else chain instead
"

R.id.imageview1
R.id.imageview2
You have made Xml layout in res/layout from there you link your widgets or views or any other control or you can make your control dynamically. like this
ImageView imageView1=new ImageView(this);
imageView1.setImageResource(R.drawable.sourceimage1);

findViewById is used to find a view that is already part of the view you're calling the method on (usually an activity).
Basically the way it's done is: (in order)
First you design a layout (either in a XML layout file, or programmatically) which lists all your components and desired locations.
You allocate an id to the resource you're interested in (either using android:id="#+id/your_id_here" in your XML, or setId(XX) if your layout is done programmatically)
You set this layout to your activity or as a child of an existing component (usually with setContentView)
Now you can use findViewById using the identifier defined in 2.
findViewById is not used with a resource itself as a parameter (your drawable object).

Related

How to display several paragraphs of text in android studio

In the app I'm building, I'm hoping to have several different guides / tutorials that will each contain several paragraphs and hopefully pictures in them. Right now the only thing I would know to do is to have all of the different texts written out long form in my strings resource file. I would then need to have separate layouts and fragments for each tutorial.
Is there an easier way? Can I separate my strings resource file at least so that I don't have that one file completely bogged down? Could I maybe import the text from a separate file?
Yes, you can. you need to set text programmatically. You need only one layout for all of these same type information page.
Let's say you have
<TextView
android:id="#+id/text_view_id"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="#string/hello" />
You can get that text view from java activity like below and set the text you want..
public class MainActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView helloTextView = (TextView) findViewById(R.id.text_view_id);
helloTextView.setText(R.string.user_greeting);
}
}
you can do this setText process by adding a switch, if or any conditional checking process like below
switch(expression) {
case value :
helloTextView.setText(R.string.firstPageText);
break;
case value :
helloTextView.setText(R.string.secondPageText);
break; // optional
// You can have any number of case statements.
helloTextView.setText(R.string.defaultText);
// Statements
}
PS: I think you can use different text style while you creating resource text. You can follow this https://www.myandroidsolutions.com/2017/09/29/android-html-textview/#.W9pu1mgzaUk for it.

Get language translation in xml from external json file

As a part of an app that I am developing there is request that it has to download JSON file that contains language translation that needs to be used in app instead of strings.xml file that is commonly used because this way any translation in app can be changed by updating external JSON file on some web portal and it avoid the need to make new build every time you want to change language translation.
I've already done this, and everything is working fine in a following way:
For example If I have button in xml once the activity starts I can reference the button and set the it's text from JSON that I've downloaded at the startup.
btnLogin = (Button) v.findViewById(R.id.btnLogin);
// reads translation from json that is stored in external application directory
btnLogin.setText(ResourceManager.getString("btnLogin"));
But my question is is there any way that I can avoid setting this text always from activity, can I somehow do it from XML file where this button is defined?
<Button
android:id="#+id/btnLogin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="{ResourceManager.getString("btnLogin")}"/>
Is there any possibility that let's me call some function from xml and bind it's result to text attribute or is there any other way which avoids referencing all buttons/textviews and other controls from activity and setting text from there?
Have you tried overriding getResources() in you Application class and then
returning an extended version of Resources.
Ok, I tried this and it seemed to work for most of the resources in my xml file.
You may have to override this in more than one place. I just overrode it inside my Application class.
private MyResources resources;
#Override
public Resources getResources() {
if (resources == null) {
resources = new MyResources(super.getResources());
}
return resources;
}
class MyResources extends Resources {
public MyResources(Resources resource) {
super(resource.getAssets(), resource.getDisplayMetrics(), resource.getConfiguration());
}
public String getString(int resId) {
return "Bob"; // Use your ResourceManger here
}
}
This worked for me..

changing the layout of current activity

FrameLayout content = (FrameLayout) findViewById(android.R.id.content);
This gives me an error
error: cannot find symbol
FrameLayout rootLayout = (FrameLayout)findViewById(android.R.id.content);
^
symbol: method findViewById(int)
I have already imported the required R package
It seems like you are trying to access the layout of your current Activity from a different class. Instead of trying to find your FrameLayout in the different class, save the reference to the FrameLayout inside of your Activity, and pass the FrameLayout to your seperate class (the class where you are currently seeing this issue).
E.g.
Activity Class:
...
OtherObject myOtherObject = new OtherObject();
FrameLayout frameLayout = (FrameLayout) findViewById(R.id.my_frame_layout);
myOtherObject.doStuffWithFrameLayout(frameLayout);
...
OtherObject Class:
...
public void doStuffWithFrameLayout(FrameLayout frameLayout) {
//You can use the FrameLayout here and do stuff with it.
//You will likely also want to pass in a Context object if you want to
//create a LayoutInflater or do other Context-dependent stuff
}
...
Try: FrameLayout content = (FrameLayout) findViewById(R.id.content);
In case this does not work remove the import of yourPackage.R and hit the button 'fix imports' not sure the import you did is correct. I always get 2 different options.
You can just call setContentView() again, but keep in mind that this will invalidate all of your View references, so make sure that you initialize them again.
There's almost never a reason to do this, so I would suggest you look into using Fragments, and just swap out the Fragments instead.
To use android.R.id.content, you must import android.R, not yourAppPackage.R .
And to use multiple layouts within one activity, you have to use ViewFlipper or ViewAnimator (or call setContentView multiple times, but it's resource expensive if you have huge layouts).

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.

Android - Text Switcher

I'm trying to add a text switcher dynamically but I get the error:
The method setFactory(ViewSwitcher.ViewFactory) in the type ViewSwitcher is not applicable for the arguments...
Here's my code:
TextSwitcher ts = (TextSwitcher) new TextSwitcher(this);
ts.setFactory(this);
Animation in = AnimationUtils.loadAnimation(this,android.R.anim.fade_in);
Animation out = AnimationUtils.loadAnimation(this,android.R.anim.fade_out);
ts.setInAnimation(in);
ts.setOutAnimation(out);
The setFactory method expects a ViewSwitcher.ViewFactory type argument and not Activity (which I presume is your this.)
You have 3 options:
you can implement your own ViewSwitcher.ViewFactory. you can see an example here.
you can use ViewSwitcher.addView to dynamically add your child views
you can define the child views in your layout xml
Either one should work OK for you.
Your activity class needs to implement android.widget.ViewSwitcher.ViewFactory interface.

Categories

Resources