Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android display html in textview inside a listview

Tags:

html

android

I display my html data in text view. In ListView, it displays raw HTML.

Here's pictures:

enter image description hereenter image description here

My ArticleActivity:

    package net.biscani.dino;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.Html;
import android.text.method.ScrollingMovementMethod;
import android.widget.TextView;

public class ArticleActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.single_article);

        Intent in = getIntent();

        String name = in.getStringExtra(GetArticles.KEY_TITLE);
        String content = in.getStringExtra(GetArticles.KEY_CONTENT);

        TextView lblName = (TextView) findViewById(R.id.name_label);
        TextView lblDesc = (TextView) findViewById(R.id.content_label);

        lblName.setText(name);
        lblDesc.setText(Html.fromHtml(content));
        lblDesc.setMovementMethod(ScrollingMovementMethod.getInstance());
    }
}

Also here's my MainActivity:

        package net.biscani.dino;

    import android.support.v7.app.ActionBarActivity;
    import java.util.ArrayList;
    import java.util.HashMap;

    import net.biscani.dino.ArticleActivity;
    import net.biscani.dino.GetArticles;
    import net.biscani.dino.MainActivity;
    import net.biscani.dino.R;

    import android.app.ListActivity;
    import android.app.LoaderManager.LoaderCallbacks;
    import android.app.ProgressDialog;
    import android.content.Intent;
    import android.content.Loader;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.AdapterView;
    import android.widget.AdapterView.OnItemClickListener;
    import android.widget.ListAdapter;
    import android.widget.ListView;
    import android.widget.SimpleAdapter;
    import android.widget.TextView;
    import android.view.Menu;
    import android.view.MenuItem;


    public class MainActivity extends ListActivity {

        private static int LOADER_NUM = 1;
        private ProgressDialog mPd;
        private ListAdapter mAdapter;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);

            mPd = new ProgressDialog(this);

            ListView lv = getListView();

            lv.setOnItemClickListener(new OnItemClickListener() {

                @Override
                public void onItemClick(AdapterView<?> parent, View view,
                        int position, long id) {
                    String title = ((TextView) view.findViewById(R.id.title))
                            .getText().toString();
                    String content = ((TextView) view
                            .findViewById(R.id.content)).getText().toString();

                    Intent in = new Intent(getApplicationContext(),
                            ArticleActivity.class);
                    in.putExtra(GetArticles.KEY_TITLE, title);
                    in.putExtra(GetArticles.KEY_CONTENT, content);
                    startActivity(in);
                }
            });

            getLoaderManager().restartLoader(LOADER_NUM, Bundle.EMPTY,
                    mLoaderCallbacks);

        }

        private LoaderCallbacks<ArrayList<HashMap<String, String>>> mLoaderCallbacks = new LoaderCallbacks<ArrayList<HashMap<String, String>>>() {

            @Override
            public Loader<ArrayList<HashMap<String, String>>> onCreateLoader(
                    int id, Bundle args) {

                mPd.show();

                return new GetArticles(MainActivity.this);
            }

            @Override
            public void onLoadFinished(
                    Loader<ArrayList<HashMap<String, String>>> loader,
                    ArrayList<HashMap<String, String>> articles) {

                mAdapter = new SimpleAdapter(MainActivity.this, articles,
                        R.layout.list_item, new String[] { GetArticles.KEY_TITLE,
                                GetArticles.KEY_CONTENT }, 
                                new int[] {
                                R.id.title, R.id.content });

                setListAdapter(mAdapter);

                mPd.dismiss();
            }

            @Override
            public void onLoaderReset(
                    Loader<ArrayList<HashMap<String, String>>> loader) {
            }
        };


        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.main, menu);
            return true;
        }

        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            // Handle action bar item clicks here. The action bar will
            // automatically handle clicks on the Home/Up button, so long
            // as you specify a parent activity in AndroidManifest.xml.
            int id = item.getItemId();
            if (id == R.id.action_settings) {
                return true;
            }
            return super.onOptionsItemSelected(item);
        }
    }

my ArticleActivity:

package net.biscani.dino;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.Html;
import android.text.method.ScrollingMovementMethod;
import android.widget.TextView;

