Android Studio 'findViewById' no longer working - android

I am very new to Android/Kotlin. I have already created some programs and am making good progress.
But since today I have the problem that I can't get an 'findViewById' running even in the standard 'Hello World' program (Empty Activity).
I have only added the line android:id="#+id/myText" in the XML.
And in MainActivity.kt the line var myTxt = findViewById(android.R.id.myText).
But I get the error message Unresolved reference: 'myText'
The text 'myText' is red.
The usual attempts: Clear Cache, new project, ... I have already tried. The behavior is always the same.
In older projects 'findViewById' is working fine. But I find no difference in Import or settings between working and non working projects.
All in Android Studio 4.1.1
I am grateful for any help
Jan
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="#+id/myText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
package com.example.myhelloworld
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var myTxt = findViewById<TextView>(android.R.id.myText)
}
}

android.R.id.something is only used for android's own internal resources. You should remove that and it will work properly.

In kotlin you dont need to set findViewById instead you can just call the TextView name like this: myText.setText(userNameWithMsg)

android. was the problem! I removed it and all is fine again.
Thank you all! Must be a kind of copy paste error ;-))
Now I can go on .....
Great forum!
Thanks a lot
Jan

Related

Trying to Change src of an ImageButton in another layout folder other than activity_main

to sum up I am trying to change the src of ImageButtons inside my dialog_colors.xml file from MainActivity. However whatever I do I couldnt manage to change it. I tried the same code with ImageButtons inside my activity_main.xml but it doesnt work for buttons inside dialog_colors.xml file.
activity_main.xlm
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<include
android:id="#+id/dialog_colors"
layout="#layout/dialog_colors"/> ...
dialog_colors.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<LinearLayout
android:id="#+id/ll_paint_colors"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<ImageButton
android:id="#+id/red"
android:layout_width="40sp"
android:layout_height="40sp"
android:src="#drawable/pallet_normal"
android:background="#color/Red"
android:layout_margin="1sp"
android:tag="redTag"
android:clickable="true"
android:onClick="selectColor"
/>...
MainActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
colorDialog=findViewById<LinearLayout>(R.id.dialog_colors)
firstRowColors=colorDialog.findViewById<LinearLayout>(R.id.ll_paint_colors)
secondRowColors=colorDialog.findViewById<LinearLayout>(R.id.ll_paint_colors2)
drawingView=findViewById<DrawingView>(R.id.drawingView)
pressedColor=secondRowColors[0] as ImageButton
pressedColor!!.setImageResource(R.drawable.pallet_pressed)
}...
I tried the same thing with TextViews etc too. It seems like I cannot change anything inside the dialog_colors.xml file.
Do not get confused about the firstRows, secondRows etc, there are many ImageButtons, it doesnt work for any of them.
I found a solution to define an attribute in the MainActivity.kt through activity_main.xml to content_main.xml (included layout). The key word here is DataBinding. The project is completely reproducible and I provide first Kotlin and at the very end the JAVA files.
KOTLIN:
To enable DataBinding you need to go to your build.gradle(Module) and add following code:
//...
dataBinding{
enabled true
}
//...
You define a container called DrawableContainer as a Kotlin class. There you define a Drawable called customDrawable.
Thus DrawableContainer.kt:
import android.graphics.drawable.Drawable
data class DrawableContainer(val customDrawable: Drawable)
Now we will define our MainActivity.kt which will bind our chosen Drawable and pass it through our Container (DrawableContainer).
Our MainActivity.kt:
import android.app.Activity
import android.os.Bundle
import androidx.databinding.DataBindingUtil
import com.example.imagebuttonexperiment.databinding.ActivityMainBinding
class MainActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityMainBinding = DataBindingUtil.setContentView(
this, R.layout.activity_main)
binding.drawable = DrawableContainer(resources.getDrawable(R.drawable.my_image))
}
}
The missing parts are our XML files. The code below shows our content_main.xml. It contains a variable (in <data>) we will define named drawable. The type guides to our DrawableContainer. So this is the first bridge between our Container and our layout we will <include. In the ImageButton you can see that as android:src we refer over our variable to our Drawable in our Container. That's why android:src="#{drawable.customDrawable}".
Thus content_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="drawable"
type="com.example.imagebuttonexperiment.DrawableContainer" />
</data>
<ImageButton
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_margin="10dp"
android:src="#{drawable.customDrawable}"/>
</layout>
Now it's important to build our second bridge. Yet, we have DrawableContainer -> content_main. This will be the bridge content_main -> MainActivity. Therefor we have our <data/> and variable defined again. As you can see in <include we bind:drawable the exact same variable which is in both XML files.
The missing piece in our puzzle is the activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity">
<data>
<variable
name="drawable"
type="com.example.imagebuttonexperiment.DrawableContainer" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
android:id="#+id/include_content"
layout="#layout/content_main"
bind:drawable = "#{drawable}"/>
</LinearLayout>
</layout>
RESULT:
The final result is an ImageButton in the MainActivity that was included by another Layout. But the Drawable was chosen from the MainActivity and passed a Container to be shown in the included Layout. Magic isn't it!? ;)
JAVA:
And I will keep my word and provide you the JAVA version also.
The XML files and gradle will be the same, you only need to use MainActivity.java instead of MainActivity.kt, the same for DrawableContainer.java instead of DrawableContainer.kt.
Here is the same in green, DrawableContainer.java:
import android.graphics.drawable.Drawable;
public class DrawableContainer {
public final Drawable customDrawable;
public DrawableContainer(Drawable customDrawable) {
this.customDrawable = customDrawable;
}
}
And of course our MainActivity.java:
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import android.annotation.SuppressLint;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import com.example.imagebuttonexperiment.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding mainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
mainBinding.setDrawable(new DrawableContainer(getDrawable(R.drawable.my_image)));
}
}
DOWNLOAD PROJECT:
In addition I provide the project with both, JAVA and Kotlin classes in it. You just need to comment the content of the 2 classes grey you don't want. In example, if you want to use Kotlin, grey the content of .java files.
Github Project
Documentation & Tutorial:
Databinding Android Documentation
Youtube Tutorial: How to bind data?
NOTE: That's somewhat a solution of my problem:
I have tried this:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
colorDialog2=Dialog(this)
colorDialog2.setContentView(R.layout.dialog_colors)
colorDialog2.setTitle("Colors")
firstRowColors=colorDialog2.findViewById<LinearLayout>(R.id.ll_paint_colors)
secondRowColors=colorDialog2.findViewById<LinearLayout>(R.id.ll_paint_colors2)
drawingView=findViewById<DrawingView>(R.id.drawingView)
pressedColor= secondRowColors[0] as ImageButton
pressedColor!!.setImageResource(R.drawable.pallet_pressed)
}
intead of this in Main.Activity
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
colorDialog=findViewById<LinearLayout>(R.id.dialog_colors)
firstRowColors=colorDialog.findViewById<LinearLayout>(R.id.ll_paint_colors)
secondRowColors=colorDialog.findViewById<LinearLayout>(R.id.ll_paint_colors2)
drawingView=findViewById<DrawingView>(R.id.drawingView)
pressedColor=secondRowColors[0] as ImageButton
pressedColor!!.setImageResource(R.drawable.pallet_pressed)}
And it worked, I managed to change the src however I wanted. (Only did this change didnt do the changes that the others provided) However, I am not even sure if this is a good practice. It works as a quick fix for sure tho.
I will look into DEX7RA's answer more later on.

