0

I am trying to initialize (or populate, if you prefer) two spinners on the same layout. I'm imitating code that I've seen in other examples and the initialization works okay in the debugger but sometime after the initialization - and before the layout with the spinners appears on my Android device (my phone) - the app crashes with a stacktrace that does NOT identify any line of code in my app. I'm trying to figure out where in my app the trouble lies. Here are the relevant lines from Logcat. I'm running Android Studio 3.1.3.

07-19 21:31:14.821 30262-30262/com.example.android.twlistsales E/ArrayAdapter: You must supply a resource ID for a TextView 07-19 21:31:14.822 30262-30262/com.example.android.twlistsales D/AndroidRuntime: Shutting down VM 07-19 21:31:14.838 30262-30262/com.example.android.twlistsales E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.android.twlistsales, PID: 30262 java.lang.IllegalStateException: ArrayAdapter requires the resource ID to be a TextView at android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java:401) at android.widget.ArrayAdapter.getView(ArrayAdapter.java:371) at android.widget.AbsSpinner.onMeasure(AbsSpinner.java:195) at android.widget.Spinner.onMeasure(Spinner.java:662) at android.support.v7.widget.AppCompatSpinner.onMeasure(AppCompatSpinner.java:420) at android.view.View.measure(View.java:21125) at android.support.constraint.ConstraintLayout.internalMeasureChildren(ConstraintLayout.java:1212) at android.support.constraint.ConstraintLayout.onMeasure(ConstraintLayout.java:1552) at android.view.View.measure(View.java:21125) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6461) at android.widget.FrameLayout.onMeasure(FrameLayout.java:185) at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:141) at android.view.View.measure(View.java:21125) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6461) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464) at android.widget.LinearLayout.measureVertical(LinearLayout.java:758) at android.widget.LinearLayout.onMeasure(LinearLayout.java:640) at android.view.View.measure(View.java:21125) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6461) at android.widget.FrameLayout.onMeasure(FrameLayout.java:185) at android.view.View.measure(View.java:21125) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6461) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464) at android.widget.LinearLayout.measureVertical(LinearLayout.java:758) at android.widget.LinearLayout.onMeasure(LinearLayout.java:640) at android.view.View.measure(View.java:21125) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6461) at android.widget.FrameLayout.onMeasure(FrameLayout.java:185) at com.android.internal.policy.DecorView.onMeasure(DecorView.java:896) at android.view.View.measure(View.java:21125) at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2612) at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1664) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1915) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1537) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7183) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:959) at android.view.Choreographer.doCallbacks(Choreographer.java:734) at android.view.Choreographer.doFrame(Choreographer.java:670) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:945) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6776) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1518) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408) Caused by: java.lang.ClassCastException: android.support.constraint.ConstraintLayout cannot be cast to android.widget.TextView at android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java:388) at android.widget.ArrayAdapter.getView(ArrayAdapter.java:371)  at android.widget.AbsSpinner.onMeasure(AbsSpinner.java:195)  at android.widget.Spinner.onMeasure(Spinner.java:662)  at android.support.v7.widget.AppCompatSpinner.onMeasure(AppCompatSpinner.java:420)  at android.view.View.measure(View.java:21125)  at android.support.constraint.ConstraintLayout.internalMeasureChildren(ConstraintLayout.java:1212)  at android.support.constraint.ConstraintLayout.onMeasure(ConstraintLayout.java:1552)  at android.view.View.measure(View.java:21125)  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6461)  at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)  at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:141)  at android.view.View.measure(View.java:21125)  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6461)  at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)  at android.widget.LinearLayout.measureVertical(LinearLayout.java:758)  at android.widget.LinearLayout.onMeasure(LinearLayout.java:640)  at android.view.View.measure(View.java:21125)  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6461)  at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)  at android.view.View.measure(View.java:21125)  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6461)  at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)  at android.widget.LinearLayout.measureVertical(LinearLayout.java:758)  at android.widget.LinearLayout.onMeasure(LinearLayout.java:640)  at android.view.View.measure(View.java:21125)  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6461)  at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)  at com.android.internal.policy.DecorView.onMeasure(DecorView.java:896)  at android.view.View.measure(View.java:21125)  at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2612)  at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1664)  at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1915)  at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1537)  at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7183)  at android.view.Choreographer$CallbackRecord.run(Choreographer.java:959)  at android.view.Choreographer.doCallbacks(Choreographer.java:734)  at android.view.Choreographer.doFrame(Choreographer.java:670)  at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:945)  at android.os.Handler.handleCallback(Handler.java:751)  at android.os.Handler.dispatchMessage(Handler.java:95)  at android.os.Looper.loop(Looper.java:154)  at android.app.ActivityThread.main(ActivityThread.java:6776)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1518)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)  Caused by: java.lang.ClassCastException: android.support.constraint.ConstraintLayout cannot be cast to android.widget.TextView at android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java:388) at android.widget.ArrayAdapter.getView(ArrayAdapter.java:371)  at android.widget.AbsSpinner.onMeasure(AbsSpinner.java:195)  at android.widget.Spinner.onMeasure(Spinner.java:662)  at android.support.v7.widget.AppCompatSpinner.onMeasure(AppCompatSpinner.java:420)  at android.view.View.measure(View.java:21125)  at android.support.constraint.ConstraintLayout.internalMeasureChildren(ConstraintLayout.java:1212)  at android.support.constraint.ConstraintLayout.onMeasure(ConstraintLayout.java:1552)  at android.view.View.measure(View.java:21125)  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6461)  at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)  at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:141)  at android.view.View.measure(View.java:21125)  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6461)  at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)  at android.widget.LinearLayout.measureVertical(LinearLayout.java:758)  at android.widget.LinearLayout.onMeasure(LinearLayout.java:640)  at android.view.View.measure(View.java:21125)  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6461)  at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)  at android.view.View.measure(View.java:21125)  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6461)  at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)  at android.widget.LinearLayout.measureVertical(LinearLayout.java:758)  at android.widget.LinearLayout.onMeasure(LinearLayout.java:640)  at android.view.View.measure(View.java:21125)  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6461)  at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)  at com.android.internal.policy.DecorView.onMeasure(DecorView.java:896)  at android.view.View.measure(View.java:21125)  at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2612)  at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1664)  at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1915)  at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1537)  at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7183)  at android.view.Choreographer$CallbackRecord.run(Choreographer.java:959)  at android.view.Choreographer.doCallbacks(Choreographer.java:734)  at android.view.Choreographer.doFrame(Choreographer.java:670)  at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:945)  at android.os.Handler.handleCallback(Handler.java:751)  at android.os.Handler.dispatchMessage(Handler.java:95)  at android.os.Looper.loop(Looper.java:154)  at android.app.ActivityThread.main(ActivityThread.java:6776)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1518)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408) 

