Android Display HTML in a ListView - android

Sorry if this is obvious to everyone else but I am having a minor difficulty understanding how to display html inside my listview.
My list view is declared.
ListView lv1 = (ListView) findViewById(R.id.ListView01);
I populate it (not shown) then set my listview here with an ArrayAdapter.
lv1.setAdapter(new ArrayAdapter<String>(SearchByFood.this, R.layout.new_list_view, foods));
Further down I create a new array of strings that I want to have bold tags in. I then add this new array (called arr_sort) to the arrayadapter insdie a onTextChanged() method.
lv1.setAdapter(new ArrayAdapter<String>(SearchByFood.this, R.layout.new_list_view, arr_sort));
So now that my new Array of Strings has < b > tags in it. How do I make my listview display the bold text?
Here is my new_list_view
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/text1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#color/grey2"
android:textSize="20sp"
android:gravity="center_vertical"
android:paddingLeft="6dip"
android:minHeight="40dip"
/>
And here is my ListView part in my main layout.
<ListView
android:id="#+id/ListView01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/rounded_corners_green"
android:cacheColorHint="#00000000"
android:divider="#color/green6"
android:dividerHeight="1px"
android:fastScrollEnabled="true" >
</ListView>
Any help would be much appreciated.

Ok, so Jitendra Sharma was had the right idea for my scenario, but I needed to override the getView method. Or at least that is what worked for me. Then in the getView method I was able to set my text to render in html.
ArrayAdapter<String> adapter = new ArrayAdapter<String>(SearchByFood.this, R.layout.new_list_view, arr_sort)
{
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
View row;
if (null == convertView) {
row = mInflater.inflate(R.layout.new_list_view, null);
} else {
row = convertView;
}
TextView tv = (TextView) row.findViewById(android.R.id.text1);
tv.setText(Html.fromHtml(getItem(position)));
//tv.setText(getItem(position));
return row;
}
};
lv1.setAdapter(adapter);

override getItem method of the Adapter and do the following:
ArrayAdapter<String> adapter= ArrayAdapter<String>(SearchByFood.this, R.layout.new_list_view, arr_sort){
public Object getItem(int position)
{
return Html.fromHtml(arr_sort.get(position));
}
};

If you are using a SimpleAdapter, here is the code that enables HTML on a TextView.
adapter.setViewBinder(new SimpleAdapter.ViewBinder() {
public boolean setViewValue(View view, Object data, String textRepresentation) {
if (data instanceof Spanned && view instanceof TextView) {
((TextView) view).setText((Spanned) data);
} else {
((TextView) view).setText(Html.fromHtml(String.valueOf(data)));
}
return true;
}
}
);
Ref: [Link] (http://android.jreactor.com/2012/07/17/simpleadapter-spanned-html-fromhtml/)

If all you wanted is to display some text where parts of the text should be bold, all you need is one TextView, and properly formatted text (with <b> added) and do the following:
textview.setText(Html.fromHtml(text));
For more information on what TextView+Html can support, see here

If you have the possibility of loading your texts from strings.xml, adding the tag there will automatically bold your text.
If however your texts are dynamic, you will have to create a custom adapter, and in it to set the text using textView.setText(Html.fromHtml(yourText));

ArrayAdapter<Spanned> listAdapter = new ArrayAdapter<Spanned>(MyActivity.this, R.layout.row);
listAdapter.add(Html.fromHtml(htmlText));
listAdapter.add(Html.fromHtml(htmlText));
...

if you use ksoap for html data from any database engine
yourVariable=String.valueOf(Html.fromHtml(ic.getProperty(0).toString()))

adapter = new ArrayAdapter<String>(rr.getContext(),android.R.layout.simple_list_item_1,titulos)
{
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
View row;
if (null == convertView) {
row = getLayoutInflater().inflate(android.R.layout.simple_list_item_1, null);
} else {
row = convertView;
}
TextView tv = (TextView) row.findViewById(android.R.id.text1);
tv.setText(Html.fromHtml(getItem(position)));
return row;
}
};
lista.setAdapter(adapter);