MainActivity.kt doesn't recognise button by ID

I'm struggling with very common problem, I think.
I've created a button in xml file and tagged it with ID. Then I wanted to make onClickListener in MainActivity.kt. But when I'm typing button's ID, it's marked red and it seems like Android Studio doesn't recognise it. I've tried cleaning and rebuilding project, but the problem still exist. Invalidate Caches/Restart didn't help as well.
Here's XML Code
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/backgroundColor"
android:fadingEdge="vertical"
android:fadingEdgeLength="80dp"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="16dp"
tools:context=".MainActivity"
tools:viewBindingIgnore="true">
<Button
android:id="#+id/btnDateBicker"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="25dp"
android:backgroundTint="#3D446C"
android:text="Select Date"
android:textSize="25sp"
android:textStyle="bold" />
</LinearLayout>
And here's kotlin code
package com.example.ageinminutes
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val mybtn = findViewById<btnDateBicker>()
}
}
If you simply want to fetch by id, use findViewById method.
val myBtn: Button = findViewById(R.id.btnDateBicker)
or
val myBtn = findViewById<Button>(R.id.btnDateBicker)
Another way to play with views in the kotlin file:
Try with synthetic binding, like just start writing few words of XML id in your kotlin file and android studio will attach that view for you. [Deprecated after Android 11]
Try with view binding or data binding, you just have to enable these settings in build.gradle file. [More Robust way]
Try this:
val mybtn = findViewById<Button>(R.id.btnDateBicker)

Toast.show() not showing the message in Emulator