[For some reason, it won't let me paste the last bit of the stacktrace here so I'm typing it:] Caused by: java.lang.ClassCastException: android.support.ConstraintLayout cannot be cast to android.widget.TextView at android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java:388) <42 more...> <1 internal call> <2 more...>

I'm guessing that if I could actually see the lines implied in the last bit of the stacktrace, it would enlighten me as to where I've made a mistake in my code but all it's given me is the Java code, which is not very helpful.

I'm inclined to think my spinner initialization code has caused some kind of issue within Java but all I'm seeing is that aspect of the problem and not getting any idea of where the problem is in MY code. How do I figure this out?

For what it's worth, here is my initialization code for both spinners:

    //Set up spinner for Client Code
    spClientCode = findViewById(R.id.client_spinner);
    //Create an array of client codes from the Client enum
    ArrayList<String> clientCodes = new ArrayList<>();
    for (Client client: Client.values()) {
        clientCodes.add(client.toString());
    }
    ArrayAdapter<String> clientAdapter = new ArrayAdapter(this, R.layout.activity_add_sale, clientCodes);

    clientAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spClientCode.setAdapter(clientAdapter);

    //Set up spinner for Seller
    spSellerName = findViewById(R.id.seller_spinner);
    //Create an array of seller names from the Seller enum
    ArrayList<String> sellers = new ArrayList<>();
    for (Seller seller: Seller.values()) {
        sellers.add(seller.toString());
    }
    ArrayAdapter<String> sellerAdapter = new ArrayAdapter(this, R.layout.activity_add_sale, sellers);

    sellerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spSellerName.setAdapter(sellerAdapter);
