3

I'm having a slightly weird error here on my adapter. The view the adapter is creating is a thumbnail on the left side and a table with a few rows. Each row have two textviews.

One of the textviews have the android:autoLink="web" property set and the listview have an onItemClickListener on it.

the problem is that every time a TextView auto-links it's content, next time its parent view is converted, it doesn't receive clicks from the onItemClickListener anymore.

Let me clarify with an example:

  • view1, view2, view3 and view4 are on the list view on the screen.
  • view2 have a link and it appears, and onClick the link opens.
  • the item click works normally for view1, view 3 and view4.
  • scroll the listview and view1 is converted to position5 and then view2 is converted to position6.
  • the item at position6 does not contain a link, but the onItemClick is also not fired for the position6 element.

the autolink feature of the textview is certainly changing something with my layout, but I don't know what. There must a property I can reset for every call to getView on my adapter, but which?

thanks for any help.

edit

let's see some code, it's pretty standard/good practices. the getView from my adapter is: @Override public View getView(int position, View convertView, ViewGroup parent) {

    // Inflate a new layout if needed
    if (convertView == null)
        convertView = createNewView();

    // Gets the item from my array
    AGplus item = (AGplus) getItem(position);
    // Gets the holder pointing to the views
    Holder h = (Holder) convertView.getTag();
    // That's a test version, I won't be using date.toString() later on
    h.date.setText(new Date(item.getDate()).toString());
    // This guys is giving me a headache,
    // If it parses the link, I can't never click on this convertView anymore,
    // event re-converting them for a text that does not contain links
    h.txt.setText(item.getTitle());


    // some image download stuff that doesn't matter for this code

    return convertView;
    }

that layouts used is a image and table and the amount of rows I inflate and insert on the table varies for each adapter. The table layout is a horizontal linear layout with a imageview and the table layout with some margin stuff and here is the row layout:

    <?xml version="1.0" encoding="utf-8"?>
    <TableRow xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:textColor="@color/text" />

        <TextView
            android:id="@+id/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:autoLink="web"
            android:text=""
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:textColor="@color/text" />

    </TableRow>

if I completely remove the android:autoLink="web" I get all the clicks, but as stated before, once a view gets "auto-linked" and then I recycle that view, I can't get clicks on that view again.

edit

and here is the layout inflation:

    private View createNewView() {

    // Instantiate view
    View v = getLayoutInflater().inflate(R.layout.expandable_child_view, null);
    TableLayout table = (TableLayout) v.findViewById(R.id.table);
    Holder h = new Holder();
    v.setTag(h);

    // Instantiate rows
    h.thumb = (ImageView) v.findViewById(R.id.img);
    h.date = (TextView) createNewRow(table, "Date: ");
    h.txt = (TextView) createNewRow(table, "Text: ");
    return v;
    }

    private View createNewRow(ViewGroup group, String title) {
    View row;
    row = getLayoutInflater().inflate(R.layout.item_table_row, null);
    ((TextView) row.findViewById(R.id.title)).setText(title);
    group.addView(row);
    return row.findViewById(R.id.text);
    }

and before someone else asks, that's the expandable_child_view layout:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_vertical" >

        <ImageView
            android:id="@+id/img"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="20dp"
            android:layout_marginLeft="40dp"
            android:layout_marginRight="5dp"
            android:layout_marginTop="20dp"
            android:src="@drawable/ic_launcher" />

        <TableLayout
            android:id="@+id/table"
            android:layout_width="match_parent"
            android:layout_height="match_parent" >
        </TableLayout>
    </LinearLayout>

as I said before, just a linear layout with a imageview and a table and a few margins.

Budius
  • 39,391
  • 16
  • 102
  • 144
  • The best way to clarify your question is by posting the appropriate code. – Sam Oct 12 '12 at 17:46
  • hi. It's your standard good-practice implementation of listview+adapter+loader. I'll edit the post now. – Budius Oct 15 '12 at 11:03
  • Show `createNewView()` also, since that's where the view is being created and set up. – Geobits Oct 15 '12 at 12:41
  • I didn't bother with those because it's simply inflating the layout and setting the Holder, but I'll update the it now. – Budius Oct 15 '12 at 12:43

2 Answers2

6

According to Romain Guy here, this is done by design to support trackball/dpad navigation. Comment 27 has a workaround to it, by setting descendant focusability on each listview item:

setDescendantFocusability(FOCUS_BLOCK_DESCENDANTS);

or

android:descendantFocusability="blocksDescendants"
Geobits
  • 22,218
  • 6
  • 59
  • 103
  • were you just waiting me to put a bounty to answer it? hehehe. Thanks, it works great. I updated on my current project and I'll go back to a personal project I did that had a drag-n-drop on a list view that one of the items (that was being recycled) missed some actions. (You may award your bounty in 22 hours), why is SO blocking if you already gave the right answer? – Budius Oct 15 '12 at 13:49
  • Nah, your original edit just bumped it to the top of the list for 'recent' questions. Glad it worked for you, though. About the bounty, I think they use a minimum 24-hour timer to prevent people from awarding it to the first answer that comes along, since a better one might appear soon afterward. – Geobits Oct 15 '12 at 13:51
  • thank you, works great. i had a textview as part of my listview item layout and it had android:autoLink="web" so end user can click on links. after adding your addition it all works now but before some items were not clickable. – j2emanue Jul 21 '13 at 20:16
0

I think I know what may be going on. When you do setText(), sometimes it'll wipe out a lot of stuff. You may have to use a ClickableSpan to put the link action back into the textview.

Joe Plante
  • 6,308
  • 2
  • 30
  • 23