This also works and is perphaps a lot simpler. First, pass your data from String[] to Spanned[]
Spanned[] myhtmldata = new Spanned[mydata.length];
for(int i = 0 ; i < mydata.length; i++) {
myhtmldata[i] = Html.fromHtml(mydata[i]);
}
Then declare the ArrayAdapter using the CharSequence parameter
ArrayAdapter<CharSequence> linksadapter = new ArrayAdapter<CharSequence>(getActivity(), R.layout.list_item, R.id.textview, myhtmldata);
setListAdapter(linksadapter);
Borrowed from here

Related

how to get the number of list items in a listview

my code shows user apps in a listview. I want to show the total number of list items (apps) in my textview. how do i get the number?
ArrayAdapter adapter = new ArrayAdapter<String>(this,R.layout.activity_listview, results){
// ArrayAdapter adapter = new ArrayAdapter<String>( this, android.R.layout.simple_list_item_1, results ) {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView textView = (TextView) super.getView(position, convertView, parent);
//Change this to your drawable
Drawable myDrawable = getResources().getDrawable(android.R.drawable.ic_dialog_alert);
textView.setCompoundDrawablesWithIntrinsicBounds( myDrawable , null, null, null);
return textView;
}
};
ListView listView = (ListView) findViewById(R.id.mobile_list);
listView.setAdapter(adapter);
I understand that the variable "results" which you use to construct your adapter, is a "List" object, right? Then, if you use the code below:
int totalNumber = results.size();
Then, the variable totalNumber will be a int equal to the number of items on your list.
Alternatively, as Kevin.Lam said, you can also try to use
adapter.getCount();
to return the total number of items.
Possibly by using ArrayAdapter's getCount() method - it shows "How many items are in the data set represented by this Adapter"

Alternating colors in Listview in Android Studio App

