Android ListView - 在活动开始时添加HTML链接

时间:2015-10-06 19:33:01

标签: java android html listview

我有一个活动,显示html链接的列表视图,每个链接都存储在TextView中,用户可以通过指定名称和网址来添加和删除链接。每个链接都以HTML格式存储在listview中,如下所示,用户可以点击“google”一词来启动网络浏览器。

<a href='http://www.google.com'>google</a>

我已经尝试了几种方法来使链接执行此操作,包括XML文件中的android:autolink="web",以下方法是唯一有效的方法。但是,由于getChildAt方法返回null,因此我无法调用它,因为活动正在初始化(来自onCreate()或onStart())。

 TextView wantedView = (TextView) listView.getChildAt(i);
 wantedView.setText(Html.fromHtml(s));
 wantedView.setClickable(true);
 wantedView.setMovementMethod(LinkMovementMethod.getInstance());

但是,如果我设置了一个可调用此代码的可点击按钮,那么它可以正常工作,尽管向列表添加新链接会恢复格式化。

有人知道为什么我在初始化时无法访问TextView对象,还有其他方法可以做到这一点?我在下面发布了我的布局文件和listview启动代码。

simplerow.xml <TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rowTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:textSize="15sp"
android:visibility="visible"
android:autoLink=""
android:gravity="center">

listview.xml <ListView
    android:id="@+id/listView1"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent" />

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_test2);

    listView1 = (ListView) findViewById(R.id.listView1);

    items = new String[]{ "<a href='http://www.facebook.com'>facebook</a>",
            "<a href='http://www.google.com'>google</a>",
            "<a href='http://www.twitter.com'>twitter</a>" };

    list = new ArrayList<>();

    for(int i=0; i<items.length; i++) {
        list.add(items[i]);
    }

    adapter = new ArrayAdapter<String>(Test.this, R.layout.simplerow, list);
    listView1.setAdapter(adapter);
    makeLinksVisible();
}

private void makeLinksVisible() {
        int i = 0;
        TextView wantedView = (TextView) listView.getChildAt(i);

        while (wantedView != null) {
            String s = wantedView.getText().toString();
            wantedView.setText(Html.fromHtml(s));
            wantedView.setClickable(true);
            wantedView.setMovementMethod(LinkMovementMethod.getInstance());

            i++;
            wantedView = (TextView) listView.getChildAt(i);
     }
}

3 个答案:

答案 0 :(得分:0)

让您创建扩展ArrayAdapter<String>的类,然后覆盖getView(...)方法。在那里你必须有一个LayoutInflatter和一个引用单行的视图(简称为row)。这是执行row.setOnClickListener(new View.OnClickListener() {/*...*/}的最佳位置。如果您有大量的数据显示,请不要忘记创建一个持有者。

有关自定义ArrayAdapters的更多信息,例如here

答案 1 :(得分:0)

解决方案是从ArrayAdapter获取TextView,而不是ListView。因此,如果您使用的是ListActivity,则可以执行以下操作:

ListView listView = getListView();
ArrayAdapter arrayAdapter = listView.getAdapter();
FrameLayout frameLayout = (FrameLayout) arrayAdapter.getView(0, null, null);
TextView wantedView = (TextView) frameLayout.findViewById(R.id.your_text_view);
wantedView.setText(Html.fromHtml(s));
wantedView.setClickable(true);
wantedView.setMovementMethod(LinkMovementMethod.getInstance());

这段代码当然假设使用了FrameLayout,但您只需将其替换为您尝试访问的TextView的任何父容器。然后在getView()方法中,您将传入TextView的位置(我仅使用零作为示例)。但是,如果您尝试在onCreate()中使用此代码,它应该可以正常运行。

答案 2 :(得分:0)

对于任何未来的观众,这里是问题的解决方案,以及我如何找到它的简要说明。

我尝试了drschultz解决方案并注意到没有变化。他评论说,使用带有字符串资源的textview可以正常工作。我尝试了这一点,并意识到需要传递列表视图跨越对象。

我找到了创建Spanned Listview的解决方案 - here - 然后添加了一个onItemClickListener,它在提供的Textview对象上调用了setMovementMethod。

我意识到之前的解决方案不起作用,因为适配器的getview&#39;方法没有提供对listview对象的引用,而是提供了具有相同数据的副本(我认为)。覆盖onItemClick方法是获取对列表对象的引用的快速解决方案,它允许您直接操作它并执行任何您喜欢的操作。

我已添加了以下用于测试此解决方案的代码。它创建了两个html引用的列表。第一次单击textview会调用onItemClick方法,然后再单击一次会将您带到指定的网页。

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_test);

    String s = new String("<a href=\"http://www.facebook.com\">facebook</a>");
    Spanned sp = Html.fromHtml(s);
    String s1 = new String("<a href=\"http://www.google.com\">google</a>");
    Spanned sp1 = Html.fromHtml(s1);

    listValues = new ArrayList<>();
    listValues.add(sp);
    listValues.add(sp1);
    setListAdapter(new SpannedAdapter(this, listValues));

    ListView l = getListView();
    l.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
            try {
                LinearLayout linearLayout = (LinearLayout) view;
                TextView wantedView = (TextView) linearLayout.findViewById(R.id.rowTextView);
                wantedView.setClickable(true);
                wantedView.setMovementMethod(LinkMovementMethod.getInstance());
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    });

}