This is my first app and I'm having some trouble.
When I run the app it crashes and I don't know how to fix this error.
public class MainActivity extends AppCompatActivity {\
TextView outputBottom = (TextView)findViewById(R.id.output);
}
public void play_the_big_lie(View view) {
the_big_lie.start();
outputBottom.setText("ObamaCare, the big lie");
}
String literal in setText cannot be translated
This is not an error and you can safely ignore it (unless you need translation in your app).
It is simply a notification by Android Studio that you should be using a string resource file instead of a hard-coded string.
If I had to guess at the source of the issue since you did not post the logcat, it is this.
You can't use findViewById before setContentView because there is no view to "find".
Please try something like the following code
public class MainActivity extends AppCompatActivity {
private TextView outputBottom;
protected void onCreate(Bundle b) {
super.onCreate(b);
setContentView(R.layout.activity_main);
outputBottom = (TextView)findViewById(R.id.output);
}
There are two issues here. First, you can't use findViewById until you have "created" things and have a view to find things with, so as the previous answer you want to separate them.
public class MainActivity extends AppCompatActivity {
private TextView outputBottom;
protected void onCreate(Bundle b) {
super.onCreate(b);
setContentView(R.layout.activity_main);
outputBottom = (TextView)findViewById(R.id.output);
}
...
}
To set text, it's better not to "hardcode" with a string in quotes, but to create a string file and ask for it, which will look more like this:
outputBottom.setText(R.string.my_words);
Here are the developer notes on strings.
If you're using Android Studio there are tutorials for how to make that happen.
You can ignore these warning by adding
lintOptions {
disable 'MissingTranslation'
}
to the gradle.build file.
Related
So I am curious if it is possible to change a TextView from another java class in Android.I know how to change it in the activity and have no issue doing that. But for reasons I am looking to pull out the UI changes into another file.
layout file
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Test UI"
android:textAlignment="center"
android:onClick="testUI"/>
<TextView
android:id="#+id/someText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="SomeText"
android:textAlignment="center"/>
Here would be the code that I would have in the main activity
SetSomeText setSomeText = new SetSomeText();
public void testUI(View v){
setSomeText.Something();
}
Then I would have a standard java class that would allow me to change the TextView
public class SetSomeText extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_someNewActivity);
}
public void Something(){
TextView someNewText = findViewById(R.id.someText);
someNewText.setText("Something");
}
}
This ends up giving me an illegal state exception. I know this is not a normal way to do this. Just curious if something like this can be done.
java.lang.IllegalStateException: Could not execute method for android:onClick
Maybe you could do something like this in the class
public void Something(TextView myView){
myView.setText("Something");
}
And you can use it in main
MyClass class = new MyClass();
TextView someNewText = findViewById(R.id.someText);
class.Something(someNewText);
Use interface to communicate between activity and java class.
Steps to achieve this using interface.
Implement the interface in your activity.
Pass the instance of the interface to the java class.
With the help of the instance you can call the method which is implemented in your activity.
If you want to communicate between 2 different activities. Use startActivityForResult and setResult methods.
You shouldn't create an object of type Activity by your self you should start a new activity by using Intents
Only the Activity that created the view can Access it using
findViewById(int); ... so calling it from another activity (in SomeThing() function) would return null
If you wanted to make changes in a view using another class then you can do something like this :
public class myAwesomeClass {
TextView tv;
public myAwesomeClass(TextView v){
this.tv = v;
}
public void doSomething(){
tv.setText("This would work with no errors");
}
}
//and In the Activity class
myAwesomeClass mAC;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_layout);
mAC = new myAwesomeClass(findViewById(R.id.someText));
}
public void testUI(View v){
mAC.doSomething();
}
sorry for the bad writing .. Im using my phone :)
I am beginner student in Java and android studio. I am trying to make a seekbar that gives both negative and positive values. I managed to make a seekbar as shown in the picture [1]: https://i.stack.imgur.com/tJZJN.png). However it start at 0 and finishes at 100. I would like it to start at -50 and finishes at 50. the code I have is right here. Hopfully someone can help .
thank you in advance.
Here is my code
public class MainActivity extends AppCompatActivity {
ArcSeekBar defaultSeekBar, seekBarBackground, gradientSeekBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
defaultSeekBar= (ArcSeekBar) findViewById (R.id.defaultSeekBar );
defaultSeekBar.setOnProgressChangedListener(new ProgressListener() {
#Override
public void invoke(int i) {
Log.d("VALUE",""+i);
}
});
}
}
Wouldn't that be setMin(x) and setMax(x) ? In addition to doing this programmatically you could also apply it within the layout itself.
Refer to (bookmark this site and always explore what APIs exist within the class you are using):
https://developer.android.com/reference/android/widget/AbsSeekBar?hl=en#setMax(int)
This question already has answers here:
Unfortunately MyApp has stopped. How can I solve this?
(23 answers)
Closed 2 years ago.
I am a novice Android Developer.
I have created a package-private class which extends Application, and contains the required code for specific functions. I basically want to display if the user-selected button is the correct choice or not, via a toast. Since I have to call this code for many activities, I just created a package-private class for it. However, on clicking the button, the app crashes. Please see the code given below for reference.
I cannot change the onClick method to non-static because if I do that, Android Studio shows an error, and if I change it to static, I am unable to use the method getApplicationContext(), because it is not accessible inside static blocks.
I think that using view.getContext() is causing the crash.
Is there any workaround, or a solution?
Your help would be greatly appreciated. Thanks :)
Here is the code for your reference.
activity.java:
public class activity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(functions.select);
functions.makeLayout(expression, buttons);
}
}
Here is the code which crashes the app.
functions.java:
class functions extends Application {
private static int idx;
public static View.OnClickListener select=new View.OnClickListener() {
#Override
public void onClick(View view) {
int selected_index=(int) view.getTag();
if(selected_index==idx)
{
Toast.makeText(view.getContext(), "Correct.", Toast.LENGTH_LONG).show();
((Button) view).setTextColor(Color.GREEN);
}
else
{
Toast.makeText(view.getContext(), "Wrong.", Toast.LENGTH_LONG).show();
((Button) view).setTextColor(Color.RED);
}
}
};
Okay, I figured out that it was not view.getContext() but the line int selected_index=(int) view.getTag(); which was causing the crash. I solved it first making it into a string and then int by using the following code:
String selected_index=view.getTag.toString();
int sidx=Integer.parseInt(selected_index);
I can't get the context of my activity for some reason. Note - It was working before but now Android Studio shows an error but does not stop my app compiling and running as expected. I've added my code further down but ultimately I think the problem is somewhere else because if I try to get the activity context in a new, empty activity, I get an error.
package com.example.myapp
public class TestActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
Context context = this; // Error here
}
}
The error is:
Incompatible types.
Required: android.content.Context
Found: com.example.myapp.TestActivity
This error only happens for this project. My searches for an answer have yielded no positive results. In fact I can't find anything on the exact issue I'm facing.
What I have tried to fix this:
this instead of MainActivity.this - same error as above
getApplicationContext() - cannot resolve method error
getActivity().getApplicationContext() - same error as #2
Clean & Rebuild project / Sync Project with Gradle Files
Restarting Android Studio
Android Studio versions 2.3.3 & 3.0 - same issue
I'm new to Android development so if you have a solution for me, please phrase it as simply as possible. Thanks in advance. Here is my code - I get the error in the onClick method where it says MainActivity.this:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Find the View that shows the Numbers category
TextView numbers = (TextView) findViewById(R.id.numbers);
// If View is present, set a click listener on that View
if(numbers != null) {
numbers.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent numbersIntent = new Intent(MainActivity.this, NumbersActivity.class);
startActivity(numbersIntent);
}
});
}
}
}
I found a solution and that was to add google() to my project's build.gradle file like so:
allprojects {
repositories {
jcenter()
google()
}
}
I also deleted the project and cloned it again so it could build from scratch. Not sure whether that helped or not.
I just noticed the fact that the method addPreferencesFromResource(int preferencesResId) is marked deprecated in Android's documentation (Reference Entry).
Unfortunately, no alternative method is provided in the method's description.
Which method should be used instead in order to connect a preferenceScreen.xml to the matching PreferenceActivity?
No alternative method is provided in the method's description because the preferred approach (as of API level 11) is to instantiate PreferenceFragment objects to load your preferences from a resource file. See the sample code here: PreferenceActivity
To add more information to the correct answer above, after reading an example from Android-er I found you can easily convert your preference activity into a preference fragment. If you have the following activity:
public class MyPreferenceActivity extends PreferenceActivity
{
#Override
protected void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.my_preference_screen);
}
}
The only changes you have to make is to create an internal fragment class, move the addPreferencesFromResources() into the fragment, and invoke the fragment from the activity, like this:
public class MyPreferenceActivity extends PreferenceActivity
{
#Override
protected void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction().replace(android.R.id.content, new MyPreferenceFragment()).commit();
}
public static class MyPreferenceFragment extends PreferenceFragment
{
#Override
public void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.my_preference_screen);
}
}
}
There may be other subtleties to making more complex preferences from fragments; if so, I hope someone notes them here.
#Garret Wilson Thank you so much! As a noob to android coding, I've been stuck with the preferences incompatibility issue for so many hours, and I find it so disappointing they deprecated the use of some methods/approaches for new ones that aren't supported by the older APIs thus having to resort to all sorts of workarounds to make your app work in a wide range of devices. It's really frustrating!
Your class is great, for it allows you to keep working in new APIs wih preferences the way it used to be, but it's not backward compatible. Since I'm trying to reach a wide range of devices I tinkered with it a bit to make it work in pre API 11 devices as well as in newer APIs:
import android.annotation.TargetApi;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment;
public class MyPrefsActivity extends PreferenceActivity
{
private static int prefs=R.xml.myprefs;
#Override
protected void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
try {
getClass().getMethod("getFragmentManager");
AddResourceApi11AndGreater();
} catch (NoSuchMethodException e) { //Api < 11
AddResourceApiLessThan11();
}
}
#SuppressWarnings("deprecation")
protected void AddResourceApiLessThan11()
{
addPreferencesFromResource(prefs);
}
#TargetApi(11)
protected void AddResourceApi11AndGreater()
{
getFragmentManager().beginTransaction().replace(android.R.id.content,
new PF()).commit();
}
#TargetApi(11)
public static class PF extends PreferenceFragment
{
#Override
public void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(MyPrefsActivity.prefs); //outer class
// private members seem to be visible for inner class, and
// making it static made things so much easier
}
}
}
Tested in two emulators (2.2 and 4.2) with success.
Why my code looks so crappy:
I'm a noob to android coding, and I'm not the greatest java fan.
In order to avoid the deprecated warning and to force Eclipse to allow me to compile I had to resort to annotations, but these seem to affect only classes or methods, so I had to move the code onto two new methods to take advantage of this.
I wouldn't like having to write my xml resource id twice anytime I copy&paste the class for a new PreferenceActivity, so I created a new variable to store this value.
I hope this will be useful to somebody else.
P.S.: Sorry for my opinionated views, but when you come new and find such handicaps, you can't help it but to get frustrated!
My approach is very close to Garret Wilson's (thanks, I voted you up ;)
In addition it provides downward compatibility with Android < 3.
I just recognized that my solution is even closer to the one by Kevin Remo. It's just a wee bit cleaner (as it does not rely on the "expection" antipattern).
public class MyPreferenceActivity extends PreferenceActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
onCreatePreferenceActivity();
} else {
onCreatePreferenceFragment();
}
}
/**
* Wraps legacy {#link #onCreate(Bundle)} code for Android < 3 (i.e. API lvl
* < 11).
*/
#SuppressWarnings("deprecation")
private void onCreatePreferenceActivity() {
addPreferencesFromResource(R.xml.preferences);
}
/**
* Wraps {#link #onCreate(Bundle)} code for Android >= 3 (i.e. API lvl >=
* 11).
*/
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void onCreatePreferenceFragment() {
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new MyPreferenceFragment ())
.commit();
}
}
For a "real" (but more complex) example see NusicPreferencesActivity and NusicPreferencesFragment.
Instead of exceptions, just use:
if (Build.VERSION.SDK_INT >= 11)
and use
#SuppressLint("NewApi")
to suppress the warnings.
Instead of using a PreferenceActivity to directly load preferences, use an AppCompatActivity or equivalent that loads a PreferenceFragmentCompat that loads your preferences. It's part of the support library (now Android Jetpack) and provides compatibility back to API 14.
In your build.gradle, add a dependency for the preference support library:
dependencies {
// ...
implementation "androidx.preference:preference:1.0.0-alpha1"
}
Note: We're going to assume you have your preferences XML already created.
For your activity, create a new activity class. If you're using material themes, you should extend an AppCompatActivity, but you can be flexible with this:
public class MyPreferencesActivity extends AppCompatActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_preferences_activity)
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container, MyPreferencesFragment())
.commitNow()
}
}
}
Now for the important part: create a fragment that loads your preferences from XML:
public class MyPreferencesFragment extends PreferenceFragmentCompat {
#Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.my_preferences_fragment); // Your preferences fragment
}
}
For more information, read the Android Developers docs for PreferenceFragmentCompat.