android - 具有自动链接的 TextView 不允许捕获 TextView 的非超链接部分上的点击事件

标签 android listview

我的 Android 项目正在加载带有 Twitter feed 项的 ListView。我遇到的问题是让嵌入式超链接发挥作用,同时如果用户单击嵌入式超链接外部的 ListView 项目,仍然允许选择 ListView 项目。

假设 Twitter 提要项的文本是:

 This is a sample tweet with an embedded link (https://t.co/eMnVvBEo7W).  And this is some random text.

这部分有效。该链接是彩色的(显示它是一个超链接),当我单击 TextView 的链接部分时,它会正确启动浏览器和页面。

问题是 TextView 上的所有其他点击都不会通过。我需要能够获取 ListView 项目上的点击事件,以便我可以使用推文执行其他功能(例如共享等)。但是,正如我所说,没有点击事件发生。我想要的是,当用户选择推文的非超链接部分时,该项目就会被选中。

这里是一些代码 fragment

ListView 项目布局:

     <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="1256dp"
    android:layout_width="1256dp"
    android:layout_height="match_parent"
    android:descendantFocusability="blocksDescendants">

    <ImageView
        android:id="@+id/imageViewTwitterFeed"
        android:layout_width="64dp"
        android:layout_height="64dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:paddingTop="5dp"
        android:paddingBottom="5dp"
        android:paddingLeft="5dp"
        android:paddingRight="5dp" />

    <TextView
        android:id="@+id/textViewTwitterFeed"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="18dp"
        android:layout_marginStart="18dp"
        android:layout_toRightOf="@+id/imageViewTwitterFeed"
        android:layout_toEndOf="@+id/imageViewTwitterFeed"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:ellipsize="end"
        android:singleLine="false"
        android:autoLink="web"
        android:focusable="false"
        android:paddingTop="5dp"
        android:paddingBottom="5dp"/>

</RelativeLayout>

fragment 布局

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ListView
        android:id="@+id/tweetList"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:choiceMode="singleChoice"
        android:listSelector="#d3d3d3"/>

</LinearLayout>

fragment 代码:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    // Inflate view
    pageView = inflater.inflate(R.layout.page_twitter_feed_view_fragment, container, false);
    tweetsListView = (ListView) pageView.findViewById(R.id.tweetList);
    tweetsListView.setBackgroundColor(Color.WHITE);

    if(pageDefinition == null)
    {
        // Get page definition associated with this fragment
        if (getArguments().containsKey(MINPageDefinition.ARG_ITEM_ID))
        {
            pageDefinition = MINAppConfiguration.getSharedInstance().currentMarket.pageArray.get(Integer.valueOf(getArguments().getString(MINPageDefinition.ARG_ITEM_ID)));
        }
        // Provide a weak reference to this fragment for optimization purposes
        pageDefinition.weakFragment = new WeakReference<Fragment>(this);
    }

    // Set up specific controls/views
    initializePage();

    // Set up adapter & click listener
    adapter = new TwitterFeedAdapter(this, tweetStatusList);
    tweetsListView.setAdapter(adapter);
    tweetsListView.setOnItemClickListener(new AdapterView.OnItemClickListener()
    {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id)
        {
            twitter4j.Status tweetStatus = (twitter4j.Status)tweetStatusList.get(position);
            setTwitterShareIntent(tweetStatus);
        }
    });

    // Report to Flurry
    WeakHashMap<String, String> map = new WeakHashMap<String, String>();
    map.put(MINFlurryDefines.kFlurryKey_PageName, pageDefinition.pageName);
    FlurryAgent.logEvent(MINFlurryDefines.kFlurryEvent_PageView + " - " + pageDefinition.pageName, map, true);

    return pageView;
}

编辑:

// Set up adapter & click listener
adapter = new TwitterFeedAdapter(this, tweetStatusList);
tweetsListView.setAdapter(adapter);
tweetsListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
tweetsListView.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
    @Override
    public void onItemClick(AdapterView<?> parent, View view, final int position, long id)
    {
        twitter4j.Status tweetStatus = (twitter4j.Status)tweetStatusList.get(position);
        setTwitterShareIntent(tweetStatus);

        // Show the item as selected
/*
        parent.requestFocusFromTouch();
        parent.setSelection(position);
        parent.requestFocus();
 */
    }
});



final TextView tweetTextView = (TextView)V.findViewById(R.id.textViewTwitterFeed);

    tweetTextView.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            //tweetsListView.setSelection(position);
            //tweetsListView.smoothScrollToPosition(position);
            tweetsListView.performItemClick(v, position, 0);
        }
    });

    tweetTextView.setMovementMethod(new CustomLinkMovementMethod());
    tweetTextView.setFocusable(false);
    tweetTextView.setClickable(false);
    tweetTextView.setLongClickable(false);

最佳答案

    textView.setMovementMethod(new CustomLinkMovementMethod());
            textView.setFocusable(false);
            textView.setClickable(false);
            textView.setLongClickable(false);

    public class CustomLinkMovementMethod extends LinkMovementMethod {
    @Override
    public boolean onTouchEvent(TextView textView, 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 -= textView.getTotalPaddingLeft();
            y -= textView.getTotalPaddingTop();

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

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

            if (!(textView.getText() instanceof Spannable)) {
                return false;
            }

            Spannable spannable = ((Spannable) textView.getText());
            ClickableSpan[] link = spannable.getSpans(off, off, ClickableSpan.class);

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

                return true;
            } else {
                Selection.removeSelection(spannable);
            }
        }
        return false;
    }
}

关于android - 具有自动链接的 TextView 不允许捕获 TextView 的非超链接部分上的点击事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32592381/

相关文章:

ListView 中的 Wpf 组合框绑定(bind)

android - 使用 CollapsingToolbarLayout 时 ListView 不适合底部

android - android中的 ListView 选择颜色

android - 获得释放 key 后 map 未显示

java - Dimens 文件中定义的字体大小,在 Java 类中显示 3 倍值

android - 如何使用 `--multi-dex` 选项?

java - 安卓虚拟设备 : Accessing NanoHTTPD from hostsystem

android - 有没有办法防止 ListView 在其适配器的数据更改时滚动到其顶部位置?

Android点击按钮后刷新 ListView

android - 弹出窗口中的 ListView