0

I generally use kotlin for android but my college wants me to use Java. So I created a new java project in android studio.

The problem is I don't want to cast the return value of findViewById() manually. Instead I want to pass EditText as type parameter which the function is not accepting as anticipated. I get the error :

/home/onkar/AndroidStudioProjects/MyApplication2/app/src/main/java/io/github/omkar76/myapplication/MainActivity.java:16: error: cannot find symbol
        Log.d("EDITTEXT", findViewById<EditText>(R.id.first_name).getText());
                          ^
  symbol:   variable findViewById
  location: class MainActivity

Why isn't this working? Why is method not found? I even checked source of AppCompatActivity and it does contain required method:

 @Override
    public <T extends View> T findViewById(@IdRes int id) {
        return getDelegate().findViewById(id);
    }

My Java code is :

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Log.d("EDITTEXT", findViewById<EditText>(R.id.first_name).getText());
    }
}

If I don't pass type argument EditText, findViewById returns View which then I need to manually cast. According to this post starting with api 26 you don't need to cast the returned value. I have API 30 SDK. So why this is not working. I am aware of workarounds like assigning return value to an EditText reference but my interest is in knowing why existig approach doesn't work.

Let me know if any other details are required. Please point out what I am doing wrong. Thanks!

Omkar76
  • 1,317
  • 1
  • 8
  • 22
  • Whats the issue with using `(EditText)findviewbyid`? or why do you want to cast the value when using `findviewbyid` while youre targeting an api of 30 ? – lyncx May 21 '21 at 06:36
  • @lyncx, as said in linked post with api 26 and higher you don't need to cast. So I don't want to use `(EditText)findviewbyid(R.id.first_name)`. Second, because `findViewById` is always returning `View` (not `EditText` as I want). Return value being `View`, I can't call `.getText()` which I want to. I want to know what's wrong with my code. – Omkar76 May 21 '21 at 06:43
  • edittext is a **view**. findviewby id returns a view that you have defined in your xml. Still dont get why it is necessary to pass a paramenter. View is a parent class of all views for example edittext – lyncx May 21 '21 at 06:59
  • @lyncx, In short "I can't call getText() on View instance" – Omkar76 May 21 '21 at 07:03

3 Answers3

2

I think you're confused with the syntax of java.

Here public <T extends View> T findViewById(@ResId int id) means :

return value cast to T, T is resolved with the left side of the assignment declaration before the equals sign. In the following example

Edittext x = view.findViewById(R.id.abc)

So here T get assigned as Edittext as Edittext is on the left side of the assignment declaration which then returns edittext as a view. Then you can call x to getstring. Hope this makes it clearer

lyncx
  • 680
  • 4
  • 8
  • 1
    Got it. Return type is inferred from reference it's assigned to. And there seems to be no way to explicitly pass type arguments as you can do in C++ or Kotlin. Thanks. – Omkar76 May 21 '21 at 07:23
  • For findViewById, yes – lyncx May 21 '21 at 07:43
1

Actually, Java has no such syntax as Kotlin for findViewById.

The Kotlin syntax:

findViewById<EditText>(R.id.first_name)

The equivalent in Java:

(EditText)findViewById(R.id.first_name);

So, you can do like this in java:

Log.d("EDITTEXT", ((EditText)findViewById(R.id.first_name)).getText().toString());

Note: You have to put toString() to convert from Editable to String explicitly in Java

Tareq Joy
  • 342
  • 3
  • 12
  • 1
    For future references to Omkar, if something works in Kotlin, but not in Java, it can be useful to decompile the Kotlin code to Java to see the differences in the languages. https://stackoverflow.com/questions/34957430/how-to-convert-a-kotlin-source-file-to-a-java-source-file – Håkon Schia May 21 '21 at 07:01
  • That's not casting syntax in kotlin either. It's just type argument to generic method `findViewById()`. If you are correct how we pass type argument to, for example, `new ArrayList` in java? – Omkar76 May 21 '21 at 07:14
0

The simplest way use a variable name

EditText editext = findViewById(R.id.first_name);

then you could use

 Log.d("EDITTEXT", editext.getText().toString());
Ganesh MB
  • 1,109
  • 2
  • 14
  • 27
  • I have mentioned in my post that I know about this workaround. I want to know why my code as is, not working. – Omkar76 May 21 '21 at 06:44
  • @Omkar76 Type parameter T has incompatible upper bounds: View and String. ```Log.d``` required ```String, String```. You can't return ```View```. – Ganesh MB May 21 '21 at 07:07