This seems to work on Android 6 Marshmallow device Xiaomi Redmi 3S.
Seems like an emulator problem, but it isn't really misbehaving in any other sense.
I am a beginner in Android development and don't know much.
I have already confirmed that notifications for my app is ON.
Specs:
API Level : Android 4.4 (KitKat)
Android Studio version: 3.6.4
Emulator: Pixel XL API 28
All I attempted to do was a toast message would pop up telling how many times the button has been clicked.
Here's the MainActivity.kt:
class MainActivity : AppCompatActivity() {
private var greetingCount = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btnToastMessage.setOnClickListener {
val suffix = when (++greetingCount) {
1 -> "st"
2 -> "nd"
3 -> "rd"
else -> "th"
}
val greetingMsg = "Welcome for the $greetingCount$suffix time(s)!"
Toast.makeText(this#MainActivity, greetingMsg, Toast.LENGTH_LONG).show()
Log.i(".MainActivity", "Clicked Button")
}
}
}
And here's the activity_main.xml file:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:padding="30dp">
<TextView
android:id="#+id/txtHelloWorld"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.314" />
<Button
android:id="#+id/btnToastMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click Me!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.49"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/txtHelloWorld"
app:layout_constraintVertical_bias="0.49" />
</androidx.constraintlayout.widget.ConstraintLayout>
Didn't know this could be done, but wiping data and cold-booting the device fixed it.
Following are the steps you can follow (because I too got stuck):
Try restarting and cleaning your emulator device.
OR
You can run the app on your physical (android) device by setting the USB Debugging
option to True.

Why am I not seeing any lint error for hard coded text in android studio

While reading on Lint tool I tried to test it on a simple project in android studio. Just created a new project with empty activity. The xml for the mainActivity is as below:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
and Mainactivity.java :
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
From android studio when I try to run Analyze>>Inspect Code>> the whole project; it shows the following in inspection result: inspection result image
Shouldn't it also be showing the warning for hard-coded text("Hello World!") which is used for TextViews text?
As I wasn't getting the warning so I tried to change the severity level in settings>> editor>>Inspection as shown in this image. But still, the inspection result is the same. No warning or errors.
Where am I going wrong?
This happens because the string Hello World! is a special case:
if (value == "Hello World!") {
// This is the default text in new templates. Users are unlikely to
// leave this in, so let's not add warnings in the editor as their
// welcome to Android development greeting.
return
}
Found a reason which is weird. If I move the exclamation sign from the text("Hello World!") then it shows the error/warning. For some reason with the exclamation sign added to the text Lint doesn't show a warning for hardcoded text.

Beginner Android why is "id" is "Unknown member" with R.id?

I'm sure this is something dead simple as it's my first android app with code (the hello world example I did was just assigning a value to a string in XML). My problem is when trying to get the reference for my button in my variable then the id as in R.id is not defined?
The compiler error is in a comment in the code below where it occurs:
package com.geeksonhugs.simplecalc;
import android.app.*;
import android.os.*;
import android.view.*;
import android.widget.*;
public class MainActivity extends Activity
{
private Button AddButton;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
AddButton = (Button)findViewById(R.id.btnAdd);
//"Unknown member 'id' of 'com.geeksonhugs.simplecalc.R'"
//AddButton.setOnClickListener(this);
}
}
XML layout file:
<?xml version='1.0' encoding='utf-8' ?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LayoutRoot"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/txtFirstNum"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="#string/strFirstNum" />
<EditText
android:id="#+id/edtFirstNum"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="" />
<TextView
android:id="#+id/txtSecondNum"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="#string/strSecondNum" />
<EditText
android:id="#+id/edtSecondNum"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="" />
<Button
android:id="#+id/btnAdd"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="#string/strAdd"
android:gravity="center" />
<TextView
android:id="#+id/txtResult"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="" />
</LinearLayout>
I resolved the issue by deleting the bin folder and recompiling using the AIDE App.
The R class is code-generated for you by the Android build tools when you build your project. This means there are four possibilities:
You have not tried building the project yet, in which case, try that.
Eclipse doesn't think it needs to build the project for some reason -- try Project > Clean from the Eclipse menu (only relevant if you are using Eclipse, of course).
There is some bug in your manifest or one of your resources that is preventing R from being built. There should be Eclipse error indicators for this.
You do not have an android:id attribute in your layout, and therefore there is no R.id available.
Please make sure the xml file you pasted is called main.xml and under layout folder.
And try to generate the R file again.
That may help.
For those using AIDE having issues referencing Id, try deleting the "gen folder" located in the bin folder and recompile. The problem is the R.java class did not create a constructor called Id. So deleting the gen folder containing the R.java class and recompiling solves this issue.
You must add id to a component in the XML file. Like this:
android:id="#+id/buton1"
Now can you click mainActivity.java and write code "R.id." you a see hint to write "buton1" and no error of "id"

Categories

Resources