I am looking to alternate the colors in my ListView between two separate colors. Here is my ListView attributes.
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/efile_results_list_view"
android:layout_gravity="top"
android:clickable="true"
android:background="" />
Here is where I am creating the ListView.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.init(R.layout.activity_efile_results);
resultListView = (ListView)findViewById(R.id.efile_results_list_view);
if (ListView() % 2 == 0) {
resultListView.setBackgroundColor(Color.LTGRAY);
}
else {
resultListView.setBackgroundColor(Color.WHITE);
}
resultListView.setOnItemClickListener(this);
if(lastRequestedFilings != null)
{
filings = lastRequestedFilings;
}
else
{
filings = new FilingEntity[1];
filings[0] = new FilingEntity();
}
//printResultsToLog();
populateResultList(filings);
}
You should override getView method in your listview adapter from which you can do the following :
View getView (int position, View convertView, ViewGroup parent) {
...
if(position % 2 == 0) {
convertView.setBackgroundColor(color1);
else {
convertView.setBackgroundColor(color2);
}
return convertView;
}
Of course your convertView should have been created before. If your adapter just extends ArrayAdapter you can just add the following line instead of the dots :
convertView = super.getView(position, convertView, parent);
Checkout this tutorial for more information.
EDIT
I will explain a little bit more.
When you want to use a ListView, you need an Adapter. The adapter is used to render the data, so each row. The ListView is just the container of the row, so if you change the background color of the ListView, you are just changing the color of the whole container. What you want to do is changing the color of each row. You have to do it in the adatper's method getView.
So first you extend for exemple an ArrayAdatper and you override getView
public class MyAdatper extends ArrayAdapter<String> {
View getView (int position, View convertView, ViewGroup parent) {
convertView = super.getView(position, convertView, parent);
if(position % 2 == 0) {
convertView.setBackgroundColor(color1);
else {
convertView.setBackgroundColor(color2);
}
return convertView;
}
Then in your Activity you do :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
resultListView = (ListView)findViewById(R.id.efile_results_list_view);
String[] mockValue = {
"Value 1",
"value 2",
"value 3" };
MyAdatper adapter = new MyAdapter(this, R.layout.list_item, R.id.info_text, mockValues));
resultListView.setAdapter(adapter);
}
Finally, create a layout that will represent a row. For example inside list_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_gravity="center"
android:layout_margin="10dp">
<TextView
android:id="#+id/info_text"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
I suggest that you look at some documentation and some tutorial to know exactly how this is working.
Here I gave you the example for a simple ListView Displaying an Array of String. If you are looking to display more complex views, look for the BaseAdapter.
ListView extends AbsListView, which implements setBackgroundColor(int color), as mentioned in the documentation. Quoting:
public void setBackgroundColor (int color). Added in API level 1.
Sets the background color for this view.
Parameters:
color - the color of the background
You can use it like this:
ListView saveList = (ListView) findViewById(R.id.some_list);
myList.setBackgroundColor(Color.rgb(102, 102, 255));
To get the RGB color code you can use this website.

How to change background of a textview in a custom listview for each row

I created an application for chat between two person
first of all i have to fetch all data from server by Jsonparser
there is a custom listview each row contains "shop,painter,datetime,comment,id"
if yourname is not empty means comment is yours and viseversa
i want to put a bubble background for comment that indicate the painter or shop
i dont know how to use getview when i have a custom listview with more than one textview and because my resource data that is contain all information comes from server and store it to the hashmap array... hashmap doesnt have position as it is in getview method...
.........some code .....
// adding HashList to ArrayList
AllCommentsList.add(map);
adapter = new SimpleAdapter(getApplicationContext(),
AllCommentsList, R.layout.list_row_order_comments,
new String[] { TAG_COMMENT_ID, TAG_SHOP, TAG_PAINTER,TAG_COMMENT, TAG_DATETIME },
new int[] { R.id.tvIdComments, R.id.tvShopSender,R.id.tvPainterSender, R.id.tvComment,R.id.tvDateTimeComments });
// updating listview
listViewComment.setAdapter(adapter);
this is my code but i want to dynamically change the background of Comment textview
how to put some code like this????
if (strPainter.equals("null")) {
tvComment.setBackgroundResource(R.drawable.bubble_green);
}
if (strShop.equals("null")) {
tvComment.setBackgroundResource(R.drawable.bubble_yellow);
}
Don't use SimpleAdapter. Create a custom adapter that overrides getView and make whatever manipulations that you want to the layout, background, etc based on the current item.
See /samples/android-8/ApiDemos/src/com/example/android/apis/view/List5.java in your Android SDK folder (download appropriate samples as necessary) for a simple example:
private class MyListAdapter extends BaseAdapter {
...
public View getView(int position, View convertView, ViewGroup parent) {
TextView tv;
if (convertView == null) {
tv = (TextView) LayoutInflater.from(mContext).inflate(
android.R.layout.simple_expandable_list_item_1, parent, false);
} else {
tv = (TextView) convertView;
}
tv.setText(mStrings[position]);
return tv;
}
...
}

Can I make one ListView item have a different Text Color?

I have the layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ListView
android:id="#+id/ListView01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1.0"
android:textColor="#android:color/white"
android:dividerHeight="1px"
android:listSelector="#drawable/highlight_sel"
/>
</LinearLayout>
And the code:
private ListView lv1;
private String lv_arr[]={"Item 1","Item 2","Item 3","Item 4"};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.newsmenu);
lv1=(ListView)findViewById(R.id.ListView01);
// By using setAdpater method in listview we an add string array in list.
lv1.setAdapter(
new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
lv_arr));
}
I want the text color of Item 2 (or 1 or 3 or 4) to appear dynamically as red (denoting a new item) or white (default). Is there a way to do this?
I already have a selector present, which is why I used ListView. I've search the Internet and this site, and I have not seen this question broached.
So is it possible?
Yes everything is possible. you need to write your own adapter implementation basically overriding the getView Method in the adapter. search google and stack you will find many tutorials on how to write an adapter.
Writing a special adapter to override getView in simple adapter is the way to change the text color alternating on the lines of your choice in a listview. I took the example which has been repeated many times on this website and added a way to change the text color. position mod length to select the color position can be replaced with any scheme you like. The text view "business" can be the first line of your layout like mine--or use the android.R.id.text1.
public class SpecialAdapter extends SimpleAdapter {
private int[] colors = new int[] { 0x30FF0000, 0x300000FF };
public SpecialAdapter(Context context, List<HashMap<String, String>> items, int resource, String[] from, int[] to) {
super(context, items, resource, from, to);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
int colorPos = position % colors.length;
//view.setBackgroundColor(colors[colorPos]); //old example
TextView tv1 = (TextView)view.findViewById(R.id.business); //new
tv1.setTextColor(colors[colorPos]); //new
return view;
}
}
Just use SpecialAdapter instead of SimpleAdapter in your app.
Here's an example of a getView method. Note that it's using a viewholder for efficiency. If you want to know more about that, let me know.
public View getView(int position, View convertView, ViewGroup parent) {
tempDeal = exampleBoxArrayList.get(position);
ViewHolder holder;
if (convertView == null) {
convertView = inflator.inflate(R.layout.list_item_example_box, null);
holder = new ViewHolder();
holder.divider = (RelativeLayout) convertView.findViewById(R.id.example_box_divider);
holder.merchantName = (TextView) convertView.findViewById(R.id.example_box_merchant_name);
holder.expireDate = (TextView) convertView.findViewById(R.id.example_box_expire_date);
holder.description = (TextView) convertView.findViewById(R.id.example_box_description);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
if (tempDeal.isDivider()) {
holder.divider.setVisibility(View.VISIBLE);
} else {
holder.divider.setVisibility(View.GONE);
}
holder.merchantName.setText(tempDeal.getMerchantName());
holder.expireDate.setText(tempDeal.getExpiryDateString());
holder.description.setText(tempDeal.getPriceOption().getDescription());
return convertView;
}
As you can see, I call the isDivider() method on my custom object (this method looks at a boolean set on data load). This method is used to turn the visibility of part of the layout on or off.
Alternatively, you could load a completely new layout based on this same concept.

Multiple choice list with custom view?

I've seen example com.example.android.apis.view.List11 from ApiDemos. In that example, each row takes the view android.R.simple_list_item_multiple_choice. Each such view has a TextView and a CheckBox.
Now I want each view to have 2 TextViews and 1 CheckBox, somewhat similar to the List3 example. I tried creating a custom layout file row.xml like this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<CheckBox
android:id="#+id/checkbox"
android:layout_alignParentRight="true"
android:layout_width="wrap_content"
android:layout_height="fill_parent" />
<TextView
android:id="#+id/text_name"
android:textSize="13px"
android:textStyle="bold"
android:layout_toLeftOf="#id/checkbox"
android:layout_alignParentLeft="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/text_phone"
android:textSize="9px"
android:layout_toLeftOf="#id/checkbox"
android:layout_below="#id/text_name"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
Then in Activity's onCreate(), I do like this:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Query the contacts
mCursor = getContentResolver().query(Phones.CONTENT_URI, null, null, null, null);
startManagingCursor(mCursor);
ListAdapter adapter = new SimpleCursorAdapter(this,
R.layout.row,
mCursor,
new String[] { Phones.NAME, Phones.NUMBER},
new int[] { R.id.text_name, R.id.text_phone });
setListAdapter(adapter);
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
}
The result kind of looks like what I want, but it looks like the list doesn't know which item of it is selected. Also, I need to click exactly on the CheckBox. In the List11 example, I only need to click on the item row.
So what do I need to do to make a multiple choice list with my custom view for each row? Many thanks.
You have to make your own RelativeLayout that implements the Checkable interface and have a reference to the CheckBox or to the CheckedTextView (or a list if it's multiple choice mode).
Look at this post:
http://www.marvinlabs.com/2010/10/29/custom-listview-ability-check-items/
The answer of Rahul Garg is good for the first time the list is loaded, if you want some rows to be checked depending on the model data, but after that you have to handle the check/uncheck events by yourself.
You can override the onListItemCLick() of the ListActivity to check/uncheck the rows
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
ViewGroup row = (ViewGroup)v;
CheckBox check = (CheckBox) row.findViewById(R.id.checkbox);
check.toggle();
}
If you do so, do not set the ListView to CHOICE_MODE_MULTIPLE, because it makes strange things when calling the function.
To retrieve the list of checked rows, you have to implement a method yourself, calling getCheckItemIds() on the ListView does not work:
ListView l = getListView();
int count = l.getCount();
for(int i=0; i<count; ++i) {
ViewGroup row = (ViewGroup)l.getChildAt(i);
CheckBox check = (Checked) row.findViewById(R.id.ck1);
if( check.isChecked() ) {
// do something
}
}
Each such view has a TextView and a
CheckBox.
No, it doesn't. It has a CheckedTextView.
So what do I need to do to make a
multiple choice list with my custom
view for each row?
Try making the CheckBox android:id value be "#android:id/text1" and see if that helps. That is the ID used by Android for the CheckedTextView in simple_list_item_multiple_choice.
The solution is to create a custom View that implements the Clickable interface.
public class OneLineCheckableListItem extends LinearLayout implements Checkable {
public OneLineCheckableListItem(Context context, AttributeSet attrs) {
super(context, attrs);
}
private boolean checked;
#Override
public boolean isChecked() {
return checked;
}
#Override
public void setChecked(boolean checked) {
this.checked = checked;
ImageView iv = (ImageView) findViewById(R.id.SelectImageView);
iv.setImageResource(checked ? R.drawable.button_up : R.drawable.button_down);
}
#Override
public void toggle() {
this.checked = !this.checked;
}
}
And create a custom layout for the list items using the new widget.
<?xml version="1.0" encoding="utf-8"?>
<ax.wordster.OneLineCheckableListItem xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:background="#drawable/selector_listitem"
android:orientation="horizontal" >
<ImageView
android:id="#+id/SelectImageView"
android:layout_width="60dp"
android:layout_height="60dp"
android:src="#drawable/button_friends_down" />
<TextView
android:id="#+id/ItemTextView"
android:layout_width="fill_parent"
android:layout_height="60dp"
android:gravity="center"
android:text="#string/___"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#color/text_item" />
</ax.wordster.OneLineCheckableListItem>
Then create a new custom Adapter using the layout above.
It is possible by some trick
in your ListActivtyClass in method
protected void onListItemClick(ListView l, View v, int position, long id) {
//just set
<your_model>.setSelected(true);
}
now in you custom Adapter
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(textViewResourceId, parent, false);
}
if (<your_model>.isSelected()) {
convertView.setBackgroundColor(Color.BLUE);
} else {
convertView.setBackgroundColor(Color.BLACK);
}
return convertView;
}
this way you can customize the view in adapter when the item is selected in the list.
Simple example how to get a custom layout to work as custom checkbox:
private class FriendsAdapter extends ArrayAdapter<WordsterUser> {
private Context context;
public FriendsAdapter(Context context) {
super(context, R.layout.listitem_oneline);
this.context = context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final int pos = position;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rv = inflater.inflate(R.layout.listitem_oneline, parent, false);
rv.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
boolean checked = friendsListView.isItemChecked(pos);
friendsListView.setItemChecked(pos, !checked);
}
});
WordsterUser u = getItem(position);
TextView itw = (TextView) rv.findViewById(R.id.ItemTextView);
itw.setText(u.userName + " (" + u.loginName + ")");
ImageView iv = (ImageView) rv.findViewById(R.id.SelectButton);
if (friendsListView.isItemChecked(position)) {
iv.setImageResource(R.drawable.downbutton);
} else {
iv.setImageResource(R.drawable.upbutton);
}
return rv;
}
}
I found it very useful this little code: http://alvinalexander.com/java/jwarehouse/apps-for-android/RingsExtended/src/com/example/android/rings_extended/CheckableRelativeLayout.java.shtml
It is a great addition to #ferdy182 's http://www.marvinlabs.com/2010/10/29/custom-listview-ability-check-items/ content.
Got the solution ... You can get the clicks on the views (like checkboxes in custom layouts of row) by adding listener to each of them in the adapter itself while you return the converted view in getView(). You may possibly have to pass a reference of list object if you intent to get any list specific info. like row id.
I want to confirm that the Pritam's answer is correct. You need an onClickListener on each list's item (define it in the adapter's getView()).
You can create a new onClickListener() for each item, or have the adapter implement onClickListener() - in this case the items must be tagged for the listener to know, which item it is operating on.
Relying on the list onItemClickListener() - as someone advised in another thread - will not work as the CheckBox will intercept the click event so the list will not get it.
And finally #Rahul and JVitella:
The situation is that the CheckBox on a list item must be clickable and checkable independently from the list item itself. Therefore the solution is as I just described above.

Categories

Resources