public class ArticleActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.single_article);

        Intent in = getIntent();

        String name = in.getStringExtra(GetArticles.KEY_TITLE);
        String content = in.getStringExtra(GetArticles.KEY_CONTENT);

        TextView lblName = (TextView) findViewById(R.id.name_label);
        TextView lblDesc = (TextView) findViewById(R.id.content_label);

        lblName.setText(name);
        lblDesc.setText(Html.fromHtml(content));
        lblDesc.setMovementMethod(ScrollingMovementMethod.getInstance());
    }
}

and my GetArticles.java:

    package net.biscani.dino;

import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import android.content.AsyncTaskLoader;
import android.content.Context;
import android.util.Log;

public class GetArticles extends
        AsyncTaskLoader<ArrayList<HashMap<String, String>>> {
    private static final String TAG = GetArticles.class.getSimpleName();

    static final String URL = "http://www.biscani.net/feed/";
    static final String KEY_ITEM = "item";
    static final String KEY_TITLE = "title";
    static final String KEY_CONTENT = "content:encoded";

    public GetArticles(Context context) {
        super(context);
    }

    @Override
    protected void onStartLoading() {
        forceLoad();
    }

    @Override
    public ArrayList<HashMap<String, String>> loadInBackground() {

        ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>();

        try {

            URL url = new URL(URL);
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(new InputSource(url.openStream()));
            doc.getDocumentElement().normalize();

            NodeList nodeList = doc.getElementsByTagName(KEY_ITEM);

            for (int i = 0; i < nodeList.getLength(); i++) {

                Node node = nodeList.item(i);

                Element fstElmnt = (Element) node;
                NodeList nameList = fstElmnt.getElementsByTagName(KEY_TITLE);
                Element nameElement = (Element) nameList.item(0);
                nameList = nameElement.getChildNodes();

                Log.d("", "Name = " + ((Node) nameList.item(0)).getNodeValue());

                NodeList contentList = fstElmnt
                        .getElementsByTagName(KEY_CONTENT);
                Element contentElement = (Element) contentList.item(0);
                contentList = contentElement.getChildNodes();

                Log.d("",
                        "Content = "
                                + ((Node) contentList.item(0))
                                        .getNodeValue());

                HashMap<String, String> map = new HashMap<String, String>();
                map.put(KEY_TITLE, ((Node) nameList.item(0)).getNodeValue());
                map.put(KEY_CONTENT,
                        ((Node) contentList.item(0)).getNodeValue());

                menuItems.add(map);
            }
        } catch (Exception e) {
            System.out.println("XML Pasing Excpetion = " + e);
        }

        return menuItems;
    }
}

ListView item layout list_item.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <!-- Name Label -->

        <TextView
            android:id="@+id/title"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:paddingTop="1dp"
            android:textColor="#dc6800"
            android:textSize="16sp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/content"
            android:layout_width="fill_parent"
            android:layout_height="50dp"
            android:ellipsize="end"
            android:scrollbars="none"
            android:textColor="#acacac" >

        </TextView>
    </LinearLayout>

</LinearLayout>

When I'm on a single article, it works, the HTML is converted. But when I'm on a list view, it wont' convert it. How could I fix this?

Thanks in advance.

like image 852
dynamitem Avatar asked Jul 10 '14 22:07

dynamitem


1 Answers

You will need to write your own Adapter subclass for the list, so that it can render the description as HTML. The SimpleAdapter class will not do this for you - it sees the encoded HTML as just an ordinary string, and doesn't know to render it as HTML.

The custom adapter would look something like this:

private class ArticleAdapter extends ArrayAdapter<HashMap<String, String>> {

    private ArticleAdapter(ArrayList<HashMap<String, String>> list) {
        super(MainActivity.this, R.layout.list_item, list);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row = convertView;
        if (row == null) {
            LayoutInflater inflater = MainActivity.this.getLayoutInflater();
            row = inflater.inflate(R.layout.list_item, parent, false);
        }
        HashMap<String, String> article = getItem(position);
        ((TextView)row.findViewById(R.id.title)).setText(article.get(GetArticles.KEY_TITLE));
        ((TextView)row.findViewById(R.id.content)).setText(Html.fromHtml(article.get(GetArticles.KEY_CONTENT)));
        return row;
    }

}
like image 120
Dave Morrissey Avatar answered Oct 23 '22 02:10

Dave Morrissey