Henry
  • 1,395
  • 1
  • 12
  • 31
  • Search for the Exception message. As explained in the linked duplicate, the `R.layout` you're passing the `ArrayAdapter`s is not just a `TextView`, but apparently a `ConstraintLayout`. If that is the correct layout, you would need to add an `R.id` argument in the constructor call for the `TextView` within that layout. However, `R.layout.activity_add_sale` does not sound like a proper layout for `Spinner` items. Are you sure that's the right one? It sounds like it's for an `Activity`. – Mike M. Jul 20 '18 at 02:07
  • I'm very confused right now. I followed the advice in the linked duplicate and added R.id.client_spinner for the first spinner and R.id.seller_spinner for the second spinner to the constructors for ArrayAdapter but I'm still getting the same stacktrace and it is still insisting that it needs a TextView. This makes no sense to me. I'm trying to use the ArrayAdapter to populate *spinners* not TextViews. Why would I use an ArrayAdapter to populate a TextView?? And yes, my spinners are within a ConstraintLayout as you deduced. – Henry Jul 20 '18 at 16:18
  • The layout and `TextView` you pass to `ArrayAdapter` are for the individual items it creates, not the `Activity`'s layout, or any other `View` therein. `ArrayAdapter` doesn't care about the particular `AdapterView` – `Spinner`, in this case – or the layout the `AdapterView` is in. – Mike M. Jul 20 '18 at 17:07
  • Sorry, Mike, but I'm not following you, particularly this part: "The layout and TextView you pass to ArrayAdapter are for the individual items it creates". I am trying to put an array of strings into a GUI control that holds MULTIPLE items, commonly known as a spinner. A TextView can only hold ONE item, not an array of items. It makes no sense to me to put an array in a TextView but that seems to be what you're telling me to do. Have I got a fundamental concept wrong somewhere? – Henry Jul 20 '18 at 18:41
  • You're not quite grasping what the `ArrayAdapter` actually does. You give it a collection of data items – a `List` or array – and a general blueprint for how each item should look – the layout, and optional `TextView`, if the layout is more than just a simple `TextView`. Then, whenever your `Spinner` needs to display an individual item, it has the `ArrayAdapter` make one, and it does that by creating a new instance of that layout/`TextView`, and filling it with the data for a single item. It will do this multiple times, once for each data item in the `List`/array (if needed). – Mike M. Jul 20 '18 at 20:10
  • So the TextView is a sort of template that tells Android how the individual array items will look? For instance, that they are phone numbers or postal codes or just plain text? That makes sense. Am I supposed to create a TextView on my layout that describes what the spinner items is going to look like and let the ArrayAdapter constructor have that TextView so it knows how to format the array items? If so, can I assume that I never actually put anything in the TextView, i.e. that it never gets displayed, just used to format the strings? – Henry Jul 20 '18 at 20:54
  • You need to provide a separate layout with a `TextView`, either by itself, or inside some a more complex setup. It shouldn't be a part of a layout for something else, like your `Activity`. For `Spinner`s, a simple, single `TextView` is quite common. In fact, the system has one built in: `android.R.layout.simple_spinner_item`. Replace your `R.layout.activity_add_sale` in the `ArrayAdapter` constructor calls with that, and it'll fix the current issue. As mentioned, you would only need to use the optional `R.id` if the `TextView` is inside something else, which is not very common for `Spinner`s. – Mike M. Jul 20 '18 at 21:49
  • Now I'm starting to get it! Thanks very much Mike! General question: it's offering to take this discussion to chat. I don't think that's necessary *this time* but where can I find information on how chat works? It would be very handy to be able to have discussions about issues at times but I'm not sure how the chat here works. Would I specify that I want to start a chat with an Android expert and then get one in a short time? – Henry Jul 21 '18 at 01:47
  • No problem. It's just offering to start a chat room for this particular question. If you click that link, it should open a new tab for a chat room titled "Discussion between [user] and [user]". It will also leave a comment here so the other party knows a room is open. It does this when you hit a certain number of comments on a post, since comments really shouldn't be used for discussion. There's a minimum rep requirement to be able to chat, though. I'm not certain, but I think it's 20, or maybe 25. – Mike M. Jul 21 '18 at 01:54

0 Answers0