My mistake causing the problem was in the XML defining the custom row's layout where I typed a <View> tag rather than a <view> tag. That capital 'V' was a mistake I was Very glad to find. I'll certainly be extra careful when typing future XML layout definitions.
- Greg On Jul 29, 2:17 pm, greg <[email protected]> wrote: > Thanks Jack, > > Constraining the problem to a TextView rather than the whole row view > is a good idea, but the apparent cast problem has now moved to > holder.text = (MyUnderlinedTextView) convertView.findViewById > (R.id.text); And, changing the definition of the ViewHolder from > > static class ViewHolder { > TextView text; > ImageView icon; > } > > to > > static class ViewHolder { > MyUnderlinedTextView text; > ImageView icon; > } > > did not get rid of the apparent cast problem. Here's the current code > and stack trace. This evening I'll try changing the row's layout so > it references a MyUnderlinedTextView rather than a TextView. However > I was hoping that the seemingly simple addition of underlining > wouldn't require modification to the layout. > > - - - > > /* > * Copyright (C) 2008 The Android Open Source Project > * > * Licensed under the Apache License, Version 2.0 (the "License"); > * you may not use this file except in compliance with the License. > * You may obtain a copy of the License at > * > * http://www.apache.org/licenses/LICENSE-2.0 > * > * Unless required by applicable law or agreed to in writing, software > * distributed under the License is distributed on an "AS IS" BASIS, > * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or > implied. > * See the License for the specific language governing permissions and > * limitations under the License. > */ > > package com.example.android.apis.view; > > import android.app.ListActivity; > import android.content.Context; > import android.graphics.Bitmap; > import android.graphics.BitmapFactory; > import android.graphics.Canvas; > import android.os.Bundle; > import android.util.AttributeSet; > import android.view.LayoutInflater; > import android.view.View; > import android.view.ViewGroup; > import android.widget.BaseAdapter; > import android.widget.ImageView; > import android.widget.TextView; > > /** > * Demonstrates how to write an efficient list adapter. The adapter > used in this example binds > * to an ImageView and to a TextView for each row in the list. > * > * To work efficiently the adapter implemented here uses two > techniques: > * - It reuses the convertView passed to getView() to avoid inflating > View when it is not necessary > * - It uses the ViewHolder pattern to avoid calling findViewById() > when it is not necessary > * > * The ViewHolder pattern consists in storing a data structure in the > tag of the view returned by > * getView(). This data structures contains references to the views we > want to bind data to, thus > * avoiding calls to findViewById() every time getView() is invoked. > */ > public class List14 extends ListActivity { > > private static class MyUnderlinedTextView extends TextView { > public MyUnderlinedTextView(Context context) { > super(context); > } > public MyUnderlinedTextView(Context context, AttributeSet as) > { > super(context, as); > } > public MyUnderlinedTextView(Context context, AttributeSet as, > int i) > { > super(context, as, i); > } > @Override > protected void onDraw(Canvascanvas){ > super.onDraw(canvas); > > // Would like to do some line drawing here (e.g., underlining > portions of text) > } > } > > private static class EfficientAdapter extends BaseAdapter { > private LayoutInflater mInflater; > private Bitmap mIcon1; > private Bitmap mIcon2; > > public EfficientAdapter(Context context) { > // Cache the LayoutInflate to avoid asking for a new one > each time. > mInflater = LayoutInflater.from(context); > > // Icons bound to the rows. > mIcon1 = BitmapFactory.decodeResource(context.getResources > (), R.drawable.icon48x48_1); > mIcon2 = BitmapFactory.decodeResource(context.getResources > (), R.drawable.icon48x48_2); > } > > /** > * The number of items in the list is determined by the number > of speeches > * in our array. > * > * @see android.widget.ListAdapter#getCount() > */ > public int getCount() { > return DATA.length; > } > > /** > * Since the data comes from an array, just returning the > index is > * sufficent to get at the data. If we were using a more > complex data > * structure, we would return whatever object represents one > row in the > * list. > * > * @see android.widget.ListAdapter#getItem(int) > */ > public Object getItem(int position) { > return position; > } > > /** > * Use the array index as a unique id. > * > * @see android.widget.ListAdapter#getItemId(int) > */ > public long getItemId(int position) { > return position; > } > > /** > * Make a view to hold each row. > * > * @see android.widget.ListAdapter#getView(int, > android.view.View, > * android.view.ViewGroup) > */ > public View getView(int position, View convertView, ViewGroup > parent) { > // A ViewHolder keeps references to children views to > avoid unneccessary calls > // to findViewById() on each row. > ViewHolder holder; > > // When convertView is not null, we can reuse it directly, > there is no need > // to reinflate it. We only inflate a new View when the > convertView supplied > // byListViewis null. > if (convertView == null) { > convertView = mInflater.inflate > (R.layout.list_item_icon_text, null); > > // Creates a ViewHolder and store references to the > two children views > // we want to bind data to. > holder = new ViewHolder(); > holder.text = (MyUnderlinedTextView) > convertView.findViewById(R.id.text); > holder.icon = (ImageView) convertView.findViewById > (R.id.icon); > > convertView.setTag(holder); > } else { > // Get the ViewHolder back to get fast access to the > TextView > // and the ImageView. > holder = (ViewHolder) convertView.getTag(); > } > > // Bind the data efficiently with the holder. > holder.text.setText(DATA[position]); > holder.icon.setImageBitmap((position & 1) == 1 ? mIcon1 : > mIcon2); > > return convertView; > } > > static class ViewHolder { > MyUnderlinedTextView text; > ImageView icon; > } > } > > @Override > public void onCreate(Bundle savedInstanceState) { > super.onCreate(savedInstanceState); > setListAdapter(new EfficientAdapter(this)); > } > > private static final String[] DATA = { > "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", > "Abondance", "Ackawi", "Acorn", "Adelost", "Affidelice au > Chablis", > "Afuega'l Pitu", "Airag", "Airedale", "Aisy Cendre", > " ... ", > "Zanetti Grana Padano", "Zanetti Parmigiano Reggiano"}; > > } > > - - - > > D/AndroidRuntime( 721): Shutting down VM > > W/dalvikvm( 721): threadid=3: thread exiting with uncaught exception > (group=0x4000fe70) > > E/AndroidRuntime( 721): Uncaught handler: thread main exiting due to > uncaught exception > > E/AndroidRuntime( 721): java.lang.ClassCastException: > android.widget.TextView > > E/AndroidRuntime( 721): at > com.example.android.apis.view.List14$EfficientAdapter.getView > (List14.java:130) > > E/AndroidRuntime( 721): at android.widget.AbsListView.obtainView > (AbsListView.java:1269) > > E/AndroidRuntime( 721): at android.widget.ListView.makeAndAddView > (ListView.java:1623) > > E/AndroidRuntime( 721): at android.widget.ListView.fillDown > (ListView.java:607) > > E/AndroidRuntime( 721): at android.widget.ListView.fillFromTop > (ListView.java:664) > > E/AndroidRuntime( 721): at android.widget.ListView.layoutChildren > (ListView.java:1481) > > E/AndroidRuntime( 721): at android.widget.AbsListView.onLayout > (AbsListView.java:1113) > > E/AndroidRuntime( 721): at android.view.View.layout(View.java:6133) > > E/AndroidRuntime( 721): at android.widget.FrameLayout.onLayout > (FrameLayout.java:333) > > E/AndroidRuntime( 721): at android.view.View.layout(View.java:6133) > > E/AndroidRuntime( 721): at android.widget.LinearLayout.setChildFrame > (LinearLayout.java:1119) > > E/AndroidRuntime( 721): at android.widget.LinearLayout.layoutVertical > (LinearLayout.java:998) > > E/AndroidRuntime( 721): at android.widget.LinearLayout.onLayout > (LinearLayout.java:918) > > E/AndroidRuntime( 721): at android.view.View.layout(View.java:6133) > > E/AndroidRuntime( 721): at android.widget.FrameLayout.onLayout > (FrameLayout.java:333) > > E/AndroidRuntime( 721): at android.view.View.layout(View.java:6133) > > E/AndroidRuntime( 721): at android.view.ViewRoot.performTraversals > (ViewRoot.java:929) > > E/AndroidRuntime( 721): at android.view.ViewRoot.handleMessage > (ViewRoot.java:1482) > > E/AndroidRuntime( 721): at android.os.Handler.dispatchMessage > (Handler.java:99) > > E/AndroidRuntime( 721): at android.os.Looper.loop(Looper.java:123) > > E/AndroidRuntime( 721): at android.app.ActivityThread.main > (ActivityThread.java:3948) > > E/AndroidRuntime( 721): at java.lang.reflect.Method.invokeNative > (Native Method) > > E/AndroidRuntime( 721): at java.lang.reflect.Method.invoke > (Method.java:521) > > E/AndroidRuntime( 721): at com.android.internal.os.ZygoteInit > $MethodAndArgsCaller.run(ZygoteInit.java:782) > > E/AndroidRuntime( 721): at com.android.internal.os.ZygoteInit.main > (ZygoteInit.java:540) > > E/AndroidRuntime( 721): at dalvik.system.NativeStart.main(Native > Method) > > I/Process ( 564): Sending signal. PID: 721 SIG: 3 > > - - - > > Thanks again and best regards, > Greg > > On Jul 29, 11:55 am, Jack Ha <[email protected]> wrote: > > > Don't do this: > > ... > > read more » --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/android-developers?hl=en -~----------~----~----~----~------~----~------~--~---

