Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ListView setOnItemClickListener Does Not Trigger When An Item Has a Link In It

I am working on integrating Twitter in an app and while all works as it should I am stumped on the setOnItemClickListener() not triggering when a ListView item has a link in it. It works just fine when an item does not have a link (URL) in it.

Clicking on the URL itself opens the web page in a Browser.

Please see the screenshots added as reference at the end of the post.

It is a custom ListView that employs a BaseAdapter. I am not sure which piece of code to put in but on being pointed to a code block that the folks here may need, I will add it immediately.

The idea behind needing to ignore the links (URLs) in an item is to provide a functionality that shows the tweet details when a user clicks on one. Something similar to what the Twitter Android app does.

So what do I do to make the setOnItemClickListener() ignore the links in items?

UPDATED:

Okay. SO I am not sure if it is relevant to the question, but, from a combination of a few solutions from SO which led me to the TweetLanes Open Source project, I have managed to get a few things working. But unfortunately, it doesn't address my primary question.

How do I make the setOnItemClickListener() ignore the links in an item so I can click it and show the details in another Activity and yet, when I click on a link, not trigger the setOnItemClickListener()? I keep getting partial solutions in every attempt I make. But at times, when I click on a link, the setOnItemClickListener() triggers too.

This is how it the flow looks at the moment:

enter image description here

In the top two screenshots, it works as it should. Not clicking on a link after all.

In the bottom two, however, when I click on the @ibnlive link, it shows the Profile for the user (@ibnlive). This part is derived from the TweetLanes source. The problem is, the click listener is also triggered. This is one of the solutions I am trying out. In this case, I have commented out the setOnItemClickListener() and am using a OnClickListener() on the TextView. This is the one method which has partial success so far.

like image 230
SSL Avatar asked Apr 17 '13 09:04

SSL


2 Answers

In order to support listItem's click events and supporting links inside records, you should set android:descendantFocusability="blocksDescendants" at the top-level layout of your list-record's xml.

like image 65
waqaslam Avatar answered Oct 05 '22 04:10

waqaslam


You probably want to take a look at babay's answer on ListView: TextView with LinkMovementMethod makes list item unclickable?

He presents a TextView that issues this problem basically by introducing a different LinkMovementMethod:

public static class LocalLinkMovementMethod extends LinkMovementMethod{
    static LocalLinkMovementMethod sInstance;


    public static LocalLinkMovementMethod getInstance() {
        if (sInstance == null)
            sInstance = new LocalLinkMovementMethod();

        return sInstance;
    }

    @Override
    public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
        int action = event.getAction();

        if (action == MotionEvent.ACTION_UP ||
                action == MotionEvent.ACTION_DOWN) {
            int x = (int) event.getX();
            int y = (int) event.getY();

            x -= widget.getTotalPaddingLeft();
            y -= widget.getTotalPaddingTop();

            x += widget.getScrollX();
            y += widget.getScrollY();

            Layout layout = widget.getLayout();
            int line = layout.getLineForVertical(y);
            int off = layout.getOffsetForHorizontal(line, x);

            ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);

            if (link.length != 0) {
                if (action == MotionEvent.ACTION_UP) {
                    link[0].onClick(widget);
                } else if (action == MotionEvent.ACTION_DOWN) {
                    Selection.setSelection(buffer,
                            buffer.getSpanStart(link[0]),
                            buffer.getSpanEnd(link[0]));
                }

                if (widget instanceof TextViewFixTouchConsume){
                    ((TextViewFixTouchConsume) widget).linkHit = true;
                }
                return true;
            } else {
                Selection.removeSelection(buffer);
                Touch.onTouchEvent(widget, buffer, event);
                return false;
            }
        }
        return Touch.onTouchEvent(widget, buffer, event);
    }
}

Solution NOT TESTED

Based on it, I advice you to fix the file TwitterLinkify.java (the function that sets the link movement) like this:

private static final void addLinkMovementMethod(TextView t) {
    MovementMethod m = t.getMovementMethod();

    if ((m == null) || !(m instanceof LocalLinkMovementMethod)) {
        if (t.getLinksClickable()) {
            t.setMovementMethod(LocalLinkMovementMethod.getInstance());
        }
    }
}

Thanks

like image 21
Sherif elKhatib Avatar answered Oct 05 '22 05:10

Sherif elKhatib