How would I go about adding clickable links开发者_Go百科 inside a ListView?
This is done using the autoLink attribute of a TextView. Took me some time to dig through the documentation so putting it here with an example in case someone else is looking for it:
Let us assume that you are binding your listview to a custom adapter. In that case, the following piece of code goes into your getView call:
Code:
textcontent.setText(Html.fromHtml(item.get_text()));
textcontent.setAutoLinkMask(Linkify.WEB_URLS);
Just put the link inside the text being passed to the setText call and you're done.
XML:
<TextView
android:id="@+id/txtview"
android:autoLink="web"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="put your link here"/>
Hope that helps...
If you have text that is already in HTML format, the best thing to do is the following:
TextView textcontent = (TextView) findViewById(...);
textcontent.setMovementMethod(LinkMovementMethod.getInstance());
String text = "<a href="http://www.stackoverflow.com">stackoverflow.com</a>";
textcontent.setText(Html.fromHtml(text));
This will cause any link tags to be clickable in your text view. Alternately, you could use android:autoLink="web"
as suggested by Legend, but this has the side-effect of a) linkifying urls that are not wrapped in anchor tags, and b) potentially missing urls or linkifying things that aren't urls. If you want the smarts of autoLink then you should use it, but if all you want is to linkify the tags that are already there, you're better off using setMovementMethod()
.
See this bug report for more details: http://code.google.com/p/android/issues/detail?id=2219
Hmm, it seems that adding textcontent.setMovementMethod(LinkMovementMethod.getInstance()); makes it so that the clicks on the textview's text parts are no longer passed through to the listview below.
I found a simple workaround under Issue 3414, Comment 27:
An easy way to work around this problem is to call "setDescendantFocusability(FOCUS_BLOCK_DESCENDANTS);" on the listView views as they are added. You'll be able to select rows, click on rows and click on child checkboxes and buttons.
It worked perfectly for me, although some casting was required:
View v;
((ViewGroup)v).setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
You need to set a function setOnItemClickListener() and inside it declare something like this:
Uri uri = Uri.parse( "http://www.google.com" );
startActivity( new Intent( Intent.ACTION_VIEW, uri ) );
The tricky part of listview is nothing within (for instance a TextView of a Button) is clickable!
Basically you need two string arrays:
- names that users see on the list_view;
- hyperlinks that you want to direct them to go.
In the array.xml:
<string-array name="search_provider_name_array">
<item>Google</item>
<item>Yahoo</item>
<item>Bing</item>
<item>Baidu</item>
</string-array>
<string-array name="search_provider_link_array">
<item>https://www.google.com</item>
<item>https://www.yahoo.com</item>
<item>https://www.bing.com</item>
<item>https://www.baidu.com</item>
</string-array>
In the layout_search_provider.xml it contains a list view:
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/lv_search"
android:dividerHeight="1dp"/>
In your activity:
public class SearchProvider implements AdapterView.OnItemClickListener {
private ListView lv_search;
private String[] names = getResources().getStringArray(R.array.search_provider_name_array);
private String[] links = getResources().getStringArray(R.array.search_provider_link_array);
//..
@Override
public View onCreateView(View v, String name, Context context, AttributeSet attrs) {
lv_search= (ListView) v.findViewById(R.id.lv_search);
ArrayAdapter sAdapter = new ArrayAdapter(getActivity(), android.R.layout.simple_list_item_1, names);
lv_search.setAdapter(sAdapter);
lv_search.setOnItemClickListener(this);
return v;
}
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
if(i<links.length){
Uri uri = Uri.parse(links[i]);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
}
}
When your list is dynamic, you can the following method(s) to update your listview.
- move the code in onCreateView() into onResume().
- sAdapter.notifyDataSetChanged();
精彩评论