Don't do this:

    UnderlinedView underlinedView = (UnderlinedView) convertView;

Instead create your own MyUnderlinedTextView class by extending
TextView.

    holder.text = (MyUnderlinedTextView) convertView.findViewById
(R.id.text);


--
Jack Ha
Open Source Development Center
・T・ ・ ・Mobile・ stick together

The views, opinions and statements in this email are those of
the author solely in their individual capacity, and do not
necessarily represent those of T-Mobile USA, Inc.



On Jul 28, 7:54 pm, greg <[email protected]> wrote:
> When I try extending the View class to a subclass that will underline
> portions of the text drawn by ListView, the code compiles okay but
> results in a runtime exception apparently due to an improper class
> cast.  Does anyone see what I've done wrong or have suggestions about
> getting access to the Canvas of ListView items so portions of text can
> be underlined?
>
> Here is the code, which is the Efficient Adapter View/List example
> from ApiDemos with an added UnderlinedView class.
>
> - - -
>
> /*
>  * 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 UnderlinedView extends View {
>                 public UnderlinedView(Context context) {
>                         super(context);
>                 }
>                 public UnderlinedView(Context context, AttributeSet as) {
>                         super(context, as);
>                 }
>                 public UnderlinedView(Context context, AttributeSet as, int 
> i) {
>                         super(context, as, i);
>                 }
>             @Override
>             protected void onDraw(Canvas canvas) {
>                 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;
>             UnderlinedView underlinedView = (UnderlinedView)
> convertView;
>
>             // 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
>             // by ListView is null.
>             if (convertView == null) {
>                 convertView = mInflater.inflate
> (R.layout.list_item_icon_text, null);
>                 underlinedView = (UnderlinedView)convertView;
>
>                 // Creates a ViewHolder and store references to the
> two children views
>                 // we want to bind data to.
>                 holder = new ViewHolder();
>                 holder.text = (TextView) underlinedView.findViewById
> (R.id.text);
>                 holder.icon = (ImageView) underlinedView.findViewById
> (R.id.icon);
>
>                 underlinedView.setTag(holder);
>             } else {
>                 // Get the ViewHolder back to get fast access to the
> TextView
>                 // and the ImageView.
>                 holder = (ViewHolder) underlinedView.getTag();
>             }
>
>             // Bind the data efficiently with the holder.
>             holder.text.setText(DATA[position]);
>             holder.icon.setImageBitmap((position & 1) == 1 ? mIcon1 :
> mIcon2);
>
>             return underlinedView;
>         }
>
>         static class ViewHolder {
>             TextView 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",
>             "... a lot more strings are defined in original ApiDemos
> sample ...",
>             "Yarra Valley Pyramid", "Yorkshire Blue", "Zamorano",
>             "Zanetti Grana Padano", "Zanetti Parmigiano Reggiano"};
>
> }
>
> - - -
>
> The stack trace from logcat suggests a problem with the class cast in
> line 127, which is the cast after the row's XML inflation in getView:
>
>                 convertView = mInflater.inflate
> (R.layout.list_item_icon_text, null);
>                 underlinedView = (UnderlinedView)convertView;
>
> D/AndroidRuntime(  723): Shutting down VM
>
> W/dalvikvm(  723): threadid=3: thread exiting with uncaught exception
> (group=0x4000fe70)
>
> E/AndroidRuntime(  723): Uncaught handler: thread main exiting due to
> uncaught exception
>
> E/AndroidRuntime(  723): java.lang.ClassCastException:
> android.widget.LinearLayout
>
> E/AndroidRuntime(  723):        at
> com.example.android.apis.view.List14$EfficientAdapter.getView
> (List14.java:127)
>
> E/AndroidRuntime(  723):        at android.widget.AbsListView.obtainView
> (AbsListView.java:1269)
>
> E/AndroidRuntime(  723):        at android.widget.ListView.makeAndAddView
> (ListView.java:1623)
>
> E/AndroidRuntime(  723):        at android.widget.ListView.fillDown
> (ListView.java:607)
>
> E/AndroidRuntime(  723):        at android.widget.ListView.fillFromTop
> (ListView.java:664)
>
> E/AndroidRuntime(  723):        at android.widget.ListView.layoutChildren
> (ListView.java:1481)
>
> E/AndroidRuntime(  723):        at android.widget.AbsListView.onLayout
> (AbsListView.java:1113)
>
> E/AndroidRuntime(  723):        at android.view.View.layout(View.java:6133)
>
> E/AndroidRuntime(  723):        at android.widget.FrameLayout.onLayout
> (FrameLayout.java:333)
>
> E/AndroidRuntime(  723):        at android.view.View.layout(View.java:6133)
>
> E/AndroidRuntime(  723):        at android.widget.LinearLayout.setChildFrame
> (LinearLayout.java:1119)
>
> E/AndroidRuntime(  723):        at android.widget.LinearLayout.layoutVertical
> (LinearLayout.java:998)
>
> E/AndroidRuntime(  723):        at android.widget.LinearLayout.onLayout
> (LinearLayout.java:918)
>
> E/AndroidRuntime(  723):        at android.view.View.layout(View.java:6133)
>
> E/AndroidRuntime(  723):        at android.widget.FrameLayout.onLayout
> (FrameLayout.java:333)
>
> E/AndroidRuntime(  723):        at android.view.View.layout(View.java:6133)
>
> E/AndroidRuntime(  723):        at android.view.ViewRoot.performTraversals
> (ViewRoot.java:929)
>
> E/AndroidRuntime(  723):        at android.view.ViewRoot.handleMessage
> (ViewRoot.java:1482)
>
> E/AndroidRuntime(  723):        at android.os.Handler.dispatchMessage
> (Handler.java:99)
>
> E/AndroidRuntime(  723):        at android.os.Looper.loop(Looper.java:123)
>
> E/AndroidRuntime(  723):        at android.app.ActivityThread.main
> (ActivityThread.java:3948)
>
> E/AndroidRuntime(  723):        at java.lang.reflect.Method.invokeNative
> (Native Method)
>
> E/AndroidRuntime(  723):        at java.lang.reflect.Method.invoke
> (Method.java:521)
>
> E/AndroidRuntime(  723):        at com.android.internal.os.ZygoteInit
> $MethodAndArgsCaller.run(ZygoteInit.java:782)
>
> E/AndroidRuntime(  723):        at com.android.internal.os.ZygoteInit.main
> (ZygoteInit.java:540)
>
> E/AndroidRuntime(  723):        at dalvik.system.NativeStart.main(Native
> Method)
>
> I/Process (  564): Sending signal. PID: 723 SIG: 3
>
> - - -
>
> Initially I tried posting this question to the Android Beginners group
> (as I'm a Java novice), but got no responses.  Anyone here have any
> suggestions?
>
> Thanks and best regards,
> Greg
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to